介绍
Selenium是一个Web自动化测试工具,它可以根据我们的指令,让浏览器自动加载页面,获取需要的数据,也可以截屏,或者判断网站上的事件,所以它很适合帮助我们构建网络爬虫,这样的爬虫不仅能处理 JavaScrip、Cookie、headers信息,并且还能帮我们模拟真实用户的操作流程。
目录
1、环境搭建
1.1、Webdriver安装
selenium
如果需实现与浏览器的交互,必须先安装Webdriver驱动
(驱动与浏览器类型和版本要对应),我这里使用的chrome浏览器,在浏览器中访问chrome://version/
可快速查看版本信息,也可以在右上角帮助->关于Google Chrome
中查看,然后再点击下载对应驱动版本,下载下来后解压文件,将chromedriver.exe
放到Python36\Scripts
目录下即可
1.2、selenium库安装
执行命令:pip3 install selenium
1.3、效果测试
编写一段调用chrome浏览器的代码进行测试
from selenium import webdriver
# 构造浏览器
chrome = webdriver.Chrome()
# 发送请求,访问url
url = 'http://www.baidu.com'
chrome.get(url)
# 关闭浏览器
chrome.quit()
执行代码后会看到浏览器自动打开,然后再关闭,说明环境已经搭建成功。另外,还可以看到浏览器中提示“Chrome正受到自动测试软件的控制”
2、基本用法
如果我们需要实现一个百度搜索的操作应该怎样做呢?其关键步骤肯定是先输入关键字,然后点击搜索按钮发送请求。
selenium中已经帮我们定义好了这些函数,比如下例中我们输入“日历”
关键字,则通过find_element_by_id('kw').send_keys('日历')
就可以实现,它是根据id先找到输入框,然后再填充文本内容。同理find_element_by_id('su').click()
表示先根据id找到搜索按钮,然后调用点击事件发送请求。这样一来,就相当于模拟了一个真实用户的搜索操作了。
from selenium import webdriver
from time import sleep
# 构造浏览器
driver = webdriver.Chrome()
# 发送请求
url ='http://www.baidu.com'
driver.get(url)
# 找到搜索框id,并输入要搜索关键字
driver.find_element_by_id('kw').send_keys('日历')
# 找到点击按钮id,发生请求
driver.find_element_by_id('su').click()
# 睡3秒目的是防止浏览器中资源未充分加载完就返回结果
sleep(3)
# 获取源代码
html = driver.page_source
print(html)
# 关闭浏览器
driver.quit()
id可以通过浏览器控制台查找到
3、参数指定
3.1、无头浏览器模式
无头浏览器
(Headless Browser)是没有图形用户界面(GUI)的web浏览器,通常是通过编程或命令行界面来控制的。我们使用爬虫获取数据时,并不需要进行实质的浏览器操作,所以可以采用无头模式
参数设置需要通过ChromeOptions()函数
,开启无头浏览器只需设置--headless
即可
from selenium import webdriver
options = webdriver.ChromeOptions()
# 开启无头浏览器模式
options.add_argument('--headless')
# 将参数设置到浏览器
chrome = webdriver.Chrome(chrome_options=options)
chrome.get('http://www.baidu.com')
print(chrome.page_source)
chrome.quit()
3.2、设置代理
为了降低被封的风险,我们通常会使用高匿代理IP,代理格式:--proxy-server=type://ip:port'
from selenium import webdriver
options = webdriver.ChromeOptions()
# 设置高匿代理
options.add_argument('--proxy-server=http://221.226.195.229:4216')
chrome = webdriver.Chrome(chrome_options=options)
chrome.get('http://httpbin.org/get')
print(chrome.page_source)
chrome.quit()
执行结果,可以看到origin
变成了代理IP 221.226.195.229
<html><head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">{
"args": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Host": "httpbin.org",
"Proxy-Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36",
"X-Amzn-Trace-Id": "Root=1-5eeeb7f6-5d6fa697b1f25abe4437de00"
},
"origin": "221.226.195.229",
"url": "http://httpbin.org/get"
}
</pre></body></html>
4、滚动条设置
selenium并不能模拟所有真实用户的操作,比如滚动屏幕。当页面上的元素超过一屏后,selenium无法直接定位到屏幕下方的元素,这时候就需要借助JS来实现屏幕滚动,将页面拖到底部,这样才能获取到完整的页面数据。
例如我们可以使用如下方法实现浏览器屏幕滚动,先设置一个阈值
(值越大越接近底部),然后调用execute_script()
函数执行js脚本
# 滑动到页面底部
js = 'document.documentElement.scrollTop=100000'
driver.execute_script(js)
下面是一个通过滑动商品页面获取整页数据的示例(结合xpath)
from selenium import webdriver
from lxml import etree
from time import sleep
# 构建浏览器
driver = webdriver.Chrome()
# 发送请求
url = 'https://list.tmall.com/search_product.htm?spm=a221t.1710963.cat.1.51631135hpNkjj&cat=50025174&q=%e4%bc%91%e9%97%b2%e8%a3%a4'
driver.get(url)
# 滑动到页面底部
js = 'document.documentElement.scrollTop=100000'
driver.execute_script(js)
# 睡2秒防止页面未加载完毕
sleep(2)
# 获取源码并解析
html = driver.page_source
e = etree.HTML(html)
# 提取商品名称、价格
productTitles = e.xpath('//div/p[@class="productTitle"]/a/text()')
productPrices = e.xpath('//div/p[@class="productPrice"]/em/text()')
for title, price in zip(productTitles, productPrices):
print(title, ":", price)
# 打印记录数
print(len(productPrices))
# 关闭浏览器
driver.quit()
执行结果,获取到60条商品记录信息
省略....
selected思莱德夏季新款含棉纯色九分休闲裤子
: 174.50
森马夏季新款商务透气休闲裤
: 259.00
60
5、常用API
5.1、常用方法
# 截图(当前页面)
driver.save_screenshot("img.png")
# 获取当前页面Cookie
driver.get_cookies()
# 获取当前url
driver.current_url
# 关闭当前页面(如果只有一个页面,会关闭浏览器)
driver.close()
# 清空文本
element.clear()
# 操作页面前进
driver.forward()
# 操作页面后退
driver.back()
5.2、元素选取
单个元素操作 | 多个元素操作 |
---|---|
find_element_by_id | |
find_element_by_name | find_elements_by_name |
find_element_by_xpath | find_elements_by_xpath |
find_element_by_link_text | find_elements_by_link_text |
find_element_by_partial_link_text | find_elements_by_partial_link_text |
find_element_by_tag_name | find_elements_by_tag_name |
find_element_by_class_name | find_elements_by_class_name |
find_element_by_css_selector | find_elements_by_css_selector |