问题描述:
在selenium定位的时候,有时候明明觉得定位的方法和代码都没有问题但是就是报错,检查了感觉定位的路径也没问题,但还是定位不到。
原因分析:
后来查询了很多才知道有frame和窗口切换导致我定位的路径没问题就是打不开我定位的页面
解决方案:
当我们遇到frame嵌套页面时,webdrive只能在一个页面上进行元素识别,没法对frame内的元素进行定位,需要通过 driver.switch_to.frame()切换frame再进行定位;
而不同句柄窗口的切换,selenium提供了 driver.switch_to.window() 可以切换到任意窗口。
(1)多frame表单切换
在下图中,web页面有4个元素,元素1、元素2、在frame1下的元素3和在frame2下的元素4。如果要定位元素3,就需要先切换到frame1,如果要定位元素4,就要先切回web页面,再跳转到frame2,最后才能定位到元素4。
部分html代码如下:
<html>
<body>
......
<div class="row-fluid">
<div class="s1">
<h3>frame1</h3>
<iframe id="search_1" name="af" src="http://www.xx.com" width="800" height="300">
<input name='value' id='s_value'>
</iframe>
</div>
</div>
<div class="row-fluid">
<div class="s2">
<h3>frame2</h3>
<iframe id="search_2" name="bf" src="http://www.xx2.com" width="800" height="300">
<input name='value2' id='s_name'>
</iframe>
</div>
</div>
......
</body>
</html>
根据元素定位以及frame定位方法,如下:
# -*- coding:utf-8 -*-
from selenium import webdriver
from time import sleep
#打开谷歌浏览器
driver=webdriver.Chrome()
# 打开url地址
driver.get("https://www.xx.com")
# 要定位元素id为s_value,就要先跳转到iframe1
#切换iframe:通过id、name直接切换iframe,也可以定位iframe元素,将元素作为参数传递
driver.switch_to.frame("search_1")
#再定位到id:s_value
driver.find_element_by_id("s_value")
# 切回主页面
driver.switch_to.default_content()
# 要定位元素id为s_name,就要先跳转到iframe2
driver.switch_to.frame("search_2")
#再定位到id:s_name
driver.find_element_by_id("s_name")
# 切回上级iframe
driver.switch_to_parent_frame()
#关闭浏览器
driver.quit()
(2)多句柄窗口切换
一个页面 = 一个句柄窗口
操作新的页面,就需要切换到新的句柄,是一个固化的模式
1、获取新的句柄
2、切换到新的句柄
PS:如果要关闭原有的标签页,操作新的标签页:
1、获取所有句柄
2、关闭原有标签页
3、切换到新的句柄
PPS:在操作页面时,一定要注意最多保留俩个页面存在,
from selenium import webdriver
#打开谷歌浏览器
driver=webdriver.Chrome()
# 打开url地址
driver.get("https://www.xx.com")
#获得当前窗口
curr_handle=driver.current_window_handle
#打开新窗口
driver.switch_to.new_window('window') # tab表示标签页,window表示浏览器
#获取所有的窗口
all_handles=driver.window_handles
#循环判断窗口是否为当前窗口
for handle in all_handles:
if handle != curr_handle:
driver.switch_to.window(handle)
print("跳转到非当前窗口!")
#跳转到原先的窗口
driver.switch_to.window(curr_handle)
#关闭浏览器
driver.quit()
实际应用:
以网易云音乐用户登录- QQ登录-点击头像进行登录为例
import time
from selenium import webdriver
# 打开页面
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://music.163.com')
driver.implicitly_wait(10)
# 切换到frame页面 用户登录
driver.switch_to.frame('g_iframe')
driver.find_element('link text', '用户登录').click()
# 切换回主页面 选择其他登录模式
driver.switch_to.default_content()
driver.find_element('link text', '选择其他登录模式').click()
time.sleep(2)
#选择qq
driver.find_element('id', 'j-official-terms').click()
driver.find_element('link text', 'QQ登录').click()
#切换到新打开的窗口
handles = driver.window_handles
driver.switch_to.window(handles[1])
#切换iframe 点击头像进行登录
driver.switch_to.frame('ptlogin_iframe')
driver.find_element('id', 'img_out_863604278').click()
登录成功!