为什么 Scrapy 需要代理
Scrapy 的代理功能允许该工具通过不同的 IP 地址建立连接,而不是始终使用运行它的机器的 IP 地址。这对于基于位置的任务、测试、监控以及其他需要考虑连接来源的任务非常有用。
Scrapy 仍负责处理主要任务,而代理则负责管理连接的来源。

Carl Gamutan
更新于:2026年10月7日
发布于:2026年10月2日
Scrapy 是一个用于大规模爬取和提取数据的 Python 框架。以下将介绍如何将其与代理服务器连接、设置代理轮换或粘性会话,以及如何解决由此引发的错误。
Scrapy 的代理功能允许该工具通过不同的 IP 地址建立连接,而不是始终使用运行它的机器的 IP 地址。这对于基于位置的任务、测试、监控以及其他需要考虑连接来源的任务非常有用。
Scrapy 仍负责处理主要任务,而代理则负责管理连接的来源。
如果没有代理,网站会持续检测到同一个IP地址。随着访问量增加,该IP可能会触发速率限制或被封禁。
地理位置同样重要。从德国访问的页面可能与从美国访问的页面显示的内容不同。
Scrapy 代理使您能够在需要时通过不同的 IP 地址和地理位置进行连接。
合适的代理类型取决于具体任务。
| 代理类型 | 爬取 | 账户管理 | 测试 | 监控 |
|---|---|---|---|---|
| 住宅型 | 当位置和 IP 来源重要时适用 | 当账户需要住宅 IP 时有用 | 适用于基于位置的测试 | 适用于检查不同位置的内容 |
| ISP | 需要稳定 IP 时效果良好 | 适用于在单一 IP 上进行较长时间的会话 | 适合使用固定 IP 进行测试 | 适用于从同一 IP 进行持续检查 |
| 数据中心 | 适合追求速度和较大请求量 | 当不需要住宅 IP 时更佳 | 适合常规测试 | 适合频繁的自动化检查 |
当 IP 来源和位置至关重要时,住宅代理非常有用。当需要同一 IP 保持更长时间的活跃状态时,ISP 代理表现出色。当主要关注速度和规模时,数据中心代理是理想选择。
最佳选择还取决于任务是否需要地理定位、稳定的连接,或是访问更大的IP池。
Scrapy 的代理配置需要 Geonode 的主机、端口、用户名和密码。请将这些凭据保存在环境变量中,然后在代码中配置代理时加载它们。
在我们的测试中,我们添加了一个下载器中间件:
DOWNLOADER_MIDDLEWARES = {
"geonode_scrapy.middlewares.GeonodeProxyMiddleware": 350,
"scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 400,
}
该中间件通过 ``request.meta["proxy"]`
传递代理 URL,Scrapy 的 ``HttpProxyMiddleware
` 随后会使用该 URL:
request.meta["proxy"] = proxy_url
您也可以将代理直接传递给单个请求:
yield scrapy.Request(
url,
meta={"proxy": proxy_url},
)
请将实际的用户名和密码保存在环境变量中,而不是直接写在 Python 文件里。在我们的测试中,此配置成功通过代理返回了 HTTP 200 状态码。
Geonode
提供了四个参数:
proxy.geonode.io:PORT:USERNAME:PASSWORD
Scrapy 需要与代理 URL 相同的详细信息:
http://USERNAME:PASSWORD@proxy.geonode.io:PORT
将凭据或完整的代理值存储在环境变量中:
GEONODE_PROXY_URL=http://USERNAME:PASSWORD@proxy.geonode.io:PORT
然后在 Python 中加载它:
import os
proxy_url = os.environ["GEONODE_PROXY_URL"]
对于我们的 HTTP 测试,最终格式为:
http://USERNAME:PASSWORD@proxy.geonode.io:9000
为了验证身份验证,我们还使用错误的凭据发送了请求。 Scrapy 收到了 HTTP 407 状态码,响应内容为:
Authentication error. Please check your authentication settings.
Scrapy 通过 HttpErrorMiddleware
将响应呈现为 HttpError('Ignoring non-200 response')
。
如果请求无需保持相同的 IP 地址,请使用 IP 轮换。
在我们的测试中,我们将 Geonode
这个轮换代理传递给了 Scrapy:
proxy_url = "http://USERNAME:PASSWORD@proxy.geonode.io:9000"
yield scrapy.Request(
url,
meta={"proxy": proxy_url},
)
我们发起了五个连续的请求:
Request 1: 101.98.231.191
Request 2: 101.98.231.191
Request 3: 101.98.231.191
Request 4: 122.164.83.189
Request 5: 122.164.83.189
Unique IPs: 2
Rotation: Yes
测试结果证实了 IP 轮换确实发生了,但并非每次请求的 IP 都会改变。
如果相关请求需要保持在同一 IP 上,请改用粘性会话:
proxy_url = (
"http://USERNAME-session-blogtest01-lifetime-10:"
"PASSWORD@proxy.geonode.io:10000"
)
我们使用同一会话发起了三个请求:
Request 1: 177.73.202.78
Request 2: 177.73.202.78
Request 3: 177.73.202.78
Same IP: Yes
在我们的测试中,这三个请求均使用了相同的 IP。
有关可用设置,请参阅 Geonode
如果代理无法正常工作,请先检查连接信息。先核对用户名和密码,然后检查主机、端口和协议。Scrapy 返回的错误信息通常有助于缩小问题范围。
407 错误通常表明存在身份验证问题。
当我们在测试 Scrapy 时使用了错误的凭据,代理返回了以下响应:
HTTP status: 407
Authentication error. Please check your authentication settings.
请先检查用户名和密码。如果凭据正确,请确保 Scrapy 接收到的代理 URL 包含完整的协议、凭据、主机和端口信息。
连接错误通常意味着 Scrapy 无法连接到代理服务器。
请先检查主机名和端口。然后确保协议与所使用的代理服务器匹配。
Scrapy 不一定会返回类似浏览器的 ERR_TUNNEL_CONNECTION_FAILED 错误。在我们的连接失败测试中,Scrapy 重试了请求,最终返回了包含 Twisted ConnectionLost 错误的 DownloadFailedError。
超时是指请求在配置的时间内未收到响应。
首先,检查目标 URL 是否正常,以及代理是否能连接。如果两者均正常,请检查 Scrapy 中的超时配置。
在我们的连接失败测试中,我们使用了 DOWNLOAD_TIMEOUT=5
这个无效的代理端口。重试后,Scrapy 返回:
DownloadFailedError(
ConnectionLost:
Connection to the other side was lost in a non-clean fashion.
)
。因此,代理连接失败可能会表现为连接错误,而非简单的超时提示。
一个容易出现的、与Scrapy相关的错误是将不完整的值传递给request.meta["proxy"]
。
在我们的测试中,我们使用了:
proxy.geonode.io:9000
,但未包含协议或凭据。该请求返回了HTTP 407错误。
解决方法是传入完整的代理 URL:
http://USERNAME:PASSWORD@proxy.geonode.io:9000
,或者让下载器中间件根据环境变量自动生成该 URL。
Scrapy 负责处理应用程序中的请求或连接。Geonode 负责处理代理连接。
您可以根据任务需求选择家庭、ISP 或数据中心代理,并在需要时使用轮询、粘性会话和地理定位功能。这样可以将代理配置与应用程序的其他代码分离。
套餐根据代理类型而异,部分选项按 GB 计费。
常见问题解答
在我们测试的 Scrapy 版本中,SOCKS5 需要额外配置。
尝试通过 Scrapy 的默认 HTTP 处理程序使用 socks5:// 代理时,出现以下错误:
UnsupportedURLSchemeError("Unsupported scheme: b'socks5'")
随后,我们安装了 httpx2[socks] 并配置了 Scrapy 的实验性 HttpxDownloadHandler。使用端口 11000 上的 SOCKS5 轮转代理后,请求成功返回 HTTP 200 状态码并获取了代理 IP。由于该处理程序尚处于实验阶段,因此更适合用于测试,而非生产环境推荐方案。
是的,Scrapy 可以通过轮换代理发送请求,但不能保证每个请求都会使用不同的 IP 地址。
我们在五次请求的测试中获得了两个唯一的 IP 地址。前三个请求共用一个 IP 地址,而最后两个请求共用另一个 IP 地址,这证实了测试过程中确实发生了 IP 轮换。
有。Geonode 提供免费试用,因此您可以在升级到付费套餐之前,先用 Scrapy 测试该代理服务。查看当前的免费试用和套餐。
对于单个请求,可通过 request.meta["proxy"] 传递代理。
如果多个请求需要使用相同的代理配置,下载器中间件可将代理逻辑集中管理。在我们的测试中,自定义中间件在 Scrapy 的内置 HttpProxyMiddleware 处理请求之前,先设置了 request.meta["proxy"]。
请检查蜘蛛是如何生成其第一个请求的。
在我们的 Scrapy 2.19 测试中,仅定义了旧版 ``start_requests()`
方法会导致蜘蛛在未发送任何请求的情况下就启动并关闭。使用异步的 ``start()
` 方法解决了此问题:
async def start(self):
yield scrapy.Request(...)
这是我们在测试环境中记录到的行为。