背景介绍
Selenium 4是一个流行的网页自动化测试工具,为测试人员和开发人员提供了一系列强大的功能来模拟用户在网页上的操作。这个版本相较之前版本语法上发生了一系列变化 引入了一些新特性和改进,比如改进的WebDriver接口、新增的终端日志记录功能、更好的网络性能分析工具等。Selenium 也常被用于网页数据爬取。它与其他爬虫工具相比具有一些独特的优势和缺点。下面将分别对其优势和缺点进行概述:
整个Selenium的发展史可以用下图概括:
Selenium的优势:
- 模拟真实用户操作:Selenium能够模拟真实的用户行为,如点击、滚动、填表和其他浏览器操作,这使得它能够与动态网页交互,执行需要JavaScript加载的内容。
- 支持多种浏览器和语言:Selenium支持多种主流浏览器,包括Chrome、Firefox、IE等,并且支持多种编程语言,如Python、Java、C#等,这提供了极大的灵活性。
- 社区和文档支持强:作为一个成熟的项目,Selenium拥有广泛的社区和丰富的文档资源,便于学习和解决问题。
- 强大的元素定位功能:Selenium提供了多种元素定位方法,如id、xpath、css选择器等,使得用户可以准确快速地定位到页面元素。
- 集成方便:Selenium可以很容易地与其他测试框架和工具集成,如TestNG、JUnit等,便于自动化测试流程。
缺点:
- 性能问题:Selenium通过驱动浏览器进行操作,相比直接发起HTTP请求的爬虫工具来说,执行效率较低,消耗资源较多。
- 学习曲线:对于新手来说,Selenium的学习曲线可能相对较陡,需要花费一定的时间来掌握。
- 维护成本:自动化脚本可能因为网页更新或浏览器更新而需要定期维护,增加了长期使用的成本。
- 异步加载问题:虽然Selenium能够处理JavaScript生成的动态内容,但是对于一些复杂的异步加载内容,编写稳定有效的等待策略可能比较困难。
- 对比轻量级爬虫的局限性:相对于Scrapy等轻量级的爬虫框架,Selenium更适合于需要模拟浏览器操作的场景,而不是大规模数据抓取任务。
总的来说,Selenium是一个功能强大的工具,特别适合于需要与网页进行复杂交互的情况。但是,如果你的目标是快速抓取大量数据,可能需要考虑更专门化的爬虫工具。
Selenium WebDriver
Selenium WebDriver可以在本地或远程计算机上以原生方式驱动浏览器,就好像用户在真实操作浏览器一样。WebDriver 易于上手,是一种简洁而紧密的编程接口,可以通过多种编程语言(例如Python、Java、C#、Ruby等)来调用WebDriver。支持全部主流浏览器:例如Firefox、Safari、Edge、Chrome 及Internet Explorer等,在这些浏览器中的自动化操作等同于按真实用户的方式进行交互。
WebDriver标准是W3C标准:主要的浏览器厂商(Mozilla、Google、Apple、Microsoft等)都支持WebDriver标准,将据此优化浏览器及开发控制代码(可将控制代码称为驱动程序,各个浏览器拥有自身的WebDriver驱动程序),提供更统一的原生操作支持,使自动化脚本更加稳定。
使用Selenium 通过编程语言实现浏览器的操作首先就需要安装和配置Selenium WebDriver。
Selenium WebDriver和Selenium的安装与配置
以Chrome浏览器为例,WebDriver版本要保证与Chrome版本一致,才可以通过变成语言使用不同浏览器版本的WebDriver操作浏览器。
查看Chrome浏览器版本:在Chrome浏览器中,首先在“帮助”→“关于Google Chrome”菜单中查看浏览器版本
下载Chrome浏览器对应版本的WebDriver
地址:https://chromedriver.chromium.org/
⏩step1:
⏩step2:
驱动下载完成后,建议将驱动程序的exe文件放到同一个文件夹下进行管理,可对各类浏览器的驱动程序统一存放,本例中存放路径为D:\AllBrowserDrivers。
为使用Selenium框架在编程中能够找到这些驱动,需要通过设置系统环境变量Path设置驱动程序所在位置
浏览器驱动程序的配置到此完成。
安装Selenium
> pip install selenium
安装完成后,就可以开始编写Selenium的相关代码了
Selenium的使用
下面结合官方文档来介绍Selenium的使用:
官方文档地址:https://www.selenium.dev/zh-cn/documentation/webdriver/
编写第一个Selenium程序,通过以下代码示例让大家对操作逻辑有个直观认识:
# 从selenium模块导入webdriver,以及用于定位元素的By类
from selenium import webdriver
from selenium.webdriver.common.by import By
# 创建一个Chrome浏览器实例
driver = webdriver.Chrome()
# 打开指定的URL
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
# 获取当前页面的标题
title = driver.title
# 设置隐式等待时间为0.5秒。这意味着在查找每个元素时,最多等待0.5秒
driver.implicitly_wait(0.5)
# 通过元素的name属性定位文本输入框,并将其存储在text_box变量中
text_box = driver.find_element(by=By.NAME, value="my-text")
# 通过CSS选择器定位提交按钮,并将其存储在submit_button变量中
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
# 在文本输入框中输入文本“Selenium”
text_box.send_keys("Selenium")
# 点击提交按钮
submit_button.click()
# 通过元素的ID定位消息元素,并将其存储在message变量中
message = driver.find_element(by=By.ID, value="message")
# 获取消息元素的文本内容,并将其存储在text变量中
text = message.text
# 关闭浏览器实例,结束测试
driver.quit()
创建Chrome浏览器实例配置
ChromeOptions配置
在Selenium WebDriver中,ChromeOptions是一个非常强大的工具,它允许您定制和控制Chrome浏览器的各种选项。使用ChromeOptions可以帮助您配置ChromeDriver以符合您的自动化测试或爬虫需求。以下是一些常用的ChromeOptions配置示例,说明了如何使用它们:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.proxy import Proxy, ProxyType
# 创建ChromeOptions实例来定制Chrome浏览器的启动选项
options = Options()
# 添加启动参数,使浏览器窗口最大化启动
options.add_argument("--start-maximized")
# 添加启动参数,以无头模式启动浏览器(没有图形界面)
options.add_argument("--headless")
# 禁用GPU加速,有时在无头模式下需要设置
options.add_argument("--disable-gpu")
# 设置用户数据目录,允许自定义配置,如cookies和扩展
options.add_argument("--user-data-dir=/path/to/your/custom/profile")
# 通过代理启动Chrome,设置HTTP代理
proxy = Proxy()
proxy.http_proxy = 'myhttpproxy:3337'
proxy.proxy_type = ProxyType.MANUAL
options.Proxy = proxy.to_capabilities()
# 添加Chrome扩展
options.add_extension('/path/to/extension.crx')
# 禁用弹窗阻止,对于某些自动化测试场景很有用
options.add_experimental_option("excludeSwitches", ["disable-popup-blocking"])
# 自定义下载文件夹的路径,便于管理下载的文件
prefs = {"download.default_directory": "/path/to/download/directory"}
options.add_experimental_option("prefs", prefs)
# 使用配置好的选项创建WebDriver实例,启动Chrome浏览器
driver = webdriver.Chrome(options=options)
# 在这里添加你的Selenium脚本,例如打开一个网页
driver.get("http://example.com")
# 最后,关闭浏览器
driver.quit()
🔰要查询add_argument()方法接受的全部参数,
最直接的资源是查看Chromium或Google Chrome的命令行开关文档。这些参数实际上是传递给Chrome浏览器的命令行参数,用于控制浏览器的启动方式和行为。虽然没有一个官方的、始终最新的参数列表(因为这些参数会随Chrome版本更新而变化),但以下是一些获取这些参数信息的途径:
Peter Beverloo的网站:这个网站维护了一个非常全面的Chrome命令行开关列表,虽然不是官方的,但更新频繁,几乎包含了所有当前可用的开关。
https://peter.sh/experiments/chromium-command-line-switches/
2.Service对象配置
在Selenium WebDriver中,Service
对象用于管理与浏览器驱动(如ChromeDriver)的通信。这允许更细粒度地控制驱动程序的启动和停止行为。使用Service
类,你可以指定浏览器驱动程序的路径,以及启动驱动程序时使用的各种选项和参数。
以下是如何使用Service
类来配置和启动ChromeDriver的示例:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
# 创建Service对象,并传入ChromeDriver的路径
service = ChromeService(
executable_path='/path/to/chromedriver',# 指定ChromeDriver的路径
port=0, # 或指定一个具体的端口号
service_args=['--verbose', '--log-path=/path/to/logfile'],
log_path='chromedriver.log',
env={'DISPLAY': ':1'} # 仅在需要时配置环境变量
)
# 创建ChromeOptions实例来配置Chrome浏览器选项
options = Options()
options.add_argument("--start-maximized") # 浏览器启动最大化
options.add_argument("--headless") # 无头模式运行
# 使用配置好的Service对象和ChromeOptions来启动ChromeDriver
driver = webdriver.Chrome(service=service, options=options)
# 在此处添加你的Selenium脚本,例如打开一个网页
# driver.get("http://example.com")
# 完成测试后关闭浏览器
driver.quit()
🔰Service类的一些主要配置项:
- executable_path:
- 描述:指定WebDriver可执行文件的路径。这是创建Service对象时必须提供的参数,以确保Selenium能够启动对应的浏览器驱动程序。
- 示例:executable_path=‘/path/to/chromedriver’
- port:
- 描述:指定WebDriver服务监听的端口。如果未指定,系统将随机选择一个可用端口。
- 示例:port=0 (系统选择可用端口)
- service_args:
- 描述:一个字符串列表,用于指定启动WebDriver服务时附加的命令行参数。
- 示例:service_args=[‘–log-path=/path/to/logfile’]
- log_path:
- 描述:指定WebDriver服务的日志文件路径。如果未指定,日志将输出到stderr。
- 示例:log_path=‘chromedriver.log’
- env:
- 描述:一个字典,用于指定启动WebDriver服务时的环境变量。
- 示例:env={‘DISPLAY’: ‘:1’}
反爬虫检测介绍
🔰网络爬虫检测技术的发展促使了行为检测和指纹识别这两大类方法的广泛应用。它们的目的是为了区分人类用户和自动化脚本(例如,爬虫或自动化测试工具)的访问行为。下面分别解释这两种方法:
行为检测行为检测技术侧重于分析用户在网页上的行为模式。这包括用户的鼠标移动、点击、键盘输入、滚动行为,以及页面访问速度和顺序等。行为检测的基本假设是,人类用户与自动化脚本在与网页交互时会表现出不同的行为特征。
- 优点:
- 直观:人类用户和机器在交互方式上有本质的区别。
- 动态:可以实时监测用户行为,对于动态变化的行为模式有很好的适应性。
- 缺点:
- 可被模仿:高级爬虫可以模仿人类行为,如随机移动鼠标、模拟键盘输入等。
- 用户体验影响:过度依赖行为检测可能会对真实用户的体验造成干扰。
指纹识别指纹识别技术通过分析访问者的设备和浏览器信息来识别用户。这包括操作系统、浏览器类型和版本、屏幕分辨率、字体列表、插件信息、语言设置、时区,甚至更高级的特征,如Canvas和WebGL指纹。指纹识别的核心思想是,每个用户的设备和浏览器配置组合在一起形成了一个独特的“指纹”,可以用来区分不同的用户。
- 优点:
- 难以模仿:相比行为模式,设备和浏览器的指纹更难被模仿。
- 用户无感知:指纹收集过程对用户透明,不影响用户体验。
- 缺点:
- 隐私问题:收集大量设备和浏览器信息可能涉及用户隐私。
- 变化问题:用户更换设备或更新浏览器可能导致指纹变化,影响识别准确性。
两种技术各有优缺点,且往往互补使用,以提高爬虫检测的准确性和难度。高级的爬虫检测系统可能会结合这两种技术,通过复杂的算法来分析用户行为和设备指纹,从而更准确地区分人类用户和自动化脚本。selenium虽然看上去十分强大,但是依然会被某些网站轻松检测出来,所以说我们就要对options进行一些设置来反反爬。
通过https://bot.sannysoft.com/网站可以查看自己的爬虫环境是否能通过bot测试。绿色为通过测试,我们的目的就是通过设置了,模拟用户通过浏览器进行访问的环境。
...配置略
driver = webdriver.Chrome(service=service, options=options)
# 打开爬虫测试网站 进行爬虫检测测试
driver.get("https://bot.sannysoft.com/")
红色部分即网站爬虫测试检测到我们是爬虫了
在网络爬虫开发和自动化测试中,处理网站的反爬虫机制是一个常见挑战。其中,改变用户代理(User-Agent)是避免被检测到的一种简单而有效的方法。fake-useragent
库在Python中用于生成随机且真实的用户代理字符串,这可以帮助模拟不同设备和浏览器访问网站,从而减少被识别为爬虫的风险。以下是如何将fake-useragent
库与Selenium结合使用的示例。
安装fake-useragent
首先,确保安装了fake-useragent
库。如果未安装,可以通过pip安装:
pip install fake-useragent
结合Selenium使用fake-useragent
接下来,你可以在Selenium脚本中使用fake-useragent
来设置随机的用户代理。以下是一个示例:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from fake_useragent import UserAgent
# 创建UserAgent对象,并生成随机用户代理
ua = UserAgent()
random_user_agent = ua.random
# 创建ChromeOptions对象
options = Options()
# 使用fake-useragent生成的随机用户代理
options.add_argument(f'user-agent={random_user_agent}')
# 初始化WebDriver,并应用配置的ChromeOptions
driver = webdriver.Chrome(options=options)
# 使用Selenium正常操作,例如访问网页
driver.get('https://www.example.com')
# 关闭浏览器
driver.quit()
这段代码首先使用fake-useragent
库生成一个随机的用户代理字符串。然后,通过Options
类将这个用户代理传递给Chrome浏览器实例。这样,当Selenium控制的浏览器访问网站时,它会使用这个随机生成的用户代理,而不是默认的用户代理字符串,这有助于避免被网站的反爬虫机制识别。
⚠️注意事项
- 网站更新:一些网站可能会定期更新其反爬虫策略,包括检测用户代理字符串的真实性。因此,仅仅改变用户代理并不总是足够的。
- 性能考虑:
fake-useragent
库可能会从互联网上下载最新的用户代理列表。如果在每次启动爬虫时都进行这一步骤,可能会影响性能。考虑缓存用户代理列表以改善性能。 - 法律和道德:在进行网络爬虫开发时,始终遵守目标网站的
robots.txt
规则,尊重网站的使用条款,并考虑到潜在的法律和道德问题。
在接下来的章节,我会详细介绍selenium的具体使用