selenium 中的 actions.perform() 仅在第一次起作用,而不是什么都不做。可能是什么问题?

actions.perform() in selenium only works at the first time, than it does nothing. What can be the problem?

下面的代码是我为试验 ActionChains 而编写的自动 CookieClicker。它基于 9:42 上的教程视频。 (Link)

当我 运行 这段代码时,for 循环 运行 下降了 1000 次,但只发生了 1 次点击。仅当我从注释行中删除“#”时才会发生多次点击,因此我每次都 运行 actions.click(cookie)。至于视频,不需要多写一行代码。可能是什么原因造成的?

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains

s = Service("C:\Program Files (x86)\chromedriver.exe")
driver = webdriver.Chrome(service=s)

driver.maximize_window()
driver.get("https://orteil.dashnet.org/cookieclicker/")

driver.implicitly_wait(5)

cookie=driver.find_element(By.ID,"bigCookie")
cookie_count = driver.find_element(By.ID,"cookies")

actions = ActionChains(driver)
actions.click(cookie)

for i in range(1000):
    #actions.click(cookie)
    actions.perform()
    count=int(cookie_count.text.split(" ")[0])
    print(i,count)
driver.quit()

我假设您使用操作是为了使用它或了解它,因为您只需调用 cookie.click() 即可获得所需的结果。

当您需要对某个元素执行某些“操作”而不是查找或单击它时,将使用操作,即您想要右键单击、单击并按住或发送组合键等。查看 Selenium Actions 了解更多信息。

关于使用action来点击,你还需要明白perform是获取你的action的复合对象(调用Actions的build函数)并执行。由于您的操作是在 for 循环之外声明的,因此在第一次单击后,perform() 函数将不再执行任何操作。

TLDR:
要么删除 for 循环中 actions.click(cookie) 的注释,要么使用 cookie.click() 在不使用操作的情况下获得相同的结果。

for i in range(10):
    actions.click(cookie)
    actions.perform()
    #cookie.click()
    count=int(cookie_count.text.split(" ")[0])
    print(i,count)

driver.quit() 

Colab Notebook of it working

The ActionChains implementation

ActionChains 可以在链式模式中使用。当您调用 ActionChains 对象上的操作方法时,操作存储在 ActionChains 对象的队列中。当您调用 时,事件将按照它们排队的顺序触发。


perform()

执行所有存储的操作。


结论

将触发存储在队列中的事件。在您的用例中,actions.click(cookie) 是事件。

您的最佳代码块将是:

driver.get("https://orteil.dashnet.org/cookieclicker/")
cookie_count = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#cookies")))
cookie = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#bigCookie")))
for i in range(100):
    ActionChains(driver).click(cookie).perform()
    count = cookie_count.text.split(" ")[0]
    print(i,count)
driver.quit()

控制台输出:

0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
20 20
21 21
22 22
23 23
24 24
25 25
26 26
27 27
28 28
29 29
30 30
31 31
32 32
33 33
34 34
35 35
36 36
37 37
38 38
39 39
40 40
41 41
42 42
43 43
44 44
45 45
46 46
47 47
48 48
49 49
50 50
51 51
52 52
53 53
54 54
55 55
56 56
57 57
58 58
59 59
60 60
61 61
62 62
63 63
64 64
65 65
66 66
67 67
68 68
69 69
70 70
71 71
72 72
73 73
74 74
75 75
76 76
77 77
78 78
79 79
80 80
81 81
82 82
83 83
84 84
85 85
86 86
87 87
88 88
89 89
90 90
91 91
92 92
93 93
94 94
95 95
96 96
97 97
98 98
99 99