如何使用FlareSolverr抓取Cloudflare站点
Cloudflare 是一种流行的网络安全服务,可保护许多网站免受不需要的流量的侵害,例如 DDoS 攻击。其先进的反机器人系统分析传入的请求并使用不断发展的算法来检测和阻止机器人。这就是您的网络抓取工具出现“访问被拒绝”错误的原因。
幸运的是,您将在本文中学习如何 使用 FlareSolverr绕过 Cloudflare 。
什么是 FlareSolverr
FlareSolverr 是一个开源代理服务器,旨在绕过 Cloudflare 的反机器人机制。它模拟可以解决挑战、通过安全检查和呈现网站内容的实际浏览器。
通常,当您访问受 Cloudflare 保护的网站时,它会让您在等候室中解决大量指纹识别挑战、验证码或其他证明您是人类的测试。FlareSolverr 使用Python Selenium和Undetected ChromeDriver自动执行绕过过程 ,以模仿实际的浏览器并像人一样行事。
解决挑战后,HTML 代码和 cookie 返回给客户端,供其他 HTTP 客户端使用,例如 Python Requests。
如何使用 FlareSolverr
FlareSolverr 的安装是独一无二的,因为您可以采用不同的方式进行安装。我们将通过分步说明使其变得简单。
但在此之前,让我们尝试访问一个没有 FlareSolverr 的网站。对于此示例,我们将使用 NowSecure,这是一个测试网站,如果您成功应对挑战,它会显示“您已通过”消息。
接下来,请确保您已安装Python,然后使用以下命令安装 Requests:
pip install requests
现在,让我们导入 Requests 模块,定义我们的目标 URL,并使用该方法向 NowSecurerequests.get()
发出请求。GET
import requests url = "https://nowsecure.nl/" response = requests.get(url)
您可以通过打印响应状态代码及其 HTML 来验证它是否有效:
print("status_code: " + str(response.status_code)) # prints the response status code print(response.text) # prints the response content as text
这是你会得到的回应:
status_code: 403 <body class="no-js"> <div class="main-wrapper" role="main"> <div class="main-content"> <noscript> <div id="challenge-error-title"> <div class="h2"> <span class="icon-wrapper"> <div class="heading-icon warning-icon"></div> </span> <span id="challenge-error-text"> Enable JavaScript and cookies to continue </span> </div> </div>
错误代码403
表示请求未经授权,HTML 是 Cloudflare 的挑战页面。简而言之,我们已被发现并被阻止。
幸运的是,我们有 FlareSolverr!接下来我们一起看看吧。
安装 FlareSolverr
设置 FlareSolverr 最流行的方法是通过 Docker 容器,因为 Chromium 浏览器包含在图像中。但是,您也可以为此配置 Prowlarr 和 Jackett。
对于本教程,我们将使用 Docker 容器。
首先,通过从以下链接之一下载安装 Docker:
运行安装包并按照说明进行操作。安装完成后,您可能需要重新启动计算机。
要检查 Docker 是否安装正确,请在终端中输入以下命令提示符:
docker
你应该得到类似这样的东西:
否则,如果安装不正确,您将收到一条错误消息。
在 Ubuntu 等 Linux 系统上,您可以运行以下命令来获取 Docker 服务的状态。
systemctl status docker
其次,通过双击 Docker Desktop 图标启动 Docker 引擎,您就可以准备集成 FlareSolverr。您可能需要在 Windows 中更新或安装适用于 Linux 的 Windows 子系统 (WSL)。
接下来,通过在终端或命令提示符中运行以下命令,从Docker 中心下载 FlareSolverr :
docker pull flaresolverr/flaresolverr
如果操作正确,您应该会在 Docker 桌面的选项卡中看到 FlareSolverr 图像'images'
。
最后,使用以下命令为 FlareSolverr 创建一个新容器,使其作为系统上的独立服务运行:
docker create --name=flaresolverr -p 8191:8191 -v /path/to/flaresolverr/config:/app/config flaresolverr/flaresolverr
替换/path/to/flaresolverr/config
为您要存储 FlareSolverr 配置文件的目录的实际路径。
上面的命令使用flareSolverr/flareSolverr
图像创建一个名为“flareSolverr”的 Docker 容器。它将容器中的端口映射8191
到本地计算机中的相同端口,以允许您从外部访问容器内运行的服务。最后,它使用该选项将卷从主机挂载到容器'-v'
。
虽然 FlareSolverr Github 存储库没有明确提及 API 端点 URL,但在大多数情况下都是默认值,如GitHub cURL 示例http://localhost:8191/v1
所示。请记住此 URL,因为我们将使用它向 FlareSolverr 发出请求,使其能够处理 Cloudflare 挑战并授予我们访问网站内容的权限。
但是,如果 FlareSolverr 容器在不同的主机或端口上运行,则 URL 将不同于默认值。您可以检查容器以查看其主机和端口。
运行 FlareSolverr
要运行 FlareSolverr,请使用以下命令启动容器,并替换[container_name]
为容器的实际名称。
docker start [container_name]
为确认您正在正确运行 Flaresolverr,请http://localhost:8191/
在您的网络浏览器上访问,您应该会得到类似这样的响应:
{ "msg": "FlareSolverr is ready!", "version": "3.1.2", "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36" }
用 FlareSolverr 抓取
如果 FlareSolverr 运行正常,您可以轻松地将要抓取的 URL 发送到其 HTTP 服务器,然后期望返回 Web 内容和 cookie。
因此,要使用 FlareSolverr 进行抓取,我们需要一个可以轻松发出 HTTP 请求的工具。由于 Python Requests 库是发出请求的事实标准,我们将使用它。
接下来,创建一个 Python 文件,导入 Requests,定义 FlareSolverr API URL,并指定内容类型,如下所示:
import requests api_url = "http://localhost:8191/v1" headers = {"Content-Type": "application/json"}
接下来,定义要在请求中发送的有效负载。在这种情况下,它应该包含 HTTP 方法、我们要抓取的 URL 和最大超时时间。我们将再次使用NowSecure作为目标 URL,这是一个受 Cloudflare 保护的测试网站。
data = { "cmd": "request.get", "url": "https://nowsecure.nl/", "maxTimeout": 60000 }
然后,POST
向 FlareSolverr API 发送请求,传递必要的参数。
response = requests.post(api_url, headers=headers, json=data)
最后,验证它是否有效:
print(response.content)
将它们放在一起,您应该具有以下完整的 Python 代码。
import requests api_url = "http://localhost:8191/v1" headers = {"Content-Type": "application/json"} data = { "cmd": "request.get", "url": "https://nowsecure.nl/", "maxTimeout": 60000 } response = requests.post(api_url, headers=headers, json=data) print(response.content)
您的回复应包含如下值:
{ "status": "ok", "message": "Challenge solved!", "solution": {"url": "https://nowsecure.nl/", "status": 200, "cookies": [{ "domain": "nowsecure.nl", "expiry": 1681830200, "httpOnly": false, "name": "cf_chl_rc_m", "path": "/", "sameSite": "Lax", "secure": false, "value": "1"}], "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", "headers": {}, "response": "<html lang="en"><head>n <!-- Required meta tags -->n <meta charset="utf-8">n ......// ..... <h1>OH YEAH, you passed!</h1>n <p class="lead">you passed!</p> .....//...", }
下面是实际的终端结果。以上回复为美化版。
带有 FlareSolverr 的 Cookie
请记住,FlareSolverr 还会在解决挑战后返回 Cloudflare cookie。我们可以通过我们的 HTTP 客户端(Python 请求)检索和使用它们,如果您发出大量请求,这会更有效率。您可以为不同的请求检索一次 cookie,而不是每次都使用繁重的 Selenium 和 Undetected ChromeDriver。
要通过 FlareSolverr 和 Requests 检索和使用 Cloudflare cookie,首先要POST
像我们之前所做的那样向 FlareSolverr 发出请求。但也导入 JSON 并在 ‘ 范围之外定义目标 URL data
。
import requests import json url = "https://nowsecure.nl/" api_url = "http://localhost:8191/v1" headers = {"Content-Type": "application/json"} data = { "cmd": "request.get", "url": url, "maxTimeout": 60000 } response = requests.post(api_url, headers=headers, json=data)
提取并清理 cookie,然后提取 FlareSolverr 用于访问目标 URL 的 User Agent。
# retrieve the entire JSON response from FlareSolverr response_data = json.loads(response.content) # Extract the cookies from the FlareSolverr response cookies = response_data["solution"]["cookies"] # Clean the cookies cookies = {cookie["name"]: cookie["value"] for cookie in cookies} # Extract the user agent from the FlareSolverr response user_agent = response_data["solution"]["userAgent"]
上面的代码在提取 cookie 和用户代理之前检索 JSON 响应。它还通过将 cookie 解析为仅包含 cookie 值的字典来清理 cookie。
GET
最后,使用清理后的 cookie 和 FlareSolverr 的用户代理向目标 URL发出新请求。
response = requests.get(url, cookies=cookies, headers={"User-Agent": user_agent})
当你把所有东西放在一起时,你的完整代码应该是这样的:
import requests import json url = "https://nowsecure.nl/" api_url = "http://localhost:8191/v1" headers = {"Content-Type": "application/json"} data = { "cmd": "request.get", "url": url, "maxTimeout": 60000 } response = requests.post(api_url, headers=headers, json=data) # retrieve the entire JSON response from FlareSolverr response_data = json.loads(response.content) # Extract the cookies from the FlareSolverr response cookies = response_data["solution"]["cookies"] # Clean the cookies cookies = {cookie["name"]: cookie["value"] for cookie in cookies} # Extract the user agent from the FlareSolverr response user_agent = response_data["solution"]["userAgent"] response = requests.get(url, cookies=cookies, headers={"User-Agent": user_agent})
通过打印结果来验证它是否有效:
print(response.content)
你应该得到类似于这样的结果:
管理会话
会话是与 FlareSolverr 的持久连接,允许您保留 Cloudflare cookie,直到您完成它们。这样,您就不必在每次请求时不断地解决挑战或向浏览器发送 cookie。
查看会话部分以获取有关创建、列出和销毁会话的详细说明。
发出 POST 请求
如果您正在尝试解决要求您提交包含POST
数据的表单的挑战,则您需要提出请求POST
。使用 FlareSolverr,这类似于请求GET
。您只需要在部分中替换request.get
为并包含参数。request.post
cmd
postData
这是一个例子:
import requests api_url = 'http://localhost:8191/v1' headers = {'Content-Type': 'application/json'} data = { "cmd": "request.post", "url":"https://www.example.com/POST", "postData": POST_DATA, "maxTimeout": 60000 } response = requests.post(api_url, headers=headers, json=data) print(response.data)
postData
必须是带有 的字符串application/x-www-form-urlencoded
,例如a=b&c=d
.
常见错误
在使用 FlareSolverr 时,用户经常会遇到一些令人沮丧的错误。让我们看看最常见的问题以及如何修复它们!
Flaresolverr 提供的 Cookie 无效
当 FlareSolverr 返回的 cookie 不起作用时会发生此错误。如果 Docker 和 FlareSolverr 的 IP 不同导致 cookie 不匹配,就会发生这种情况。换句话说:当它们在不同的网络上运行时。
使用代理或 VPN 时经常出现这种情况,因为 FlareSolverr 目前不支持它们。要解决此问题,请尝试禁用代理或 VPN。如果那不可能,请参阅此问题。
检测到挑战但未配置 Flaresolverr
此错误在 Jackett 中很常见,其中 Cloudflare 保护了一些索引器。要解决它,请安装FlareSolverr 服务并配置 FlareSolverr API URL。
FlareSolverr 的局限性和解决方案
虽然 FlareSolverr 是绕过 Cloudflare 挑战的绝佳工具,但它是开源的。此类解决方案很少跟上 Cloudflare 频繁发展的机器人管理系统的步伐,下面是一个示例:
让我们针对具有更高级 Cloudflare 保护的网站(例如Glassdoor)尝试我们之前的代码。
我们的脚本如下所示:
import requests url = "http://localhost:8191/v1" headers = {"Content-Type": "application/json"} data = { "cmd": "request.get", "url": "https://www.glassdoor.com/Overview/Working-at-Google-EI_IE9079.11,17.htm", "maxTimeout": 60000 } response = requests.post(url, headers=headers, json=data) print(response.content)
我们收到以下错误消息:
b'{"status": "error", "message": "Error: Error solving the challenge. Timeout after 60.0 seconds.", "startTimestamp": 1681908319571, "endTimestamp": 1681908380332, "version": "3.1.2"}'
上面的结果证实了FlareSolverr 无法解决高级 Cloudflare 挑战。
幸运的是,不断发展的网络抓取解决方案 ZenRows 提供了一条出路。让我们看看它如何针对 Glassdoor,而 FlareSolverr 失败了。
要使用ZenRows,请注册以获取免费的 API 密钥。然后,使用以下命令安装 ZenRows SDK:
免费领取1000次ZenRows API网页爬取pip install zenrows
接下来,导入 ZenRows 客户端并使用您的 API 密钥创建一个新实例。
from zenrows import ZenRowsClient #Create a new zenrowsClient instance client = ZenRowsClient("APIKey")
指定您的目标 URL 并设置必要的参数。要绕过反机器人措施,您必须设置"antibot": "true"
,"premium_proxy": "true."
和"js_render": "true"
。
url = "https://www.glassdoor.com/Overview/Working-at-Google-EI_IE9079.11,17.htm" params = {"js_render":"true","antibot":"true","premium_proxy":"true"}
最后,GET
使用预定义参数发出请求。
response = client.get(url, params=params)
您的完整代码应如下所示,我们在其中添加了一个print
:
from zenrows import ZenRowsClient #create new zenrowsclient instance client = ZenRowsClient("Your_API_Key") url = "https://www.glassdoor.com/Overview/Working-at-Google-EI_IE9079.11,17.htm" #define the necessary parameters params = {"js_render":"true","antibot":"true","premium_proxy":"true"} #make a get request response = client.get(url, params=params) print(response.text)
绕过任何级别的 Cloudflare 保护都厉害。