在iframe下处理 #document 的方法

Ways to deal with #document under iframe

提问人:Alexandre 提问时间:11/8/2018 最后编辑:undetected SeleniumAlexandre 更新时间:8/21/2019 访问量:20995

问:

对于我现在正在测试的门户,我遇到了无法创建任何 xpath 定位器的问题,一段时间后我发现这是因为“#document”,这会切断路径并使简单的“复制 xpath”将路径定向到完全不同的元素。

<iframe id="FRAMENAME" src="/webclient/workspace/launch-task/REMbl?ds=BP" width="100%" height="100%" frameborder="0" data-navitemname="navitemname" style="" xpath="1">
#document
    <html>
        CODE....
    </html>

我找到了解决这个问题的方法是简单地添加一个开关,如下所示:

driver.switchTo().frame("FRAMENAME");

这可工作并使其余代码正常工作,但是需要一些额外的时间来处理此命令,直到代码移动到下一行。

所以我想问一下,有没有更好的解决方案?更智能/更快的东西?

我担心当我有很多脚本的时候,执行时间会太长。

例如,我不使用 id 定位器,因为它们都是动态的,所以有时需要 xpath。

谢谢!

JavaScript 硒 web驱动程序 iframe 量角器

评论

0赞 Guy 11/8/2018
这是访问内部元素的唯一方法。你可以在代码审查时发布你的代码,也许有人会看到你可以改进的地方。<iframe>
0赞 Alexandre 11/8/2018
嗨,感谢您的回答,该门户不是由我们开发的,这使得更改代码变得困难,我们正在开发一个工具来使用它,此测试的目的是检查信息是否正确导入。测试代码的其余部分运行得很快,唯一的一点是速度变慢,但无论如何我都会在那里发布以防万一。谢谢!
0赞 Guy 11/8/2018
我建议你把你的代码发布在那里,而不是网站:)。转换需要多少时间,我从来没有监禁过任何问题。
0赞 Alexandre 11/8/2018
啊,好吧,嘿嘿嘿,这取决于屏幕,但我会说每个开关需要 4 到 6 秒,所以在我需要与不同帧交互的测试用例中,这会增加执行时间,目前这不是大问题,但将来可能需要太长时间。感谢您的帮助!

答:

8赞 Oleksii 11/12/2018 #1

要使用内部的元素,您必须切换到这个特定的 .iframeiframe

您的解决方案是正确的。Selenium 没有任何其他方法可以处理包装器。.switchTo().frame("FRAMENAME");iframe

6赞 undetected Selenium 11/13/2018 #2

内联框架

根据使用内联框架中的文档,内联框架是一种将文档嵌入到 HTML 文档中的构造,以便嵌入的数据显示在浏览器窗口的子窗口中。这并不意味着完全包含并且两个文档是独立的,并且它们都被视为完整的文档,而不是将一个文档视为另一个文档的一部分。


iframe 结构和详细信息

  • 通常,iframe 元素的形式为:

    <iframe src="URL" more attributes>
    alternative content for browsers which do not
    support iframe
    </iframe>
    
  • 支持 iframe 的浏览器在子窗口中显示 URL 引用的文档,通常带有垂直和/或水平滚动条。此类浏览器会忽略 iframe 元素的内容(即开始标签和结束标签之间的所有内容)。不支持 iframe(或禁用此类支持)的浏览器会执行相反的操作,即处理内容,就好像 and 标签不存在一样。因此,尽管某些浏览器忽略了内容,但内容很重要。<iframe...></iframe><iframe...></iframe>

  • 总而言之,内联框架并不意味着包含功能,尽管它有时可能具有类似的目的。

  • 请注意,当使用内联框架时,浏览器(如果支持它们)会向 in in the iframe 元素所引用的服务器发送请求,并在获取请求的文档后将其显示在内联框架中。从这个意义上说,内联框架是浏览器和服务器的联合问题,但只有浏览器需要专门识别 iframe;从服务器的角度来看,对文档只有一个普通的HTTP请求,它发送文档时没有(或不需要)任何关于浏览器将如何处理它的想法。URL


更智能的东西

根据最佳实践,在切换到 iframe 时,您需要诱导 WebDriverWait,如下所示:

  • 切换帧名称(Java 示例代码):

    new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.name("frame_name")));
    
  • 通过 iframe XPath(Python 示例代码)切换:

    WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id='ptifrmtgtframe' and @name='TargetContent']")))
    
  • 通过 iframe CssSelector 切换(C# 示例代码):

    new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe#twitter-widget-0")));
    

参考

您可以在以下位置找到一些相关讨论:


TL的;博士

内联帧与普通帧