Scrapy 指南 · 1 分钟阅读

如何在 Scrapy 中使用代理

Scrapy 通过三种方式中的一种将每个请求路由到代理:每个请求的元键、环境变量或轮换下载中间件。以下是每种方式的示例代码,适用于经过身份验证的 s4m 代理。

Scrapy 与代理通信的三种方式

Scrapy 默认启用一个 HttpProxyMiddleware。它从两个地方读取代理:请求的 proxy 键的 meta 字典,或者标准的 http_proxy / https_proxy 环境变量。对于整个爬虫使用固定代理,环境变量是最快的方式;对于每个请求的控制和轮换,通常通过自定义下载中间件设置 request.meta["proxy"]。

身份验证是人们常常忽视的部分。Scrapy 不 像 curl 那样从代理 URL 中读取 USER:PASS@ — 它期望一个 Proxy-Authorization 头。干净的方法是构建该头并在你的中间件中附加它。s4m 代理使用 USER:PASS 对 proxy.s4m.online 进行身份验证,HTTP 端口为 3128(这是 Scrapy 的 HTTP 代理中间件的自然适配)。对于 SOCKS5,你需要在爬虫前面加一个本地的 SOCKS 到 HTTP 桥接,但对于大多数抓取,HTTP 端点更简单。了解更多信息,请访问 proxy page,并查看其他 scraping guides。

一个旋转代理中间件

将此代码放入middlewares.py中,在settings.py中启用,每个请求从您的代理池中选择一个带有正确身份验证头的代理。

python
# middlewares.py
import base64
import random

USER, PASS, HOST = "USER", "PASS", "proxy.s4m.online"
PROXIES = [f"http://{HOST}:3128"]  # add more endpoints/ports to rotate

class S4mProxyMiddleware:
    def _auth_header(self):
        raw = f"{USER}:{PASS}".encode()
        return b"Basic " + base64.b64encode(raw)

    def process_request(self, request, spider):
        request.meta["proxy"] = random.choice(PROXIES)
        # Scrapy needs the Proxy-Authorization header explicitly:
        request.headers[b"Proxy-Authorization"] = self._auth_header()

# settings.py
DOWNLOADER_MIDDLEWARES = {
    # keep Scrapy's built-in proxy middleware after ours
    "myproject.middlewares.S4mProxyMiddleware": 350,
    "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 400,
}
CONCURRENT_REQUESTS = 8
DOWNLOAD_DELAY = 0.5
RETRY_ENABLED = True
RETRY_TIMES = 3
RETRY_HTTP_CODES = [429, 500, 502, 503, 504]

连接起来

从一个干净的项目到一个代理爬虫。

添加中间件

将 S4mProxyMiddleware 类粘贴到您项目的 middlewares.py 中,并用您的 s4m 凭据和端点替换 USER、PASS 和 HOST。

在设置中启用它

在 DOWNLOADER_MIDDLEWARES 中注册,优先级低于 Scrapy 的 HttpProxyMiddleware(数字越小优先级越高),这样在内置中间件运行之前就设置了你的代理和头部。

调整礼貌性

设置 DOWNLOAD_DELAY 和 CONCURRENT_REQUESTS 以保持在目标的速率限制之下,并启用 RETRY_HTTP_CODES 以便在 429 和 5xx 时自动重试临时阻塞。

验证出口IP

向 IP 回显端点如 https://api.ipify.org 添加第一次请求,并记录响应以确认您的爬虫确实通过代理退出。

轮换、重试和诚实

对于真实的轮换,将多个端点放入PROXIES中,并让process_request每次请求选择一个;结合Scrapy内置的重试中间件,以便在出现429或503时重新尝试新的选择。保持DOWNLOAD_DELAY为非零且并发适中——一个能够退避的爬虫比一个快速爬行的爬虫更难被阻止。

两个诚实的警告。首先,s4m代理是数据中心,而不是住宅:非常适合API、测试和适度防御的网站,但激进的反机器人系统可能会标记数据中心范围。其次,轮换并不是忽视网站规则的许可证——请阅读robots.txt及其条款。当您需要一个一致的出口以供白名单使用时,请添加一个专用个人IP,而不是轮换。在提交流量之前,使用工具检查出口和端口,并在免费代理列表上进行原型测试。

FAQ

问题,已解答

为什么Scrapy无法从代理URL中获取我的USER:PASS?

与curl不同,Scrapy的HttpProxyMiddleware不会从URL中解析凭据。您必须自己设置Proxy-Authorization头 — 从USER:PASS构建基本身份验证头,如中间件示例所示。

Scrapy可以使用SOCKS5代理吗?

通过HttpProxyMiddleware不支持原生SOCKS5,因为它是面向HTTP的。对于Scrapy,请使用3128端口上的HTTP端点,或者如果您特别需要SOCKS5,请运行本地SOCKS到HTTP的桥接。

我如何按请求轮换代理?

将多个代理端点放入列表中,并在 process_request 中选择一个,每次设置 request.meta["proxy"]。将其与 Scrapy 的重试中间件配对,以便被阻止的请求在新的选择上重试。

这些是住宅代理吗?

不。s4m代理是经过身份验证的数据中心SOCKS5和HTTP代理,按需计费。它们适合大多数抓取,尽管防御严密的目标可能会标记数据中心IP范围。

扩展您的Scrapy爬虫

在proxy.s4m.online上的经过身份验证的数据中心代理,按需计费,准备通过Scrapy中间件轮换。当目标期望一个一致的出口时,添加一个专用IP。

人们通过搜索找到此页面

此页面回答的真实搜索短语 — 链接的短语打开详细覆盖它们的页面。