循环遍历随机排列的 WebElements 数组,而不会使它们过时



我的困境是,如果我使用

a=[]
a=driver.find_elements_by_class_name("card")
random.shuffle(a)
for card in a:
nextup=(str(card.text) + 'n' + "_" * 15)
do a bunch of stuff that takes about 10 min

第一轮有效,但随后我得到一个 StaleElementException,因为它单击链接并转到差异页面。所以后来我切换到这个:

a=[]
a=driver.find_elements_by_class_name("card")
i=0
cardnum=len(a)
while i != cardnum:
i += 1 #needed because first element thats found doesnt work
a=driver.find_elements_by_class_name("card") #also needed to refresh the list
random.shuffle(a) 
nextup=(str(card.text) + 'n' + "_" * 15)
do a bunch of stuff that takes about 10 min

这个问题是 i 变量,因为由于每个循环的洗牌,可能会点击同一张牌。然后我添加了一个捕获来检查卡是否已被单击,如果已单击,请继续。听起来它会起作用,但遗憾的是 i 变量计算这些,然后最终计数超过索引。我想过定期将 i 设置回 1,但我不知道它是否有效。编辑:将进行无限循环,因为一旦单击所有内容,我将为零,并且永远不会退出。

我知道代码经过广泛测试,但是,机器人因不像人类和随机而被禁止。此脚本的基础知识是遍历类别列表,然后遍历类别中的所有卡片。尝试随机化类别,但类似的困境,因为要刷新列表,您必须像上面的块一样在每个循环中重新制作数组,然后出现类别已经完成的问题将再次单击...任何建议将不胜感激。

这里发生的事情是,当你与页面交互时,DOM 会刷新,最终导致你存储的元素过时。

不要保留元素列表,而是保留对其各个元素路径的引用,并根据需要重新获取元素:

# The base css path for all the cards
base_card_css_path = ".card"
# Get all the target elements. You are only doing this to
# get a count of the number of elements on the page
card_elems = driver.find_elements_by_css_selector(base_card_css_path)
# Convert this to a list of indexes, starting with 1
card_indexes = list(range(1, len(card_elems)+1))
# Shuffle it
random.shuffle(card_indexes)
# Use `:nth-child(X)` syntax to get these elements on an as needed basis
for index in card_indexes:
card_css = base_card_css_path + ":nth-child({0})".format(index)
card = driver.find_element_by_css_selector(card_css)
nextup=(str(card.text) + 'n' + "_" * 15)
# do a bunch of stuff that takes about 10 min

(以上未经测试,原因显而易见)

最新更新