【问题标题】:Selenium Error - Try/Except, element not attached to pageSelenium 错误 - 尝试/排除,元素未附加到页面
【发布时间】:2019-10-14 19:41:03
【问题描述】:

我正在做一个程序,其中用户登录到他的帐户(100% 完成),然后它转到一个站点(www.site.com(不是这个))并搜索一个元素。问题:元素并不总是存在,它会随机弹出,所以我想做一个程序,当它没有掉落(糖果)时,它会转到另一个选项卡。

我尝试了很多东西,改变循环,在 try 中添加/删除东西,除了等等......

for i in range(10000):
    while True:
        print("Starting!")
        try:
            element = browser.find_element_by_xpath('//*[@id="redeem-candy-voucher"]')#.click()
        except NoSuchElementException:
            pass
        browser.execute_script("arguments[0].click();", element)

        print("Clicked Candy! Skullbux Gained!")

        time.sleep(3)

        browser.execute_script("window.open('');")
        browser.switch_to.window(browser.window_handles[1])
        browser.get("https://www.brickplanet.com/events/trick-or-treat")

        time.sleep(3)

        try:
            element = browser.find_element_by_xpath('//*[@id="redeem-candy-voucher"]')#.click()
        except NoSuchElementException:
            pass
        browser.execute_script("arguments[0].click();", element)

        print("Clicked Candy! 0.25 Gained!")
        #browser.close()
        time.sleep(5)

有 2 个可能的错误。 它找到元素,然后刷新页面,然后出现错误:

DevTools listening on ws://127.0.0.1:52479/devtools/browser/a2cfa4b3-e538-49fb-872c-114db52513ce
Starting!
Clicked Candy! Skullbux Gained!
Traceback (most recent call last):
  File "C:\Users\DOMA\Desktop\bp hack.py", line 54, in <module>
    browser.execute_script("arguments[0].click();", element)
  File "C:\Users\DOMA\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 636, in execute_script
    'args': converted_args})['value']
  File "C:\Users\DOMA\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\DOMA\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=77.0.3865.90)

当它根本找不到任何元素时:

DevTools listening on ws://127.0.0.1:52432/devtools/browser/9250b0fb-2742-4a8b-9043-b7cdbec1f8e3
Starting!
Traceback (most recent call last):
  File "C:\Users\DOMA\Desktop\bp hack.py", line 38, in <module>
    browser.execute_script("arguments[0].click();", element)
NameError: name 'element' is not defined

Process returned 1 (0x1)        execution time : 20.796 s
Press any key to continue . . .

【问题讨论】:

    标签: python selenium


    【解决方案1】:

    这两个问题的根本原因相同;当你这样称呼时:

            try:
                element = browser.find_element_by_xpath('//*[@id="redeem-candy-voucher"]')#.click()
            except NoSuchElementException:
                pass
            browser.execute_script("arguments[0].click();", element)
    

    如果element = browser.find_element_by_xpath('//*[@id="redeem-candy-voucher"]') 因任何原因失败,则:

    • 如果您的代码通过except 路由而没有通过try 路由,则element 将不会被定义。
    • element 可能引用您在第一个try 块中找到的元素,但由于该元素未附加到DOM,因此将引发StaleElementReferenceException。

    你应该做的是避免这种行为是这样的:

            try:
                element = browser.find_element_by_xpath('//*[@id="redeem-candy-voucher"]')
                browser.execute_script("arguments[0].click();", element)
            except NoSuchElementException:
                pass
    
    

    【讨论】:

      【解决方案2】:

      StaleElementReferenceException 发生是因为您正在刷新页面。页面刷新后,定位到的元素就不是同一个元素了,所以需要重新找元素来获取新的实例。

      我会在你的元素上添加一个wait,这也应该解决找不到元素的情况:

      # Wait for element to exist
      element = WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.XPATH, "//*[@id='redeem-candy-voucher']")))
      
      browser.execute_script("arguments[0].click();", element
      

      至于您的 StaleElement 问题 - 如果您刷新页面,您将需要重新找到该元素。这是一个例子:

      # wait and find the element
      element = WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.XPATH, "//*[@id='redeem-candy-voucher']")))
      
      # refresh
      driver.refresh()
      
      # This will throw an exception!
      # element.click()
      
      # Find fresh instance of element to avoid the exception.
      element = WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.XPATH, "//*[@id="redeem-candy-voucher"]")))
      
      element.click()
      

      希望这会有所帮助。

      【讨论】:

      • 所以我只需要在我的代码中的某个地方放一些这样的东西吗?还是我可以全部使用?
      • 第一个示例可以用代码示例中的NoSuchElement 错误替换您的try / except 块。第二个比较笼统,只是举例说明如何避免StaleElementReference异常。 XPath ID 定位器中的 " 双引号也存在问题,我已修复。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多