Таймер внутри таймера

здравствуйте и заранее спасибо, сейчас я пишу игру The Cookie Cutter из книги Анжелы Ю «100 дней кода», Цель состоит в том, чтобы получить как можно больше кликов в течение 5 минут, проверяя каждые 5 секунд деньги (я назвал это «счетом»), которые я накопил, чтобы я мог приобрести самое высокое доступное обновление.

это решение Анжелы на Github: мне показалось, что это долго и неоправданно сложно.

мой код немного беспорядочный, так как он все еще находится в стадии разработки.

то, что я хотел сделать со своим кодом, - это перебрать каталог, содержащий #id и цену обновления, и как только он распознает соответствие возможной покупке, он нажимает на него.

import threading
import time
from collections import defaultdict

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from threading import Thread
from time import sleep
from datetime import datetime, timedelta

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("detach", True)

driver = webdriver.Chrome(options=chrome_options)
driver.get("https://orteil.dashnet.org/experiments/cookie/")
driver.maximize_window()

#######################ELEMENTS & CONVERTING TO LISTS\DICT#######################
cookie = driver.find_element(By.CSS_SELECTOR, '#cookie')
score = driver.find_element(By.CSS_SELECTOR, '#money')
scoreNum = int(score.text)
all_prices = driver.find_elements(By.CSS_SELECTOR, '#store b')
all_ids = driver.find_elements(By.CSS_SELECTOR, '#store div')
new_all_prices = []
new_all_ids = []
for new_id in all_ids:
    new_all_ids.append(new_id.get_attribute("id"))
for price in all_prices:
    a, b, c = price.text.partition('-')
    new_price = c.replace(" ", "")
    if c == "":
        pass
    else:
        new_all_prices.append(c.replace(" ", ""))

tuples = [(key, value)
          for i, (key, value) in enumerate(zip(new_all_prices, new_all_ids))]

myDict = dict(tuples)

#######################FUNCTIONS#######################


def five_seconds_check():
    for key, value in myDict.items():
        if scoreNum >= key:
            my_clickable_purchase = driver.find_element(By.CSS_SELECTOR, f'{myDict[key]}')
            my_clickable_purchase.click()


timeout = time.time() + 5
five_min = time.time() + 60 * 5  # 5 minutes

while True:
    cookie.click()
    if time.time() > timeout:
        five_seconds_check()
    elif time.time() > five_min:
        break

#########################CLOSING BROWSER#########################
time.sleep(5)
driver.close()

часть, с которой я борюсь, - это как написать таймер внутри таймера - то есть, как мне заставить общий цикл while работать в течение 5 минут и одновременно проверять обновление денег\покупок каждые 5 секунд.

🤔 А знаете ли вы, что...
С Python можно создавать веб-скраперы для извлечения данных из веб-сайтов.


68
2

Ответы:

Я думаю, ты очень близок! Просто убедитесь, что ваш 5-секундный цикл сбрасывается каждый раз после завершения. Кроме того, возможно, сохраните время как переменные, чтобы вам не приходилось так часто вызывать time.time().

Я бы также заменил последний elif на if, чтобы вы могли запускать и пятисекундный цикл, и пятиминутный перерыв в одной итерации.

Завершенный код выглядит следующим образом:

start_time = time.time()
timeout = start_time + 5
five_min = start_time + (60 * 5)  # 1 minutes

while True:
    cookie.click()
    curr_time = time.time()
    if curr_time > timeout:
        five_seconds_check()
        timeout = curr_time + 5
    if time.time() > five_min:
        break

Есть и другие, более эффективные способы сделать это, которые не полагаются на непрерывные циклы while; рассмотрите возможность поиска решений, основанных на time.sleep() или модуле sched.


Решено

на случай, если кто-то сталкивается с той же проблемой или просто хочет посмотреть — это окончательный результат после того, как я получил некоторую информацию и внес дополнительные изменения в общий код, поскольку в нем было несколько ошибок, за исключением времени петля.

import time
from selenium import webdriver
from selenium.webdriver.common.by import By

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("detach", True)

driver = webdriver.Chrome(options=chrome_options)
driver.get("https://orteil.dashnet.org/experiments/cookie/")
driver.maximize_window()

#######################ELEMENTS & CONVERTING TO LISTS\DICT#######################
cookie = driver.find_element(By.CSS_SELECTOR, '#cookie')
all_prices = driver.find_elements(By.CSS_SELECTOR, '#store b')
all_ids = driver.find_elements(By.CSS_SELECTOR, '#store div')
new_all_prices = []
new_all_ids = []
for new_id in all_ids:
    new_all_ids.append(new_id.get_attribute("id"))
for price in all_prices:
    a, b, c = price.text.partition('-')
    new_price = c.replace(" ", "")
    if c == "":
        pass
    else:
        new_all_prices.append(int(c.replace(" ", "").replace(",", "")))

tuples = [(key, value)
          for i, (key, value) in enumerate(zip(new_all_prices, new_all_ids))]


#######################FUNCTIONS#######################

def five_seconds_check():
    for key, value in myDict.items():
        score = driver.find_element(By.CSS_SELECTOR, '#money')
        scoreNum = int(score.text.replace(",", ""))
        if scoreNum >= key:
            my_clickable_purchase = driver.find_element(By.CSS_SELECTOR, f'#{value}')
            my_clickable_purchase.click()
            break


myDict = dict(tuples.__reversed__())

start_time = time.time()
timeout = start_time + 5
five_min = start_time + (60 * 5)  # 5 minutes

while time.time() < five_min:
    cookie.click()
    if time.time() >= timeout:
        five_seconds_check()
        timeout = time.time() + 5

#########################CLOSING BROWSER#########################
time.sleep(5)
driver.close()

Интересные вопросы для изучения

Python: только 2 уникальных имени столбца в фрейме данных, всего 3105 столбцов. Как получить среднее значение строки, сгруппированной по уникальному имени столбцаКак мне ввести аннотацию на листе или, точнее, на листе, доступном только для чтения?Рисовать линии между несколькими точками с известными координатамиКак я могу сравнить значение в одном столбце со всеми значениями, которые находятся ДО него в другом столбце, чтобы найти количество уникальных значений, которые меньше?Деление по нейронной сети; фиксированная стоимость, производимая каждый разВызвать Swift Actor из кода AVAudioEngine (синхронно)Самая быстрая группировка значений ключейКак сделать массив потокобезопасным в Java?Как остановить поток, который вызывает длительную задачу из другого скрипта Python?(C#/.NET 8.0) Почему я не могу получать, а затем отправлять данные из UdpClients, созданных и используемых в отдельных потоках?