本文是关于爬虫工具selenium的介绍, 包括安装和常见的使用方法, 稍作整理以备之后使用.
1. selenium 安装
selenium是一款常用的爬虫工具, 与常见的爬虫库相比, 它是直接模拟并调用浏览器直接运行, 从而可以避免很多的反爬机制, 某些程度上类似于按键精灵. 但功能更强大, 自定义性更强.
首先我们需要在python环境中安装selenium库.
1 | pip install selenium |
除了基本python依赖库, 我们还需要安装浏览器驱动, 由于我使用chrome较多, 这里选择的是chomedriver
, 其他浏览器需要寻找对应驱动.
- 首先打开chrome浏览器, 在地址栏输入
Chrome://version
, 查看浏览器对应版本号, 例如目前我的是:98.0.4758.82 (正式版本) (64 位)
. - 然后在chromedriver网址中寻找到对应版本下载并解压即可.(这是官网, 有墙)
- 最后将
chromedriver.exe
放在python环境的Scripts
文件夹中, 或项目文件夹中, 或者放在喜欢的文件夹下(不是).
ok, 然后就开始我们的学习之路吧!
2. 基本用法
导入库
1
from selenium import webdriver
初始化浏览器 若已经放入
Scripts
文件夹中, 则直接调用.1
2# 初始化选择chrome浏览器
browser = webdriver.Chrome()否则需要手动选择浏览器的路径, 相对路径或绝对路径都可以.
1
2# 初始化选择chrome浏览器
browser = webdriver.Chrome(path)这时运行会发现有一个chrome浏览器自动弹出, 若我们想要程序安静运行的时候, 就可以设置无界面, 也叫
无头浏览器
.1
2
3
4
5# 参数设置
option = webdriver.ChromeOptions()
option.add_argument("headless")
browser = webdriver.Chrome(options=option)访问网址
1
2# 访问百度
browser.get(r'https://www.baidu.com/')关闭浏览器
1
2# 关闭浏览器
browser.close()
3. 浏览器设置
浏览器大小
1
2
3
4
5# 全屏
browser.maximize_window()
# 分辨率 600*800
browser.set_window_size(600,800)浏览器刷新 同刷新键, 最好写个异常检测
1
2
3
4
5
6try:
# 刷新页面
browser.refresh()
print('刷新页面')
except Exception as e:
print('刷新失败')前进/后退
1
2
3
4# 后退
browser.back()
# 前进
browser.forward()
4. 网页基本信息
当前网页的标题等信息.
1 | # 网页标题 |
也可以直接获取网页源码, 这就可以直接使用正则表达式
、Bs4
和xpath
等工具进行解析了.
1 | print(browser.page_source) |
5. 定位页面元素
定位页面元素, 即直接寻找浏览器的中渲染后的元素, 而不是源代码, 以如下搜索框标签为例
1 | <!-- 百度页面的搜索框 --> |
按照id/name/class定位
1
2
3
4# 在百度搜索框中输入python
browser.find_element_by_id('kw').send_keys('python')
browser.find_element_by_name('wd').send_keys('python')
browser.find_element_by_class_name('s_ipt').send_keys('python')按照tag定位 但是实际上一个页面可能会存在很多个相同的tag, 这时候会使得tag指向模糊, 从而引发报错.
1
2# 在百度搜索框中输入python
browser.find_element_by_tag_name('input').send_keys('python')link定位 定位连接名称, 例如在百度左上角链接的例子中进行定位.
1
2
3
4
5
6<div id="s-top-left" class="s-top-left-new s-isindex-wrap">
<a href="http://news.baidu.com" target="_blank" class="mnav c-font-normal c-color-t">新闻</a>
<a href="https://www.hao123.com" target="_blank" class="mnav c-font-normal c-color-t">hao123</a>
<a href="http://map.baidu.com" target="_blank" class="mnav c-font-normal c-color-t">地图</a>
...
</div>直接根据链接的名称来定位.
1
2# 点击新闻链接
browser.find_element_by_link_text('新闻').click()但有时候链接名称很长, 可以使用模糊定位
partial
, 当然, 链接指向得唯一.1
2# 点击含有闻的链接
browser.find_element_by_partial_link_text('闻').click()xpath定位 以上的方法必须保证元素唯一, 当元素不唯一的时候, 就需要使用xpath来进行唯一定位了, 例如使用xpath来寻找搜索框的位置.
1
2# 在百度搜索框中输入python
browser.find_element_by_xpath("//*[@id='kw']").send_keys('python')css定位 该方法比xpath简洁且更快一些
1
2# 在百度搜索框中输入python
browser.find_element_by_css_selector('#kw').send_keys('python')定位多个元素 当然, 有时候我们就是需要多个元素, 那么就只需要使用
复数s
即可.1
2
3
4# element s
browser.find_elements_by_class_name(name)
browser.find_elements_by_id(id_)
browser.find_elements_by_name(name)
6. 获取元素信息
通常在上一步定位元素之后, 会对元素进行一些操作.
获取元素属性 例如想要获取百度logo的信息, 先定位图片元素, 再获取信息
1
2
3
4
5# 先使用上述方法获取百度logo元素
logo = browser.find_element_by_class_name('index-logo-src')
# 然后使用get_attribute来获取想要的属性信息
logo = browser.find_element_by_class_name('index-logo-src')
logo_url = logo.get_attribute('src')获取元素文本 首先直接使用class寻找热榜元素, 但是有多个元素, 所以使用复数
elements
来获得, 并使用for循环
打印. 获取文本时使用text
来获取1
2
3
4# 获取热榜
hots = browser.find_elements_by_class_name('title-content-title')
for h in hots:
print(h.text)获取其他属性 获取例如id或tag
1
2
3
4
5logo = browser.find_element_by_class_name('index-logo-src')
print(logo.id)
print(logo.location)
print(logo.tag_name)
print(logo.size)
7. 页面交互
除了直接获取页面的元素, 有时候还需要对页面进行一些操作.
输入/清除文本 例如在百度搜索框输入"冬奥会", 然后清除
1
2
3
4
5
6# 首先获取搜索框元素, 然后使用send_keys输入内容
search_bar = browser.find_element_by_id('kw')
search_bar.send_keys('冬奥会')
# 稍微等两秒, 不然就看不见了
time.sleep(2)
search_bar.clear()提交(回车) 上述内容输入后, 需要点击回车来提交, 才能得到想要的搜索信息.
这篇博文
2022年2月5日
编写时百度已经发现selenium啦, 所以需要增加一些伪装手段, 在本文最后.👉 直达反爬.1
2search_bar.send_keys('冬奥会')
search_bar.submit()点击 当我们需要进行点击操作的时候, 使用click. 例如之前的提交, 也可以找到
百度一下
这个按钮, 然后click!1
2
3# 点击热榜第一条
hots = browser.find_elements_by_class_name('title-content-title')
hots[0].click()单选和多选同理, 定位到对应元素, 然后click即可.
而偶尔也会使用右击, 那就需要新的依赖库.
1
2
3
4
5
6
7from selenium.webdriver.common.action_chains import ActionChains
hots = browser.find_elements_by_class_name('title-content-title')
# 鼠标右击
ActionChains(browser).context_click(hots[0]).perform()
# 双击
# ActionChains(browser).double_click(hots[0]).perform()双击是
double_click
, 找不到合适的例子就不提了. 这里是ActionChains
可以深入挖掘, 是定义一系列的操作一起perform
, 当然, 普通的一些操作其实也够了.悬停 我就放放不进去.
1
ActionChains(browser).move_to_element(move).perform()
下拉框选择 需要导入一个相关的库, 以访问MySQL官网, 选择下载对应操作系统为例.
1
2
3
4
5
6
7
8
9
10
11
12
13from selenium.webdriver.support.select import Select
# 访问mysql下载官网
browser.get(r'https://dev.mysql.com/downloads/mysql/')
select_os = browser.find_element_by_id('os-ga')
# 使用索引选择第三个
Select(select_os).select_by_index(3)
time.sleep(2)
# 使用value选择value="3"的
Select(select_os).select_by_value("3")
time.sleep(2)
# 使用文本值选择macOS
Select(select_os).select_by_visible_text("macOS")拖拽 多用于验证码之类的, 参考菜鸟小例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
import time
browser = webdriver.Chrome()
url = 'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
time.sleep(2)
browser.switch_to.frame('iframeResult')
# 开始位置
source = browser.find_element_by_css_selector("#draggable")
# 结束位置
target = browser.find_element_by_css_selector("#droppable")
# 执行元素的拖放操作
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()
# 拖拽
time.sleep(15)
# 关闭浏览器
browser.close()
8. 键盘操作
键盘的大部分操作都有相应的命令使用, 需要导入Keys
类
1 | from selenium.webdriver.common.keys import Keys |
9. 其他
延时等待 可以发现, 在上面的程序中, 有些效果需要延时等待才能够出现, 在实际中也是需要一定的延时, 一方面是为了不过于频繁访问而被认为是爬虫, 另一方面也是由于网络资源加载需要一定时间来等待.
1
2
3# 简单的就可以直接使用
time.sleep(2) # 睡眠2秒
# 还有一些 隐式等待 implicitly_wait 和显示等待 WebDriverWait等操作, 另寻截图 可以保存为base64/png/file三种
1
browser.get_screenshot_as_file('截图.png')
窗口切换 我们的程序是针对当前窗口进行工作的, 但有时候程序需要切换窗口, 那么就需要切换当前工作窗口.
1
2
3
4
5
6
7
8
9# 访问网址:百度
browser.get(r'https://www.baidu.com/')
hots = browser.find_elements_by_class_name('title-content-title')
hots[0].click() # 点击第一个热榜
time.sleep(2)
# 回到第 i 个窗口(按顺序)
browser.switch_to_window(browser.window_handles[0])
time.sleep(2)
hots[1].click() # 点击第一个热榜当然, 若页面内有iframe元素的话, 则需要切换到该iframe元素中, 可以根据其id切换, 类似的如下
1
2# 切换到子框架
browser.switch_to.frame('iframeResult')下拉进度条 有些网页的内容是随着进度条的下滑而出现的, 所以需要下拉进度条这个操作. 这个操作是使用js代码实现的, 所以我们需要让浏览器执行js代码即可, 其他js代码类似.
1
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
10. 反爬
例如上面的百度被发现了, 就需要更好的伪装我们的浏览器browser.
1 | browser = webdriver.Chrome() |
网站检测selenium的原理是:
- selenium 在开启后的浏览器加了一些变量值, 如:window.navigator.webdriver 等等.
- 像window.navigator.webdriver, 在正常的谷歌浏览器是undefined, 在selenium打开的谷歌浏览器是true. 网站就下发js代码, 检测这个变量值给网站, 网站判断这个值, 为true就是爬虫程序就封杀或需要验证码.
当然还有其他的一些手段, 以后遇到再补充.
参考
个人收获
这次回顾了selenium的使用方法, 仔细深究的话操作是很细的, 模仿真正的浏览器运行是没有问题的, 包括登录访问什么的都很简单, 还可以作为浏览器上的按键精灵来使用😂.
相比于直接获取资源的爬虫来说肯定是较慢的, 但胜于功能强大, 还是可以提高摸鱼工作效率的:+1:.