目录
前言
selenium比requests更加成熟,能够模拟人的操作获取网页,爬取浏览器加载后的页面源代码,利用“检查”可以对页面元素直接进行操作,比requests更加直观。
selenium是第三方的库,而且期间也需要用到相应的浏览器驱动,相关selenium的安装和浏览器驱动安装网上都有教程。
一、使用步骤
1.引入库和创建对象
代码如下(示例):
from selenium.webdriver import Chrome
web = Chrome()
web.get('https://www.baidu.com')
这就是访问了百度搜索的页面。会自动弹出浏览器访问百度。之后几乎所有的操作都将围绕web这个变量展开。
2.查找元素
自我感觉唯有xpath的查找能够准确无误,其他都不太行。更新的3.10版本废除了原先的查找方法,我们需要引进By来进行查询:find_element(By.xpath,'xpath地址')。
例如我们需要访问bilibili并点击“热门”这个标签。那么我们右键查找或者f12利用左上角的检查来获取xpath,然后利用xpath来进行解析。
from selenium.webdriver.common.by import By
web.find_element(By.XPATH, '//*[@id="i_cecream"]/div[1]/div[3]/div[2]/div[1]/a[1]').click()
还有其他解析的方法比如id什么的感觉用处不大,可以看:
https://zhuanlan.zhihu.com/p/36268930
与之相对应的还有:
find_elements,主要是来寻找相同下面xpath下的一组的数据,原理和单数类似。
注意 :
关于xpath定位不到的问题:
1. 设置休眠等待时间,可能是未加载完毕就爬取,导致找不到信息或者错误的乱码的信息。
2. 多表单切换:
在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位。这时就需要通过switch_to.frame()方法将当前定位的主体切换为frame/iframe表单的内嵌页面中。
<html>
<body>
...
<iframe id="x-URS-iframe" ...>
<html>
<body>
...
<input name="email" >
126邮箱登录框的结构大概是这样子的,想要操作登录框必须要先切换到iframe表单。
switch_to.frame() 默认可以直接取表单的id 或name属性。如果iframe没有可用的id和name属性,则可以通过下面的方式进行定位。
……
#先通过xpth定位到iframe
xf = driver.find_element_by_xpath('//*[@id="x-URS-iframe"]')
#再将定位对象传给switch_to.frame()方法
driver.switch_to.frame(xf)
……
#driver.switch_to.parent_frame() #这个语句是用来切换到上一层的iframe,一般不用
#可以有iframe的name信息的
web.switch_to.frame('zzj_top_6s') #zzj_top_6s就是它的name
3. key、鼠标事件和键盘事件
3.1 keys方法
from selenium.webdriver.common.keys import Keys
cl = web.find_element(By.XPATH, '//*[@id="nav-searchform"]/div[1]/input')
cl.send_keys('python')
cl.send_keys(Keys.ENTER)
方法 | 说明 |
---|---|
click() | 单击元素 |
send_keys (value) | 模拟按键输入 |
text | 获取元素的文本 |
submit() | 用于提交表单 |
3.2 鼠标事件
方法 | 说明 |
---|---|
ActionChains(driver) | 构造ActionChains对象 |
move_to_element(above) | 停在某个元素上面 |
double_click() | 双击 |
drag_and_drop() | 拖动 |
move_by_offset(xoffset, yoffset) | 鼠标从当前位置移动到某个坐标 |
context_click | 右击 |
perform() | 执行所有 ActionChains 中存储的行为,可以理解成是对整个操作的提交动作 |
from selenium.webdriver.common.action_chains import ActionChains
cl = web.find_element(By.XPATH, '//*[@id="i_cecream"]/div[1]/div[3]/div[2]/div[1]/a[1]')
actions = ActionChains(web)
actions.context_click(cl)
actions.perform()
3.3 键盘事件
按键 | 说明 |
send_keys(Keys.BACK_SPACE) | 删除键(BackSpace) |
send_keys(Keys.SPACE) | 空格键(Space) |
send_keys(Keys.TAB) | 制表键(Tab) |
send_keys(Keys.ESCAPE) | 回退键(Esc) |
send_keys(Keys.ENTER) | 回车键(Enter) |
send_keys(Keys.CONTROL,‘a’) | 全选(Ctrl+A) |
send_keys(Keys.CONTROL,‘c’) | 复制(Ctrl+C) |
send_keys(Keys.CONTROL,‘x’) | 剪切(Ctrl+X) |
send_keys(Keys.CONTROL,‘v’) | 粘贴(Ctrl+V) |
send_keys(Keys.F1…Fn) | 键盘 F1…Fn |
和上面的鼠标事件一样,就是这个函数名字不同。
3.4 获取断言信息
属性 | 说明 |
---|---|
title | 用于获得当前页面的标题 |
current_url | 用户获得当前页面的URL |
text | 获取搜索条目的文本信息 |
4. 多窗口切换
在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作。WebDriver提供了switch_to.window()方法,可以实现在不同的窗口之间切换。
web.switch_to.window(web.window_handles[-1])
5.下拉框处理
需要用到select。
from selenium.webdriver.support.select import Select
sel = Select(web.find_element_by_xpath('//*[@id="OptionDate"]'))#找到下拉框的位置
for i in range(len(sel.options)):
sel.select_by_index(i) # 按照索引位置切换
time.sleep(1)
table = web.find_element_by_xpath('//*[@id="TableList"]/table')#每一页的值
之后可以对每一个table的数据进行提取。
6.窗口截图
如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因。WebDriver提供了截图函数get_screenshot_as_file()来截取当前窗口。
web.find_element_by_id('kw').send_keys('selenium')
web.find_element_by_id('su').click()
sleep(2)
#1.截取当前窗口,并指定截图图片的保存位置
web.get_screenshot_as_file("D:\\baidu_img.jpg")
7. 反反爬
加上如下参数,可以做到一点点小小的反爬。
option = Options()
option.add_argument('--disable-blink-features=AutomationControlled')
web = Chrome(options=option)