Cloudflare 是如何检测无头浏览器的?
Cloudflare 是一家拥有庞大网络的科技公司。他们专注于 CDN、DNS 以及各种在线安全系统等服务。其 Web 应用防火墙通常旨在防御 DDoS 或跨站脚本攻击等威胁。近年来,Cloudflare 及其他该领域的服务商纷纷引入了指纹识别系统,能够检测无头浏览器。正如您所料,Selenium 是首批受到这些技术影响的工具之一。 鉴于网络爬虫行业高度依赖这项技术,爬虫工具也因此受到了直接影响。
在探讨反机器人技术之前,我认为有必要先讨论一下 Cloudflare 是如何检测 Selenium 的。其实,这个系统可能非常复杂。例如,浏览器中存在一些 WebDriver 所不具备的属性。浏览器的 `navigator` 接口甚至有一个名为 `webdriver` 的属性,用于指示浏览器是否被自动化程序控制。而这正是最明显的破绽。如果你想亲自尝试一下:
- 打开浏览器的开发者工具
- 转到控制台
- 输入以下命令:`navigator.webdriver`
就你的情况而言,它应该返回 `false`。但如果你用 Puppeteer 或 Selenium 尝试,结果会是 `true`。如果你想知道 Cloudflare 是如何利用这一点来检测机器人的,其实很简单。他们只需要在合作伙伴的网站上注入如下所示的脚本即可:
// detection-script.js
const webdriver = navigator.webdriver
// If webdriver returns true, display a reCaptcha
// In this example, I am transferring the user to a Cloudflare challenge page.
// But you get the idea
if ( webdriver ) location.replace('https://cloudflarechallenge.com')
当然,在现实中,这些服务商使用的检测层级远不止这些。就连屏幕尺寸、键盘布局,甚至是浏览器使用的插件,都会被用来对浏览器进行精准的指纹识别。如果你对无浏览器检测的工作原理感兴趣,可以看看我开发的这个简单的 Service Worker 测试工具。而这仅仅是针对浏览器的检测方式。 你还可以通过查看请求来源的 IP 地址来检测机器人活动。例如,如果你使用的是数据中心 IP,那么每次请求被封禁的概率都会增加。这就是为什么在构建网络爬虫时,建议使用家庭 IP 或 ISP 代理。
如何使用 Selenium 绕过 Cloudflare
幸运的是,网络爬虫社区非常活跃。正因为绕过 Cloudflare 及其他反机器人服务商的需求如此旺盛,该领域已涌现出许多开源解决方案。当编程社区通力合作时,定能成就非凡之事!展望未来,我建议我们按照以下步骤进行:
- 进行一些测试,以确认默认的 Selenium 能否绕过 Cloudflare
- 增加一些额外的规避措施,让我们的脚本更隐蔽
那么,让我们从第一步开始:
#1:默认的Selenium能否绕过Cloudflare?
我不是那种喜欢妄下结论的人。尤其是因为我们并不确切知道 Cloudflare 的系统是如何运作的。他们的代码采用了各种混淆手段,这使得逆向工程变得更加困难。正因如此,在我作为开发者的整个职业生涯中,我深知测试是理解系统运作原理的最佳途径。 那么,让我们构建一个基础的爬虫程序,看看它在受Cloudflare保护的真实目标上表现如何。
1.1. 配置环境
在 Python 中,最好将项目集中在一个目录下。因此,让我们创建一个新文件夹,打开终端窗口并切换到该目录:
# 创建一个新的虚拟环境并激活它
~ » python3 -m venv env && source env/bin/activate
# 安装依赖项
~ » python3 -m pip install selenium
# 创建一个新的 .py 文件,并在 IDE 中打开该项目
~ » touch app.py && code .
1.2. 使用 Selenium 构建一个简单的网页爬虫
既然你已经成功创建了项目,现在是时候添加一些代码了。我们这里不会构建什么复杂的东西,这个脚本仅用于测试。如果你想学习高级网页抓取技术,可以查看这篇关于 Pyppeteer 的教程 [链接]。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 将 Chrome 设置为无头模式
options = Options()
options.headless = True
# 创建一个新的 Chrome 实例并导航至目标页面
driver = webdriver.Chrome(options=options)
driver.get('https://www.snipesusa.com/')
# 等待页面加载
time.sleep(10)
# 截取页面截图
driver.get_screenshot_as_file('screenshot.png')
# 关闭浏览器
driver.quit()
现在请看这张截图。我得到的结果如下:

我认为我们可以断定这次测试失败了。目标网站由 Cloudflare 提供保护,如你所见,我们的请求被拦截了。因此,默认情况下,Selenium 无法绕过 Cloudflare。我不会深入研究并测试其他机器人检测服务商。如果你想进一步测试,以下是一些目标网站及其服务商:

