python+selenium遇到元素定位不到的问题,顺便记录一下自己这次的错误(报错selenium.common.exceptions.NoSuchElementException)

今天在写selenium一个发送邮件脚本时,遇到一些没有找到页面元素的错误。经过自己反复调试,找原因百度,终于解决了。简单总结一下吧,原因有以下几点:
一:Frame控件嵌套,.Frame/Iframe原因定位不到元素:
一般大家经常使用的邮箱算是frame嵌套的典型,通常注册登录都是在一个frame控件里面,而且标题正文可能是frame中嵌套iframe,接下里用我今天的脚本为例子(qq邮箱)

可以看到,如果我们要想找到收件人,标题就要先进到第一个Frame控件中,否则就会报错,但如果还要找到正文元素,就要进入第二个ifame控件中
可以使用 self.driver.switch_to.frame(传入id或者xpath值)方法进入Frame控件中。注(原来driver.switch_to_frame()这个方法在webdriver3.0中已经不支持了)
值得注意的一点的是:如果我此时我要点击发送按钮就需要先退出iframe控件,因为此时发送并不在正文所在的iframe控件当中,因此,无论你怎么定位,也定位不到。
此时就需要用到switch_to.default_content()这个方法。这个方法是无论你在哪一层级的frame控件中,只要调用此方法都会返回原始页面。如果我要找到发送按钮,就还要再次进入frame控件中去找
html界面结构如下
就是这个嵌套问题让我折腾一上午,总结一下吧:遇到多级Frame嵌套问题,一定要先仔细观察HTML的结构,别着急定位,观察好结构在往下进行,省的跟我一样浪费时间。

二:.页面还没有加载出来,就对页面上的元素进行的操作:
        这种情况一般说来,可以设置等待,等待页面显示之后再操作,这与人手工操作的原理一样:
        1设置等待时间;缺点是需要设置较长的等待时间,案例多了测试就很慢;
        2设置等待页面的某个元素出现,比如一个文本、一个输入框都可以,一旦指定的元素出现,就可以做操作。
        3在调试的过程中可以把页面的html代码打印出来,以便分析。
        解决方案:
        导入时间模块。(或者利用隐式等待或者显式等待)
        import time
        time.sleep(3)
 三:利用xpath进行定位:
        由于Xpath层级太复杂,容易犯错。虽然有人说xpath不好,但它真的功能很强大,可以找到父亲/祖先,这是其他方式都做不到的,如果遇到定位不到元素不妨试试xpath
        解决方案:
        1可以使用Firefox的firePath,复制xpath路径。该方式容易因为层级改变而需要重新编写过xpath路径,不建议使用,初学者可以先复制路径,然后尝试去修改它。
        2提高下写xpath的水平。
        这里推荐一篇文章吧:[selenium+python元素定位方法总结](http://https://www.cnblogs.com/yufeihlf/p/5717291.html)
        该博文详细总结了Xpath的使用,多组合定位一般都能实现定位问题。

        如何检验编写的Xpath是否正确?编写好Xpath路径,可以直接复制到搜狐浏览器的firebug查看html源码,通过Xpath搜索:如下红色框,若无报错,则说明编写的Xpath路径没错。
        find_element_by_xpath("//input[@id='kw']")
        
        (注:如果是动态元素,直接使用xpath进行定位)
    四:不可见元素定位

           如上百度登录代码,通过名称为tj_login查找的登录元素,有些是不可见的,所以加一个循环判断,找到可见元素(is_displayed())点击登录即可。
原文地址:https://www.cnblogs.com/lxc1997ye/p/11596115.html