selenium这种模拟浏览器的操作,虽然简单,但是代码量大,非常繁琐,且在使用过程中会遇到各种坑,不像请求接口,直接发get、post包就行了!
无法定位元素
selenium在使用过程中,会有定位不到元素的情况,如果不是自己代码问题的话,可能会是下面几种原因:
参考地址:https://www.cnblogs.com/niansi/p/6666319.html
1、frame/iframe原因定位不到元素:
这个是最常见的原因,首先要理解下frame的实质,frame中实际上是嵌入了另一个页面,而selenium每次只能在一个页面识别,因此需要先定位到相应的frame,对那个页面里的元素进行定位。
解决方案:
如果iframe有name或id的话,直接使用switch_to_frame(“name值”)或switch_to_frame(“id值”)。
driver = webdriver.Chrome()
driver.get(r'http://www.126.com/')
driver.switch_to_frame('x-URS-iframe') # 需先跳转到iframe框架
username = driver.find_element_by_name('email')
username.clear()
如果iframe没有name或id的话,则可以通过下面的方式定位
# 先定位到iframe
elementi= driver.find_element_by_class_name('APP-editor-iframe')
# 再将定位对象传给switch_to_frame()方法
driver.switch_to_frame(elementi)
如果完成操作后,可以通过switch_to.parent_content()方法跳出当前iframe,或者还可以通过switch_to.default_content()方法跳回最外层的页面。
代码片段:
iframe = driver.find_element_by_xpath('//div[@id="bn_con_27316"]/iframe')
print(iframe)
driver.switch_to.frame(iframe) # iframe标签多了这一句[作用是跳到iframe上]
clicks = driver.find_elements_by_xpath('//ul[@class="rows"]//li')
print(clicks)
clicks[random.randint(0, 3)].click()
2、页面还没有加载出来,就对页面上的元素进行的操作:
一般情况说来,设置等待就行了,等待页面显示之后再操作,这与人手工操作的原理一样:
2.1 设置等待时间;缺点是需要设置较长的等待时间,页面多了测试就很慢,一般不建议使用这种强制等待
import time
time.sleep(3)
2.2 设置等待页面的某个元素出现,比如一个文本、一个输入框都可以,一旦指定的元素出现,就可以做操作:隐式等待、显示等待
2.3 在调试的过程中可以把页面的html代码打印出来,以便分析
3、二次定位 如:弹出框登录
比如 百度登录弹出框登录百度账号,需先定位到百度弹出框,然后再定位到用户名密码登录
# coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("http://www.baidu.com/")
time.sleep(3)
# 点击登录:有些name为tj_login的元素为不可见的,点击可见的那个登录按钮即可
# 否则会报:selenium.common.exceptions.ElementNotVisibleException
element0 = driver.find_elements_by_name("tj_login")
for ele0 in element0:
if ele0.is_displayed():
ele0.click()
# 在登录弹出框,需先定位到登录弹出框
# 否则会报:NoSuchElementException
element1 = driver.find_element_by_class_name("tang-content")
element11 = element1.find_element_by_id("TANGRAM__PSP_8__userName")
element11.clear()
element11.send_keys("登录名")
element2 = element1.find_element_by_id("TANGRAM__PSP_8__password")
element2.clear()
element2.send_keys("密码")
element3 = element1.find_element_by_id("TANGRAM__PSP_8__submit")
element3.click()
element3.submit()
try:
assert "登录名" in driver.page_source
except AssertionError:
print "登录失败"
else:
print "登录成功"
time.sleep(3)
finally:
print "测试记录:已测试"
driver.close()
4、不可见元素
如上百度登录代码,通过名称为tj_login查找的登录元素,有些是不可见的,所以加一个循环判断,找到可见元素(is_displayed())点击登录即可
绕过网站监测
在使用selenium的时候,经常会被网站监测到,比如会检测:window.navigator.webdriver,navigator.languages,navigator.plugins.length……
尤其是像淘宝、知乎、这种经常被爬的大网站
1、跳过js检测
解决办法可以参考下面几篇文章:
https://blog.youkuaiyun.com/Chen_chong__/article/details/82950968?tdsourcetag=s_pcqq_aiomsg
https://blog.youkuaiyun.com/Revivedsun/article/details/81785000