-
解决
Selenium
弹出新页面无法定位元素
问题
问题来源
一般来说,
我们进行自动化登录,
之后
想直接进行对图书的续约操作,
但是
利用元素定位的方法,
p>
怎么都找不到元素,
我一直以为是我的规则用的不对,
导
致元素找不到,其实,只是窗口句柄还停留在上一个页面而已
!
对于新弹出的页
面还没有定位
!!!
那怎么可能找得到在新页面的元素呢
!!
这是新手
(
我
)
犯下最大
的错误,只顾于对元素方法的定位,却没有意识到页面发生跳转
后的
handles
的变化。
请看测试
;
#coding=utf-8
from selenium import webdriver
import time
browser=x()
(
_element_by_id(
_element_by_id(<
/p>
(3)
sreach_window=t_window_handle
//
此行代码用来定位当前页
面
_element_by_xpath(
v[4]/h3/a
(5)
当然如果我一点都不改,
也是进行不了测试的,
这位大哥把注释符号写错了,
不是
//
,而是
#
啊大哥
ok
,然后运行下:出错了
所以我
感到好奇的是,
这位大哥到底有没有跑过这段代码,
看着原创的
样子
应该没有抄袭才对啊,那应该是测试过代码才对,但是可重复性在哪
?
最后发现
需要修改
http
成这样才能访问
(
大哥少加个
/)
:
(
修改后代码如下:
#coding=utf-8
from selenium import webdriver
import time
browser=x()
(
_element_by_id(
_element_by_id(<
/p>
(1)
sreach_window=t_window_handle
#
此行代码用来定位当前页面
(2)
_element_by_xpath(
v[4]/h3/a<
/p>
我这里修改了一下
div[4]
,大哥的
索引直接到有道翻译
了,不利于下一步测试
(1)
ok
,这次能正常索引到值,但是
!!!
我要说的是但是
!!!
这根本没有跳转页面
!
还是在同一个页面进行
操作的
!
如果我把大哥的代码
改成:<
/p>
在我测试
的时候,
发生了奇怪的事情,
同样的代码,
有时候能跑有时候抛出
错误,我已设定休眠时间,难道是我频繁访问导致百度封我<
/p>
?
刚才上述的代码我
都实际测试过的,但
是现在又不能用了
--wtf--
,所以。我换了稳定的引擎,
我
采用
bing
搜索来试试,上面的全
部作废,如果有人知道问题出在哪,请留言
7.19
补充
应该是搜索引擎热点的问题,
p>
每次键入相同的值可能搜索结果首项会不一致
的,百度可能更新热点
比较快把,所以出现了我所谓不稳定的情况
正题测试
我和上述那位大哥不同的观点在于,他用的
sreach_window=t_window_handle
方法并不能实现对新窗口句柄的捕
捉,我以
bing
主页为测试页,重新构造
了一下,
#coding=utf-8
from selenium import webdriver
import time
browser=x()
(
keywords = 'MrLevo520 CSDN'
send_keywords=('utf-8')#
中英混输
入可防止乱码
_element_by_id(
(1)
#----------
操作
一:进行对关键字
MrLevo520
CSDN
搜索
----------------
_element_by_id(
执行此
操
作会进行搜
索,但是没有弹出新窗口,所以句柄不用重定位
(3)
#----------
操作二:对搜索页面
我的
C
SDN
进行点击操作
--------------
_element_by_xpath(
进
行当
前页面点击第一项
#------
--
操作三:对新弹出的页面再点击
贡
献的资源
选项
-----
sreach_window=t_window_handle
_element_by_xpath(
3]
(5)
浏览器运行结果只到如图:
而且抛出错误:
ElementException: Message: Unable to
locate
element:
{
]
p>
可见,
此语句并没有实现句柄重定位的功能,
然后我再试试下面的方法,
所
有语句不变,只改变获取当前句
柄的语句,改成
_to_window(_handles[1])
最后程序应该是这样:
#coding=utf-8
from selenium
import webdriver
import time
browser=x()
(
keywords = 'MrLevo520 CSDN'
send_keywords=('utf-8')#
中英混输
入可防止乱码
_element_by_id(
(1)
#----------
操作
一:进行对关键字
MrLevo520
CSDN
搜索
----------------
_element_by_id(
执行此
操
作会进行搜
索,但是没有弹出新窗口,所以句柄不用重定位
(3)
#----------
操作二:对搜索页面
我的
C
SDN
进行点击操作
--------------
_element_by_xpath(
进
行当
前页面点击第一项
#------
--
操作三:对新弹出的页面再点击
贡
献的资源
选项
-----
_to_window(_handles[1])
_ele
ment_by_xpath(
3]
(5)
最后结果,按照我的思路,进行了相应的点击,最后如图
所以从
上述的例子上来说,语句
sreach_window=t_window_handl
e
并没有实现重定位,
可能我才
疏学浅
,但至少,在上述的那位大哥的博客中,写的是错误的,运行失败,我对
2016.7.
16
的所有数据负责,实际测试失败。
7.17-
补充:另一种获取句柄方法
还有另一种方法,就是直接定位当
前最新弹出的窗口。代码是这样的
for handle
in _handles:#
方法二,始终获得当前最后的窗口,
所以多要多次使用
_to_window(handle)
那么结合到我的代码中那就是这样的:
#Author
:哈士奇说喵
#
因为搜索引擎检索项根据热度来排名,
所以
我只能对
7.17
的数据进行测试和负
责,大家测试时候注意元素变化
#coding=utf-8
from selenium import webdriver
import time
browser=x()
(
keywords = 'MrLevo520 CSDN'
send_keywords=('utf-8')#
中英混输
入可防止乱码
_element_by_id(
(1)
#----------
操作
一:进行对关键字
MrLevo520
CSDN
搜索
----------------
_element_by_id(
执行此
操
作会进行搜
索,但是没有弹出新窗口,所以句柄不用重定位
(3)
#----------
操作二:对搜索页面第一项进行点击操作
-------------- <
/p>
_element_by_xpath(
进
行当前页面点击第一项
#---
-----
操作三:对新弹出的页面再点击
我的头像
选项
-----
#
注意此时已经是弹出的第一个窗口了,需要重新定位句柄
'''_to_window(_handles[1])#
方法一
'''
for handle in
_handles:#
方法二,始终获得当前最后的窗口
_to_window(handle)
_element_by_xpath(
/div/a
< br>
#------------------
操作四:点
击
贡献的资源
#
注意此时已经是新弹出的第二个窗口了,需要重新定位句柄
_to_window(_handles[2])#
方
法
一
,
注
意
window_handles[2]
变成了<
/p>
2
'''for handle in _handles:#
方法二,始终获得当前最后的窗
口
_to_window(handle)'''
<
/p>
_element_by_xpath(
3]
(5)
< br>上面的代码,
我要说几点,
总共实现完成会存在三个浏览
器窗口,
也就是相
当于实现了两次句柄重定位功能,
也就是下面的图片,
对
bing
< br>搜索
“
MrLevo520
C
SDN
”
跳出的最热项,
也就是这一篇
(
感谢大家厚爱
)
,
但是昨天最热弹出来的是
直接是我的主页,
大家从上面的动图应该也可以看出来,
所以等你测试这段代码
的时候,可能最热项目又变化了,道理大家懂就
ok
,
不影响重抓句柄代码。
代码实现了从
1
,到
2
,点击头像后,再跳转到
3
主页,之后再点击
贡献资
源
,实现的动图如下:
Pay
Attention
1.
搜索引擎根据热度来排名,
也就是代码具有
<
/p>
不稳定性
,
应该
根据自己实
际情况,定位不同元素,我只对当前编辑时间的数据负责
2.
在实际操作过程中,
会产生第一个页面还没等第二个页面缓冲完,
直接又
占领
主视觉的问题,别担心,句柄还是在传递的,程序一直在跑,而且没有出
错,
过一会时间就会更新加载页面的,
如果想要关闭无关页面,
请看这篇博客
基
于
Selenium
一键写
CSDN
博客
3.
可能我的代码第一次获取句柄和第二次获取句柄不一样的方法,
这是为了
展示,
你可以两次句柄获取都用方法二
,
也可以都是用方法一,
但是方法一注意
修改标号。
方法一
VS
方法二
相比较于方法二,
方法一的优点在于后续操作,
比如关闭第几个窗口,
句柄
传递是按照顺序来的。
p>
缺点在于对于较多新页面,
有时候弹出窗口太多会变得难
以计算。
而方法二,
一直在获取最后的窗口,
如果你只是
对最后的窗口进行操作,
也
就是
(
p>
自己定义的
)
”
前
向
“操作时,
不计后果,
可以直接拿来
用,
而且代码不变。
缺点在于,
如果要
返回到某个窗口句柄,
那就显得没有方法一来的好,
至少我现<
/p>
在是这么认为的,可能以后我会回来修改。
总结
我姑且认为这句语句,单独作用于上述博客中是不可行的。
所以我在后续的博客中对窗口重定
向语句改成了
_to_window(_handles[1])
,
至少在我的实验中,
这句语句实现了我需要的操作。
最后上张动图表示流程:
最后
将待解决实际问题解决,方法总是
好多种,就看自己想不想解决。