报错原因
大家好,我是最渣的黑客,今天遇到一个问题,也是一个很让人头疼的问题,难度也不大,就是靠自己细心才能去解决。废话不多说,直接上问题。
当我在写企鹅号自媒体 web自动化的时候,在登录时,就直接让我停止的脚步,下方是我部分代码【错误代码】:
【前提提示:我的所有 find_element_by_xpath 的都是对的】
driver = webdriver.Chrome(r"D:\pro_py\auto_office\chromedriver\chromedriver.exe")
home_url = "https://om.qq.com/main"
login_url = "https://om.qq.com/userAuth/index"
driver.get(login_url)
def Qehao():
time.sleep(3)
driver.find_element_by_xpath('//*[@id="screens"]/div[2]/div[4]/div[2]/div[1]/div/div[1]/div[2]/div[1]/img').click() #点击QQ登录
time.sleep(3)
driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click() #点击账号密码登录【错误就在这里】
加上图演示:
1.点击QQ登录:
driver.find_element_by_xpath('//*[@id="screens"]/div[2]/div[4]/div[2]/div[1]/div/div[1]/div[2]/div[1]/img').click() #点击QQ登录
如图:
2.点击账号密码登录:
driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click() #点击账号密码登录【错误就在这里】
如图:
上方操作两步后直接报下方错误:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="switcher_plogin"]"}
(Session info: chrome=85.0.4183.121)
我用了以下两种方法方法没有得到解决:
1.ActionChains 方法
ActionChains(driver).move_to_element(
driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click()).perform()
2.execute_script 方法
release = driver.find_element_by_xpath('//*[@id="switcher_plogin"]')
driver.execute_script("$(arguments[0]).click()", release)
纠结了很久,不断地尝试F12,查看网站元素,最后发现 frame 标签这个坑了。一开始为什么没有发现 frame,是因为我习惯性直接使用F12的那个直接查找元素的功能,就是下图:
可以说是,习惯害人。让我白白浪费了30分钟的时间。废话不多说。直接说怎么查找问题。
查找问题:
按F12 ,仔细观察,截图如下:
红框显示,有两个frame ,是一个内嵌式的frame 。这个时候我们就需要进行 切换两次 frame 。在切换前,我先说下 frame 的使用方法:
frame 的使用方法:
前面需要导入的模块就只有 webdriver ,其他也不需要导入。
from selenium import webdriver #导入webdriver模块
driver = webdriver.Chrome() # 设置谷歌浏览器
然后可以使用 切换frame ,才能定位到自己的元素,切换的方法有很多种。
第一种:用frame的index来定位,第一个是0。
driver.switch_to.frame(0)
如图:
第二种:根据frame标签的的ID值,进行切换
driver.switch_to.frame("frame标签的ID")
如图:
可写成:
driver.switch_to.frame("qqAuthFrame_3696222")
第三种:根据frame标签的name值,进行切换
driver.switch_to.frame("frame标签的name值")
如图:
可写成:
driver.switch_to.frame("qqAuthFrame_3696222")
最后一种就是直接用driver.find_element_xx_xx() 方法定位切换了
driver.switch_to.frame(driver.find_element_by_id("qqAuthFrame_3696222"))
在这里切换 frame 的方法差不多都掌握了。
继续说问题了,当我按照上面,frame 切换方法定位发现还是有些问题。因为我发现每一次打开浏览器,进行点击QQ 登录的时候,发现frame 的 ID 和 name 属性 总是在变化。 如果你也用了诸多方法,还是提示 未找到元素no such element 这样的错误提示,就要注意了,是不是每一次打开网站时,那些标签的属性都不一样。这样用XPATH 以及 CSS,ID等 定位都会报错。这个时候就需要多了解 selenium 的定位方法的基础知识了。
推荐新手需要看下关于selenium 文章的讲解:Python Selenium库的使用
解决方法:
因为是涉及到两个嵌套的 frame ,所以要进行两次的切换,代码如下:
driver = webdriver.Chrome(r"D:\pro_py\auto_office\chromedriver\chromedriver.exe")
home_url = "https://om.qq.com/main"
login_url = "https://om.qq.com/userAuth/index"
driver.get(login_url)
def Qehao():
time.sleep(3)
driver.find_element_by_xpath('//*[@id="screens"]/div[2]/div[4]/div[2]/div[1]/div/div[1]/div[2]/div[1]/img').click()
time.sleep(3)
driver.switch_to.frame(driver.find_elements_by_tag_name('iframe')[0]) #利用查找标签名称进行列表[0]定位切换到下一个frame
driver.switch_to.frame('ptlogin_iframe') # 这个ID 不会变化直接进行ID定位切换
driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click() # 可以正确点击 账号密码登录
记得当输入好账号密码,进入到主页后,要进行切换到 主目录,以下是一次性退出所有frame。
driver.switch_to.default_content()
下方是后退一步,切换到上一个 frame【看情况使用,一般都是用上方那个】
driver.switch_to.parent_frame()
这是我讲了第三个 python3 selenium web自动化遇到 Message: no such element: Unable to locate element 的问题的解决办法,其实在做自动化的时候,每次遇到没找到元素定位这种错误就很恼火,因为有些时候,明明是对的,偏偏运行就是报错。每次都要把每个解决办法都要尝试一下,是一个很费时间的问题。有些时候并不是 方法不对,可能定位是出现相同的元素标签,也会报错,未找到元素定位等问题。希望这篇能给你初学web 的同学和同事带来帮助。如果你喜欢我的文章,点个关注呗。