- 环境搭建
- 引入
- 简单使用 selenium
- 获取(定位)元素
- 元素的操作
- 模拟事件
- 窗口切换
- 处理嵌套的页面
- 处理下拉列表
- 处理滚动条
- 设置浏览器对象
- 获取页面代码
在学习爬虫时,很多网站进行加密解密操作等,搞的特别头疼。于是希望能够让浏览器对需要爬取的页面进行脚本执行等操作,我们只要爬取结果页面里的数据就可以了。基于这个需求,找到了 selenium 模块。
selenium 是一个自动化测试工具,可以运行浏览器并且像人手工一样进行操作,能够做到 RPA 的功能。程序员可以从 selenium 上直接提取网页上的各种信息。
环境搭建- 首先,使用 pip install selenium 安装 selenium 库
- 然后,因为是需要基于浏览器操作,所以要下载浏览器驱动:selenium 驱动(镜像) 或 npmmirror 中国镜像站
根据 chrome 的版本下载具体版本 - 将解压后的 chromedriver.exe 放在 python 解释器 python.exe 的文件夹(或 Script 文件夹,必须添加在环境变量 path 中)内。
也可以在通过 selenium.webdriver.Chrome() 实例化一个driver时,通过Service对象指明驱动器所在路径,例:
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.service import Service # 引入 Service 对象
import time
url = 'https://www.baidu.com'
path = Service('e:\chromedriver.exe') # 将路径实例化为一个Service对象
chrome = webdriver.Chrome(service=path) # 实例化浏览器对象,打开浏览器
chrome.get(url) # 浏览地址页面
chrome.quit() # 关闭浏览器
引入
使用 from selenium.webdriver import Chrome 可以引入 chrome 操作的库,如果浏览器不一样,可以将 Chrome 换成使用的浏览器
简单使用 selenium搭建好环境后,可以测试使用 selenium 了。
import time
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.service import Service
path = Service('D:\360极速浏览器X下载\chromedriver.exe') # 获取浏览器驱动的路径
chrome = Chrome(service=path) # 实例化浏览器对象
chrome.get('https://www.baidu.com') # 跳转到页面
chrome.maximize_window() # 窗口最大化
print(chrome.title) # 输出一下页面 title
chrome.find_element('id', 'kw').send_keys('python') # 找到 id = 'kw' 的元素,输入 'python'
chrome.find_element('id', 'su').click() # 找到 id = 'su' 的元素,点击
time.sleep(2)
chrome.close()
获取(定位)元素
使用 .find_element(by=By.ID,value=None)->WebElement 方法来定位单一元素,使用 .find_elements(by=By.ID,value=None)->list of WebElement 来定位若干元素
chrome.find_element('id', 'kw')
可以引入 By 来获取更多的定位方式 from selenium.webdriver.common.by import By ,例如:
from selenium.webdriver.common.by import By
chrome.find_element(by=By.CLASS_NAME, value='logo') # 根据 class 定位
chrome.find_element('id', 'changeCity_btn') # 根据 ID 定位,等同于 chrome.find_element(by=By.ID, value='changeCity_btn')
chrome.find_element(by=By.XPATH, value='//*[@id="changeCityBox"]') # 根据 xpath 定位
也可以使用分级的方式进行定位
chrome.find_element('id', 'changeCity_btn').find_element(by=By.TAG_NAME, value='span')
| 定位方式 | 说明 |
|---|---|
| By.ID | 按照元素 id 属性定位 |
| By.CLASS_NAME | 按照 class 属性定位 |
| By.TAG_NAME | 按照标签名称定位 |
| By.Name | 按照 name 属性定位 |
| By.XPATH | 按照XPATH语法定位 |
| By.LINK_TEXT | 按照链接(a标签)的文本属性(text)定位 |
| By.PARTIAL_LINK_TEXT | 按照链接(a标签)的部分文本属性(text)定位 |
| By.CSS_SELECtOR | 按照 CSS 选择器定位 |
需要注意的是,使用 xpath 方式定位时,按照标签内文本定位标签语法如下例:
chrome.find_element(by=By.XPATH, value='//a[contains(text(),"全国")]') # 等同于 chrome.find_element(by=By.LINK_TEXT, value='全国')元素的操作
定位获取到元素后,就可以进行一些需要的操作了,比如点击、输入文本等。
chrome.find_element(by=By.XPATH, value='//a[contains(text(),"全国")]').click() # 点击定位的元素
text = chrome.find_element(by=By.TAG_NAME, value='span').text # 获取元素的文本
chrome.find_element('id', 'kw').send_keys('python') # 输入文本
url = chrome.find_element(by=By.CLASS_NAME, value='logo').get_attribute('href') # 获取元素的属性
| 元素的方法 | 说明 |
|---|---|
| tag_name | 获取标签名称 |
| text | 获取标签文本(包含所有子元素中的文本内容) |
| click() | 点击标签 |
| submit() | 提交一个 Form |
| clear() | 如果是一个能够输入文本的元素,清空文本 |
| get_attribute(name) | 获取元素的属性,参数 name 是属性名称 |
| is_selected() | 返回元素是否被选中(checkbox) |
| is_enable() | 返回元素是否可用 |
| send_keys(*value) | 模拟输入文本,可以连续输入,例:send_keys('python',' pycharm') |
| is_displayed() | 返回元素是否可见 |
| size | 返回元素的大小(宽、高) |
| location | 返回元素的位置(x,y) |
| screenshot(filename) | 截图,保存到绝对路径的文件 filename 中(png格式) |
| screenshot_as_png | 返回二进制 png 格式的截图 |
| parent | 返回父元素 |
| id | 返回 id 属性 |
需要注意的是,使用 send_keys(*value) 模拟输入特殊按键,例如回车,需要引入类 Keys。使用 from selenium.webdriver.common.keys import Keys 。然后特殊的按键可以从 Keys 类中查找。
chrome.find_element('id', 'kw').send_keys('python', Keys.ENTER)
模拟事件
模拟事件需要引入事件链 ActionChains 类 from selenium.webdriver.common.action_chains import ActionChains。
action = ActionChains(chrome) # 绑定事件到浏览器对象 action.move_to_element_with_offset(img, x, y) # 带着偏移量移动到元素 img 的某个位置(坐标为 x,y),定义元素的左上角坐标为 0, 0 action.click() # 点击操作 action.perform() # 提交事件并执行 action.drag_and_drop_by_offset(btn, 300, 0) # 将 btn 元素拖拽到相对位置 x,y 的地方,然后释放 action.perform() # 提交事件并执行
注意使用事件时,不要手动操作,否则容易出错。
窗口切换由 selenium 新打开的窗口,在 selenium 看来是后台窗口,所以要使用的时候需要进行窗口切换。使用 chrome.switch_to.window() 来切换窗口。例如:
chrome.switch_to.window(chrome.window_handles[-1]) # 切换窗口到浏览器所有窗口的最后一个
操作完成后,可以关闭当前窗口:
chrome.close() # 关闭子窗口 chrome.switch_to.window(chrome.window_handles[0]) # 回到第一个窗口处理嵌套的页面
有些页面使用了页面嵌套,比如 iframe 标签,就必须切换 selenium 视角到 iframe ,然后才能拿到数据
iframe = chrome.find_element(by=By.XPATH, value='//*[@id="player_ifram"]') # 定位到 iframe chrome.switch_to.frame(iframe) # 切换到 iframe 框架内部 chrome.switch_to.default_content() # 切换回原页面处理下拉列表
sel_el = chrome.find_element(by=By.XPATH, value='//*[@id="OpthonDate"]') # 获取下拉列表元素(select 标签) from selenium.webdriver.support.select import Select # 引入下拉列表支持 sel = Select(sel_el) # 对元素进行包装,包装成下拉菜单 # sel.options 能够获取下拉菜单有多少个选项 for i in range(len(sel.options)): # i 是每个下拉选项的索引位置 sel.select_by_index(i) # 按照索引进行切换处理滚动条
对于滚动屏幕加载的页面,需要拉动滚动条,但是 selenium 没有直接控制滚动条的方法。还好 selenium 提供了一个操作 js 的方法: execute_script() ,能够执行 js 脚本(不同浏览器可能支持不同方式的 js 脚本,可以在开发工具的控制台进行测试)。
js = "var q=document.documentElement.scrollTop=0" # 滚动条到顶部
js = "var q=document.documentElement.scrollTop=10000" # 文档到10000的位置,就是底部
js = "window.scrollTo(0,document.body.scrollHeight)" # 滚动条按照位置拖动到底部
js = "documnet.getElementsByClassName('scroll')[0].scrollTop.10000" # 设置滚动条的位置
js = "window.scrollTo(100,400) # 滚动 100,400 个单位,可以横向滚动
chrome.execute_script(js) # 执行 js 脚本
for i in range(10):
s = chrome.find_element(by=By.CLASS_NAME, value='jspDrag') # 找到滚动条
ActionChains(chrome).drag_and_drop_by_offset(s,0,10).perform() # 拖动 s ,移动 0,10 个像素
time.sleep(2) # 休息一下
需要的是,滚动滚动条是需要时间的,所以最好添加 time.sleep() 空出滚动时间。
设置浏览器对象使用 selenium 时,是模仿手工进行操作。但是浏览器不需要在前台显示,在后台运行然后返回需要的数据就可以了。
from selenium.webdriver.chrome.options import Options # 引入设置
opt = Options() # 创建设置对象
opt.add_argument('--headless') # 无头,即后台运行
opt.add_argumnet('--disable-gpu') # 不显示
chrome = Chrome(options=opt) # 创建实例时启用设置
可用的设置参数有
| 参数 | 说明 |
|---|---|
| user-agent= | 设置请求头的 user-agent |
| –start-maximized | 最大化运行(全屏窗口) |
| –incognito | 隐身模式(无痕模式) |
| –hide-scrollbars | 隐藏滚动条 |
| –disable-javascript | 禁用 js |
| blink-settings=imagesEnabled=false | 不加载图片,提升速度 |
| –disable-blink-features=AutomationControlled | 关闭自动化控制标记(防止navigator检查) |
| –headless | 不提供可视化页面 |
| –ignore-certificate-errors | 禁用扩展插件并实现窗口最大化 |
| –disable-gpu | 禁用GPU加速 |
| –proxy-server= | 使用代理 |
可以通过 selenium 获取浏览器加载并运行 js 处理过的页面代码。
chrome.page_source # 返回经过浏览器和 js 处理过的页面代码



