我试图使用python selenium实现一些自动化功能,但遇到了一些奇怪的行为
html的总体布局:
<html>
<body>
<div class="parent">
<iframe style="display: none"> ... </iframe>
<iframe style="display: none"> ... </iframe>
<iframe style="display: block">
#document
...
<div class="someClass"> ... </div>
</iframe>
<iframe style="display: none"> ... </iframe>
<iframe style="display: none"> ... </iframe>
</div>
</body>
现在,每个iframe实际上都有相同的内部html,来自网站的代码似乎是随机选择哪个iframe获得display="block"
。但是,我找不到任何iFrame
我尝试了一种标准方法:iframe = driver.find_elements_by_xpath("//iframe[contains(@style, 'display:block')]")
如果失败了,我就试图找到任何iframe:driver.find_element_by_tag_name("iframe")
他们都没有找到任何iframe元素。我看到以下错误:
Traceback (most recent call last):
File "myfile.py", line 60, in <module>
iframe = driver.find_element_by_xpath("//iframe[contains(@style, 'display: block')]")
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 394, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
'value': value})['value']
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: The result of the xpath expression "//iframe[contains(@style, 'display: block')]" is: [object HTMLIFrameElement]. It should be an element.
(Session info: chrome=93.0.4577.63)
关于xpath返回[object HTMLIFrameElement]的原因,以及我在通过xpath搜索时无法访问其他对象的原因,有什么想法吗
编辑
新代码选项1:
iframes = driver.find_elements_by_xpath(".//iframe[contains(@style,'display: block')]")
这仍然抛出与上面完全相同的错误
新代码选项2:
parent = driver.find_element_by_xpath("//div[@class='parent']")
iframes = parent.find_elements_by_tag_name("iframe")
// when I print typeof iframes here, it's a list of dicts
// find the right index. Here, for simplicity, I just set it a default value
index = 4
// ...
driver.switch_to.frame(iframes[index])
我得到以下错误:
Traceback (most recent call last):
File "myfile.py", line 76, in <module>
driver.switch_to.frame(iframe)
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\switch_to.py", line 89, in frame
self._driver.execute(Command.SWITCH_TO_FRAME, {'id': frame_reference})
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: missing 'ELEMENT'
(Session info: chrome=93.0.4577.82)
当我打印iFrame时:
[{}, {}, {}, {}, {u'ontouchmove': {}, u'ontouchstart': {}}, {}, {}, {}, {}, {}]
作为参考,这是我试图点击的页面。有时,您必须刷新几次才能获得挑战,而使用selenium时,刷新频率要高得多。此外,使用无头模式会导致每次挑战都会发生https://catalog.usmint.gov/coins/coin-programs/morgan-and-peace-silver-dollar-coins/
我所见过的唯一类似的情况是,当我试图从任何类似的广告中获取一个
iframe
时,它在我试图获取它们的那一刻消失了我总是用
getElementsByTagName("iframe")
解决这个问题,所以在加载页面之前,请尝试再等待一点,以确保在运行iframe之前完全初始化了iframe。 在this question上已经讨论了一种实现这一点的方法另外,这里是python等待模式的官方文档: https://selenium-python.readthedocs.io/waits.html
PS:刚刚测试了您的示例html页面,当使用
document.getElementsByTagName("iframe")
时,我可以很容易地在我的浏览器上获得它们,如下图所示,因此您很可能遇到了我上面提到的问题之一,因为您的Selenium应该能够看到它们,假设它们是静态的,并且不会消失,并且您的页面已完全加载:额外细节
在您的例子中,如果您作为属性接收
HTMLIFrameElement
而不是简单的iframe
标记,这意味着您正在处理一个Web界面,您可以从该界面直接访问它们的属性,这意味着您确实在页面上找到了一个iframe。 您可以使用它的属性来访问native APIs,它有一个.src
属性,反映它正在加载的URL,在许多情况下,您可以在不同的页面中打开此URL,并直接获取它所呈现的内容(除非URL包含一些CORS块)。 此外,确实存在一些与WaitForPageToLoad
相关的硒铬错误,可以使用其他方法修复,如described here,尽管我认为这不是您当前的问题?您是否尝试过Selenium文档的示例
See cap. "Using an Index"
我遇到过这样的情况:帧需要时间渲染,并且最初没有被代码捕获。以下方法对我很有效
相关问题 更多 >
编程相关推荐