Python 如何在selenium中选择html元素,而不管它位于哪个框架中?

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

我试图选择一个元素,它驻留在一个iframe中,也可能驻留在其他iframe中

是否可以在(python)selenium中的某个(子)iframe中选择一个元素,而不必事先选择iframe?是否有一种方法可以在每个iframe上“循环”并检查在哪里可以找到我的元素


在元素、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的好办法,这样编写测试就可以了。。。?