#2:隐形 Selenium 能否绕过 Cloudflare?
首先,让我澄清一下术语。我所说的“隐形 Selenium”是指一种能够不被检测到并绕过 Cloudflare 的 Selenium 版本。 我这里指的并非任何具体的隐身技术。您可以通过几种方式在 Selenium 中实现规避技术。既有专门处理此功能的包,也可以使用 `execute_cdp_cmd` 直接与 Chrome API 交互。后者能提供更大的控制权,但需要更多的工作量。以下是一个示例,展示如何使用它来更改用户代理的值:
driver.execute_cdp_cmd('Emulation.setUserAgentOverride', {
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win32; x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
"platform": "Win32",
"acceptLanguage":"ro-RO"
})
但你必须通过CDP来查找那些能让你进行所有必要更改的 API。所以,目前我们先用一些包来测试一下吧。
1.1. 隐形 Selenium
至少有两个包可用于让 Selenium 隐身运行。但截至目前,尚无任何一个包能保证绕过 Cloudflare。因此,我们仍需进行测试,以验证它们是否有效。 首先,让我们来看看 `selenium-stealth`。该包是 `puppeteer-extra-plugin-stealth` 的封装,使得在 Python 的 Selenium 中也能使用 Puppeteer 的规避功能。要使用它,你需要先进行安装。打开终端窗口并输入以下命令:
# 安装 selenium-stealth
~ » python3 -m pip install selenium-stealth
现在一切就绪。我们可以利用它让之前的爬虫工具更隐蔽:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium_stealth import stealth
import time
# 将 Chrome 设置为无头模式
options = Options()
options.headless = True
# 创建一个新的 Chrome 实例
driver = webdriver.Chrome(options=options)
# 对 WebDriver 应用隐身设置
stealth(driver,
languages=["en-US", "en"],
vendor="Google Inc.",
platform="Win32",
webgl_vendor="Intel Inc.",
renderer="Intel Iris OpenGL Engine",
fix_hairline=True,
)
# 导航至目标页面
driver.get('https://www.snipesusa.com/')
# 等待页面加载
time.sleep(10)
# 截取页面截图
driver.get_screenshot_as_file('stealth.png')
# 关闭浏览器
driver.quit()
这次运行脚本时,我得到的结果与默认的Selenium设置有所不同:

您可以使用的第二个选项是 `undetected_chromedriver`。该选项被描述为“经过优化的 Selenium Chromedriver”。让我们来试一试:
# 安装 undetected_chromedriver
~ » python3 -m pip install undetected_chromedriver
该代码与我们的默认脚本非常相似。主要区别在于包名。以下是一个使用 `undetected_chromedriver` 的基本爬虫,让我们看看它能否绕过 Cloudflare:
import undetected_chromedriver as uc
import time
# 将 Chrome 设置为无头模式
options = uc.ChromeOptions()
options.headless = True
# 创建一个新的 Chrome 实例并最大化窗口
driver = uc.Chrome(options=options, executable_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome')
driver.maximize_window()
# 导航至目标页面
driver.get('https://www.snipesusa.com/')
# 等待页面加载
time.sleep(10)
# 截取页面截图
driver.get_screenshot_as_file('stealth-uc.png')
# 关闭浏览器
driver.quit()
然而,运行脚本的结果对我来说依然很顺利。看来至少这两个软件包能够成功绕过 Cloudflare 的防护。至少在短期内是这样。说实话,如果你频繁使用这些脚本,Cloudflare 很可能会追踪到你的 IP 地址并将其封禁。因此,让我向你介绍第三种方案:网络爬虫 API。
1.2. Selenium 与 Web Scraping API
Web Scraping API 拥有一个名为“代理模式”的强大功能。您可以在此处了解更多相关信息。但我想特别指出的是,我们的代理模式可以与 Selenium 成功集成。这样,您就能使用我们已实现的所有规避功能。此外,我要告诉您,我们有一支专门的团队致力于开发定制化的规避技术。 从技术层面来说,我们处理 IP 轮换,使用多种代理,破解验证码,并利用 Chrome 的 API 持续更改我们的指纹。通俗来说,这意味着您将省去不少麻烦,并获得更高的成功率。您基本上将获得目前最隐蔽的 Selenium 版本。具体实现方法如下:
# 安装 selenium-wire
~ » python3 -m pip install selenium-wire
我们正在使用 `selenium-wire` 来通过代理运行 Selenium。以下是脚本:
from seleniumwire import webdriver
import time
# Method to encode parameters
def get_params(object):
params = ''
for key,value in object.items():
if list(object).index(key) < len(object) - 1:
params += f"{key}={value}."
else:
params += f"{key}={value}"
return params
# Your WSA API key
API_KEY = '<YOUR_API_KEY>'
# Default proxy mode parameters
PARAMETERS = {
"proxy_type":"datacenter",
"device":"desktop",
"render_js":1
}
# Set Selenium to use a proxy
options = {
'proxy': {
"http": f"http://webscrapingapi.{ get_params(PARAMETERS) }:{ API_KEY }@proxy.webscrapingapi.com:80",
}
}
# Create a new Chrome instance
driver = webdriver.Chrome(seleniumwire_options=options)
# Navigate to target
driver.get('https://www.httpbin.org/get')
# Retrieve the HTML documeent from the page
html = driver.page_source
print(html)
# Close browser
driver.quit()
如果你运行这个脚本几次,就会发现 IP 地址每次都会发生变化。这就是我们的 IP 轮换系统。在后台,它还会自动应用一些规避技术。你甚至无需为此操心。我们会处理 Cloudflare 的绕过问题,这样你就可以更专注于数据解析。
结论
如果你想开发一个能够绕过 Cloudflare 的爬虫,就必须考虑诸多因素。即使由一支专职团队全天候运作,也无法保证规避措施每次都能奏效。这是因为,随着每个浏览器版本的发布,API 都有可能新增功能。而其中一些功能可能会被用于识别和检测机器人。
我甚至要说,要绕过 Cloudflare 和其他服务商,最好的浏览器就是你自己搭建的那个。我们在 Web Scraping API 搭建了一个,现在与大家分享。祝您刮取愉快!




