Reputation: 159
I'm trying to implement a cookie clicker bot. Cookie clicker it's just a stupid simple game, where you can click on the cookie to earn more cookies. You can take a look at that masterpiece here.
The bot should just open the page, and click on the cookie 4000 times, but it clicks only one time.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://orteil.dashnet.org/cookieclicker/")
driver.implicitly_wait(10)
cookie = driver.find_element(By.ID, "bigCookie")
actions = ActionChains(driver)
actions.click(cookie)
for i in range(4000):
actions.perform()
I see these messages in the console. What is wrong with me my code?
Upvotes: 2
Views: 1709
Reputation: 1
You should use reset_actions() which clears actions that are already stored locally and on the remote end.
You can add some time delay while performing mouse movement operations.
for i in range(4000):
actions.reset_actions()
actions.click(cookie)
actions.perform()
Upvotes: 0
Reputation: 320
Here was my solution to the coding challenge. Note that just as @Prophet suggested, what I ended up doing was putting my code inside of the for loop.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
def getCount(count):
try:
v = int(str(count).split(" ")[0])
return v
except:
return 0
#strings
url = "https://orteil.dashnet.org/cookieclicker/"
english = "langSelect-EN"
bigCookie = "bigCookie"
cookieCount = "cookies"
options = Options()
options.page_load_strategy = 'normal'
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(10)
driver.get(url)
print("Looking for language button")
language = driver.find_element(By.ID, english)
language.click()
for i in range(5000):
try:
print("Cycle " + str(i))
cookie = driver.find_element(By.ID, bigCookie)
counter = driver.find_element(By.ID, cookieCount)
cookies = getCount(counter.text)
items = [driver.find_element(By.ID, "productPrice" + str(i)) for i in range(2, -1, -1) ]
# I tried this both ways, and it clicks significantly faster if I don't use "ActionChains"
# actions = ActionChains(driver)
# actions.move_to_element(cookie)
# actions.click(cookie)
# actions.perform()
cookie.click()
for item in items:
price = getCount(item.text)
if price > 0 and price <= cookies:
actions = ActionChains(driver)
actions.move_to_element(item)
actions.click()
actions.perform()
except:
print(f"Cycle {i} Failed :-(")
Hope this helps!
Upvotes: 0
Reputation: 33361
What you trying to do here is to load the gun one time and then to press on trigger several times in a loop... To do what you wish you should slightly change your code as following:
actions = ActionChains(driver)
for i in range(4000):
actions.click(cookie)
actions.perform()
BTW I guess this code will still not work since after the first click on the cookie
element even if it will appear again it will be a NEW, ANOTHER element even if it could be located with the same locator.
So trying to click it again will cause StaleElementReferenceException
.
To make this work you will have to locate the cookie
element again each time, as following:
actions = ActionChains(driver)
for i in range(4000):
cookie = wait.until(EC.visibility_of_element_located((By.ID, "bigCookie")))
actions.click(cookie)
actions.perform()
Upvotes: 1