Python 如何在selenium中选择html元素,而不管它位于哪个框架中?
我试图选择一个元素,它驻留在一个iframe中,也可能驻留在其他iframe中 是否可以在(python)selenium中的某个(子)iframe中选择一个元素,而不必事先选择iframe?是否有一种方法可以在每个iframe上“循环”并检查在哪里可以找到我的元素Python 如何在selenium中选择html元素,而不管它位于哪个框架中?,python,html,selenium,selenium-webdriver,iframe,Python,Html,Selenium,Selenium Webdriver,Iframe,我试图选择一个元素,它驻留在一个iframe中,也可能驻留在其他iframe中 是否可以在(python)selenium中的某个(子)iframe中选择一个元素,而不必事先选择iframe?是否有一种方法可以在每个iframe上“循环”并检查在哪里可以找到我的元素 在元素、html内容和iFrame即将加载的情况下,如何做到这一点?编写自己的递归查找程序应该很容易。很抱歉,我不懂python,但在Java中,它可能类似于: public void findInAllFrames(WebElem
在元素、html内容和iFrame即将加载的情况下,如何做到这一点?编写自己的递归查找程序应该很容易。很抱歉,我不懂python,但在Java中,它可能类似于:
public void findInAllFrames(WebElement e, String targetIdStr) {
List<WebElement> l = e.findElements(By.tagName("iframe"));
for(int inx=0; inx<l.size(); inx++) {
List<WebElement> targets = l.get(inx).findElements(By.id(targetIdStr));
if(targets.size()>0) {
// Do something with your targets
}
findInAllFrames(l.get(inx), targetIdStr);
}
}
public void findInAllFrames(WebElement e,String targetistr){
列表l=e.findElements(按.tagName(“iframe”);
对于(int inx=0;inx0){
//对你的目标做点什么
}
findInAllFrames(l.get(inx),targetIdStr);
}
}
否,如果不切换到相应的iframe
,则无法通过Selenium
在iframe
中与任何网站元素进行交互
原因:
加载页面时,Selenium
的焦点默认保持在顶部窗口上。顶部窗口
包含其他iFrame
和框架集
。因此,当我们需要与iframe中的WebElement
交互时,我们必须通过以下提到的方法之一切换到相应的iframe
:
帧切换方法:
我们可以通过3种方式切换到帧
按帧名称:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"name_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"xpath_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"css_of_iframe"))
名称
iframe的属性,通过该属性我们可以切换到它
例如:
driver.switch_to.frame("iframe_name")
driver.switch_to.frame("iframe_id")
driver.switch_to.frame(0)
driver.switch_to.frame(1)
driver.switch_to.default_content()
driver.switch_to.parent_frame()
按帧ID:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"name_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"xpath_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"css_of_iframe"))
ID
iframe的属性,通过该属性我们可以切换到它
例如:
driver.switch_to.frame("iframe_name")
driver.switch_to.frame("iframe_id")
driver.switch_to.frame(0)
driver.switch_to.frame(1)
driver.switch_to.default_content()
driver.switch_to.parent_frame()
按帧索引:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"name_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"xpath_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"css_of_iframe"))
假设页面中有10个帧,我们可以使用索引切换到iframe
例如:
driver.switch_to.frame("iframe_name")
driver.switch_to.frame("iframe_id")
driver.switch_to.frame(0)
driver.switch_to.frame(1)
driver.switch_to.default_content()
driver.switch_to.parent_frame()
切换回主框架:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"name_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"xpath_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"css_of_iframe"))
我们可以使用默认内容()
或父框架()
切换回主框架
例如:
driver.switch_to.frame("iframe_name")
driver.switch_to.frame("iframe_id")
driver.switch_to.frame(0)
driver.switch_to.frame(1)
driver.switch_to.default_content()
driver.switch_to.parent_frame()
切换帧的更好方法:
切换帧的一种更好的方法是,在预期条件设置为的情况下,诱导WebDriverWait
使帧可用,并将其切换为可用,如下所示:
- 通过
帧ID
:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"name_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"xpath_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"css_of_iframe"))
- 通过帧名称
:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"name_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"xpath_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"css_of_iframe"))
通过帧Xpath
:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"name_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"xpath_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"css_of_iframe"))
通过框架CSS
:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"name_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"xpath_of_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"css_of_iframe"))
参考文献
有关详细讨论,请参见:
可以通过在每个帧上递归使用querySelectorAll
来进行JavaScript注入。但是,脚本将受到同源策略的限制,这意味着您只能使用来自与主页相同域的帧来执行此操作。那么我想这不是我的选项。无论如何,感谢您的建议……如果您使用的是Chrome,那么应该可以通过使用开关“--disable web security”启动浏览器来禁用同源策略。我想知道为什么selenium会如此复杂。使用GUI时,只需“单击”一个元素。对于selenium,您会遇到框架方面的这些不可能的问题……但是,首先,selenium被构造成如此不可用,这有什么原因吗?为什么人们不想出一个关于selenium的好办法,这样编写测试就可以了。。。?