当前位置: 首页 > 知识库问答 >
问题:

selenium中缺少iframe元素

林星阑
2023-03-14

我试图使用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得到了显示="块"。然而,我找不到任何iframe。

我尝试了一种标准方法:iframe=driver。通过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/


共有3个答案

唐弘益
2023-03-14

我遇到过这样的情况:帧需要时间渲染,并且最初没有被代码捕获。以下方法对我很有效。

iframes = driver.find_elements_by_tag_name('iframe')

for iframe in iframes:
if 'block' in iframe.get_attribute('style'):
    driver.switch_to.frame(iframe)
    break
皇甫建木
2023-03-14

每当我遇到iFrame时,我大部分时间都无法直接访问它们。相反,我必须将xpath更改为iframe及其父元素,并从那里访问它,如下所示。

try:
    # instead of xpath = '//iframe' try accessing the parent element and add /iframe
    iframe_xpath = '//*[@id="parent-element"]/iframe'
    
    # or more specifically to get the right one in your case
    iframe_xpath = '//*[@id="parent-element"]/iframe[contains(@style, "display: block")]'

    WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, iframe_xpath)))
              

    driver.switch_to.frame(driver.find_element(By.XPATH, iframe_xpath))
    # Do your thing in the frame
    ...

    # go back to the normal content
    driver.switch_to.default_content()
except:
    # Ideally you catch each error separately; TimeoutException, NoSuchElementException, ...
    pass
诸葛利
2023-03-14

我见过的唯一一种情况是,当我试图从任何类似的广告中访问一个iframe时,它在我试图获取它们的那一刻就消失了。

我总是用getElementsByTagName("iframe")来解决这个问题,所以在加载页面之前,试着多等一会儿,以确保iframe在运行之前已经完全初始化了。一个方法做到这一点已经讨论了这个问题

另外,这里是python等待模式的官方文档:https://selenium-python.readthedocs.io/waits.html

附言:刚刚测试了你的示例html页面,当使用document.getElementsByTagName(“iframe”)时,我可以很容易地在浏览器上找到它们,正如你在下面的图片上看到的,所以很可能你遇到了我遇到的问题之一上面提到,因为你的Selenium应该能够看到它们,假设它们是静态的,不会消失,并且你的页面已经满载:

在您的例子中,如果您将htmliframelement作为属性接收,而不是一个简单的iframe标记,这意味着您正在处理一个Web界面,您可以从该界面直接访问它们的属性,这意味着您确实在页面上找到了一个iframe。您可以使用它的属性访问本机API,并且它有一个。src属性,反映它正在加载的URL,在许多情况下,您可以在不同的页面中打开此URL,并直接获取它所呈现的内容(除非URL包含某些CORS块)。此外,Selenium和Chrome确实存在一些与WaitForPageToLoad相关的bug,可以使用其他方法修复,如本文所述,尽管我认为这不是您当前的问题。

 类似资料:
  • 我对selenium的第一个测试是单击网站上的按钮。我需要点击的第一个按钮是“是的,你可以使用cookies”——网站弹出窗口中的按钮。但似乎selenium并没有找到那个按钮,即使我添加了一条等待线。我也尝试了弹出窗口中的其他按钮,但是我的元素找不到任何一个可以点击的按钮。元素在iframe中,所以我想我必须更改为它,但似乎我做错了什么。 这就产生了错误 如果我尝试在更改为iframe后直接单击

  • 本文向大家介绍java selenium处理Iframe中的元素示例,包括了java selenium处理Iframe中的元素示例的使用技巧和注意事项,需要的朋友参考一下 java selenium  处理Iframe 中的元素 有时候我们定位元素的时候,发现怎么都定位不了。 这时候你需要查一查你要定位的元素是否在iframe里面 阅读目录 什么是iframe iframe 就是HTML 中,用于

  • 我知道我必须切换到一个iframe当我想要点击和元素在它里面。iFrame的开头是这样的: 我使用切换到它 然后,我尝试单击Iframe中的“Join”按钮,使用它的XPath: 在一张桌子里面。 我可以选择“以前的会议”选项卡,但不能使用加入或邀请按钮。 这两个图像只是一个接着一个。

  • 如何使用selenium Python从主机A(在本例中为jsfiddle.net)单击此处的红色按钮?(java脚本限制策略错误,不让我去做)。我也不想直接点击红色按钮。谢了。

  • 问题内容: 我正在尝试使用Selenium,Python和BS4在iframe中访问iframe 在返回的文本中,似乎还有两个iframe。我将如何访问那些?我尝试上面的代码没有成功。 问题答案: 将返回到文档顶部。发生的事情是您切换到第一个,然后又切换回文档的顶部,然后尝试查找第二个。硒找不到第二个,因为它在第一个之内。 如果删除第二个,则应该没问题:

  • 问题内容: 到目前为止,这就是我所拥有的:我已将框架切换到其父框架,然后又切换到了我无法找到的框架: 由于找不到“ frame”元素,因此出现此错误: org.openqa.selenium.NoSuchElementException:无法找到元素 HTML: 我要定位的iframe位于多个div中。它与错误有关系吗?还是我的元素查找方式有问题? 问题答案: 按照HTML,一旦进入 父框架 ,就