繁体   English   中英

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

[英]Selenium / Python: Why isn't my Selenium find_element_by finding elements anymore after finding the first one in my for loop iterations?

你觉得这个设置有什么问题吗?

(硒等较早进口)

它遍历 table_rows 直到找到“try”成功的第一行,然后从 getinfo() 返回 function 从“try”运行(单击链接,转到页面,获取信息,然后单击后退按钮返回原始页面),然后不断迭代 table_rows 的 rest。

最后执行正确数量的 table_rows 迭代,“try” function 再次被触发(在 current_cell 工作之前的 print()),但 find_element_by_class 似乎没有在随后的 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 row in table_rows:”之前的更多代码,但我认为这不是问题,因为它在找到第一个“a0”后仍在遍历 table_rows 的 rest细胞。

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) 

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

仅供参考:我仍然看不出我现有代码有什么问题,因为当我注释掉该文本的 function 部分时,它正确地找到了所有 a0 单元格(#getinfo(current_cell)......谢谢@goalie1998 的建议)。 而且,对于这个新的解决方法,我没有更改 function 中的任何内容,它可以正常工作。 因此,它必须与 Selenium 在尝试迭代循环时搞砸有关(1)试图 find_element_by 页面上的某些东西(页面上存在多次,这就是你创建循环的原因) (2) 单击该循环中的链接,转到页面,返回页面,然后应该使用 find_element_by “函数”(可能是错误的术语用法)继续运行迭代以获得下一个存在于页面上的一个。 不知道为什么 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() function (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)

但是,我只需要对 my.getinfo() function 做两个小改动。

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

二,我现在可以使用我更基本的driver.find_element_by而不是我原来的table.find_element_by ....“table” 可能也可以,但我担心 memory 会丢失,因为我是现在在我的 function 中运行 .click() 代码。 我决定用“驱动程序” go 因为它更确定。 (我对编码还是很陌生,这可能没有必要。)

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。 注意 IF HAVING STALE ERRORS / 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”数字更改为您希望代码找到元素(最有可能是重新加载的页面)的任何时间

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM