如何解决"WebDriverException:消息:TypeError:无法访问死对象"并等待使用Selenium和Python的框架可用 [英] How to address "WebDriverException: Message: TypeError: can't access dead object" and wait for a frame to be available using Selenium and Python

查看:280
本文介绍了如何解决"WebDriverException:消息:TypeError:无法访问死对象"并等待使用Selenium和Python的框架可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要测试一个相当复杂的网页设置,其中包含嵌套框架.

I have a rather complex webpage setup I need to test, containing nested frames.

在实际问题中,硒代码正在加载包含要切换到的框架的新网页内容.为了避免任何明确的等待,我尝试了以下代码片段:

In the actual problem the selenium code is loading new webpage contents containing a frame, which I want to switch to. In order to avoid any explicit waits, I tried the following code snippet:

self.driver.switch_to_default_content()
WebDriverWait(self.driver, 300).\
        until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'frame1')))
WebDriverWait(self.driver, 300).\
        until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'frame2')))

但是,此代码段始终会失败,并导致以下错误:

However, this snippet always fails and results in the following error:

  ...
  File "/home/adietz/Projects/Venv/nosetests/local/lib/python2.7/site-packages/selenium/webdriver/support/wait.py", line 71, in until
    value = method(self._driver)
  File "/home/adietz/Projects/Venv/nosetests/local/lib/python2.7/site-packages/selenium/webdriver/support/expected_conditions.py", line 247, in __call__
    self.frame_locator))
  File "/home/adietz/Projects/Venv/nosetests/local/lib/python2.7/site-packages/selenium/webdriver/support/expected_conditions.py", line 402, in _find_element
    raise e
WebDriverException: Message: TypeError: can't access dead object

但是,如果我还要睡觉:

However, if I use a sleep in addition:

time.sleep(30)
self.driver.switch_to_default_content()
WebDriverWait(self.driver, 300).\
        until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'frame1')))
WebDriverWait(self.driver, 300).\
        until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'frame2')))

selenium能够找到框架内的框架并切换到该框架.在错误情况下,硒似乎切换为框架1",而尚未加载框架2",但是框架2"在其他框架1"实例中被加载,或者硒无法识别(可能是错误?).因此,硒现在位于某些"frame1"内部,并且由于某些原因并未意识到"frame2"已加载.

selenium is able to find the frame inside the frame and switch to it. It looks like in the error case selenium switches to 'frame1' while 'frame2' is not yet loaded, but 'frame2' gets loaded in some other instance of 'frame1', or not recognized by selenium (maybe a bug?). So now selenium is inside some 'frame1' and for some reasons does not realize that the 'frame2' has been loaded.

我可以解决此问题的唯一方法(不使用长时间睡眠)是使用以下丑陋的代码:

The only way I can fix this (without using a long sleep) is by using this ugly piece of code:

    mustend = time.time() + 300
    while time.time() < mustend:
        try:
            self.driver.switch_to_default_content()
            self.driver.switch_to.frame(self.driver.find_element_by_id("frame1"))
            self.driver.switch_to.frame(self.driver.find_element_by_id("frame2"))               
            break
        except WebDriverException as e:
            self.log("Sleeping 1 sec")
            time.sleep(1)
    if time.time() > mustend:
        raise TimeoutException

因此,每当我得到一个WebDriverException(死对象)时,我都会转到顶层框架并尝试切换到内部框架-逐帧.

So whenever I get a WebDriverException (dead object), I go to the top-level frame and try to switch to the inner frame - frame by frame.

还有其他可以尝试的方法吗?

Is there any other approach I can try?

其他信息

  • iframe是嵌套的,即"frame2"位于"frame1"内部.

推荐答案

更好的方法是制定自己的期望条件. 例如:

Better approach is to make your own expected_condition. For example:

class nested_frames_to_be_available_and_switch:
    def __init__(self, *args):
        """
        :param args: locators tuple of nested frames (BY.ID, "ID1"), (BY.ID, "ID2"), ...
        """
        self.locators = args

    def __call__(self, driver):
        try:
            for locator in self.locators:
                driver.switch_to.frame(driver.find_element(*locator))
        except WebDriverException:
            driver.switch_to_default_content()
            return False
        return True

WebDriverWait(driver, 300).until(nested_frames_to_be_available_and_switch((By.ID, 'frame1'), (By.ID, 'frame1')))

但是也许没有必要..告诉我,我需要查看您的html DOM.

But maybe there is no need for that.. To tell so I need to see your html DOM.

这篇关于如何解决"WebDriverException:消息:TypeError:无法访问死对象"并等待使用Selenium和Python的框架可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