Selenium / Python:为什么在我的for循环迭代中找到第一个元素后,为什么Selenium find_element_不再通过查找元素了?

感动

您是否发现此设置有问题?

(硒等,较早导入)

它遍历table_rows直到找到“ try”成功的第一行,然后从“ try”运行的getinfo()函数返回(单击链接,转到页面,获取信息,然后单击返回按钮),然后继续遍历table_rows的其余部分。

正确的table_rows迭代次数将在最后执行,并且将再次触发“ try”函数(在current_cell工作之前使用print()),但是find_element_by_class似乎并没有在其中拾取更多的“ a0”。随后的table_rows迭代,即使肯定有一些迭代也要找到(current_cell之后的print()在第一次之后就不再打印)。

感谢您的帮助。我是编码的新手,已经学到了很多东西,但是这让我很沮丧。

def getinfo(current_cell):
    link_in_current_cell = current_cell.find_element_by_tag_name("a")
    link_in_current_cell.click()

    waitfortable2 = WebDriverWait(driver, 5).until(
        EC.presence_of_element_located((By.CLASS_NAME, "top-edit-table"))
        ) 
    
    print("Here is the info about a0.")

    driver.back()

    return True


for row in table_rows:
    print("got the row!")   
        
    waitfortable = WebDriverWait(driver, 5).until(
        EC.presence_of_element_located((By.XPATH, "/html/body/table[3]/tbody/tr/td[2]/form/table/tbody/tr/td/table/tbody/tr[4]/td/table/tbody/tr[1]/td[1]"))
        ) 

    try:
        print("we're trying!")
        current_cell = row.find_element_by_class_name("a0")
        print("we got an a0!")
        getinfo(current_cell)
    except:
        print("Not an a0 cell.")
        pass

    continue

如果需要的话,这是“ for table_rows中的行:”之前的更多代码,但我认为这不是问题,因为它在找到第一个“ a0”之后仍在遍历其余的table_rows。细胞。

try:
    WebDriverWait(driver, 5).until(
        EC.presence_of_element_located((By.XPATH, "/html/body/table[3]/tbody/tr/td[2]/form/table/tbody/tr/td/table/tbody/tr[4]/td/table/tbody/tr[1]/td[1]"))
        ) 

    table = driver.find_element_by_xpath("/html/body/table[3]/tbody/tr/td[2]/form/table/tbody/tr/td/table/tbody/tr[4]/td/table")
    table_rows = table.find_elements_by_tag_name("tr") 

    for row in table_rows:
        print("got the row!") 
        ....
        ....
        ....(see code box above) 
感动

成功!我找到了自己的解决方法!

仅供参考:我仍然看不到我现有的代码有什么问题,因为当我注释掉文本的函数部分时,它正确地找到了所有的a0单元格(#getinfo(current_cell)...谢谢@ goalie1998的建议)。而且,对于此新的解决方法,我没有对该功能进行任何更改,此方法可以正常工作。因此,它必须与Selenium在尝试遍历循环时变得混乱有关,该循环(1)试图通过页面上的某物(页面上多次存在,这是find_element_by的原因,这就是创建循环的原因) (2)单击该循环中的链接,转到页面,返回到页面,然后应该使用find_element_by“ function”(在这里可能是错误的术语用法)继续运行迭代以获取下一个页面上存在的一个。不知道为什么Selenium会因此而陷入困境,但是确实如此。(更多经验丰富的编码人员,请随时阐述)。

无论如何,我的解决方法思考过程可能是:

(1)在单击任何链接之前找到所有链接(并创建这些链接的列表)

我决定一次都不要查找并单击链接,而是决定先查找所有链接(单击它们之前)我将上面的代码更改为此:

# this is where I'm storing all the links
text_link_list = []

for row in table_rows:

    print("got the row!")
        
    waitfortable = WebDriverWait(driver, 5).until(
        EC.presence_of_element_located((By.XPATH, "/html/body/table[3]/tbody/tr/td[2]/form/table/tbody/tr/td/table/tbody/tr[4]/td/table/tbody/tr[1]/td[1]"))
         ) 
        
    ## Get a0
    try:
        print("we're trying!")
        row.find_element_by_class_name("a0")
        print("we got an a0!")
        
        # this next part is just because there are also blank "a0" cells without 
        # text (aka a link) in them, and I don't care about those ones.

        current_row_has_a0 = row.find_element_by_class_name("a0")
        if str(current_row_has_a0.text) != "":
            text_link_list += [current_row_has_a0.text]
            print("text added to text_link_list!")
        else:
            print("wasn't a text cell!")
     except:
         pass

     continue

(2)遍历该链接列表,运行包含.click()和.back()的Selenium代码

现在我有了链接列表,我可以遍历所有链接并执行我创建的.click()->执行动作-> .back()函数(getinfo()-上面讨论的原始代码)

## brand new for loop, after "for row in table_rows" loop

for text in text_link_list:
    # waiting for page to load upon iterations
    table = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, "/html/body/table[3]/tbody/tr/td[2]/form/table/tbody/tr/td/table/tbody/tr[4]/td/table/tbody/tr[1]/td[1]"))
        ) 
    
    # this is my .click() --> perform actions --> .back() function
    getinfo(text)

但是,我只需要对.getinfo()函数进行两个小的更改。

第一,我现在通过链接的“链接文本”单击链接,而不是之前使用的a0类(需要使用.find_element_by_link_text

第二,我现在可以使用更基本的driver.find_element_by代替原来的table.find_element_by..“ table”了,但是我担心进入“ table”的记忆会丢失,因为我现在正在运行函数。 .click()代码。因为可以肯定,我决定选择“驱动程序”。(我对编码还是很陌生,可能没有必要。)

def getinfo(text):
    link_in_current_cell = driver.find_element_by_link_text(text)
    link_in_current_cell.click()

    waitfortable2 = WebDriverWait(driver, 5).until(
        EC.presence_of_element_located((By.CLASS_NAME, "top-edit-table"))
        ) 
    
    print("Here is the info from this temporary page.")

    driver.back()

    return True

我希望这对某人有帮助。当我这样做的时候,我很激动,它奏效了!让我知道它是否对您有帮助!<3

PS。注意:如果出现批量错误/ StaleElementReferenceException:如果要遍历循环并通过类似的链接driver.find_element_by(而不是使用.back()单击链接,则可能会遇到Stale错误,尤其是在尝试使用.click()的情况下。您在循环之前或循环之外分配的变量。您可以通过以下方式在链接的那个位置重新定义变量来解决此问题(也许不是最漂亮的方法):

my_link = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.LINK_TEXT, "linktext"))
    )
my_link.click()
continue
  • 仅当您想要结束当前迭代并开始下一个迭代时才需要“继续”,并且如果这是在循环的结尾,则“继续”也没有必要
  • 您可以将红色的“ 10”数字更改为您希望在脚本执行失败之前给代码以找到元素的时间(也可能是要重新加载的页面)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章