通过代理抓取来防止禁令

有时,您可能会被正在抓取的网站阻止,因为您被识别为抓取者,有时发生这种情况是因为网站管理员看到来自统一 IP 的抓取请求,此时他们只是阻止对该 IP 的访问。 为了帮助防止此问题,可以在 Scrapy 中使用代理随机化中间件。 有一个库 scrapy-proxies,它实现了代理随机化功能。

准备工作

您可以从 GitHub 获取 scrapy-proxies: https://github.com/aivarsk/scrapy-proxies 或使用 pip install scrapy_proxies 安装它。

如何做

scrapy-proxys 的使用是通过配置完成的。 首先配置 DOWNLOADER_MIDDLEWARES,并确保安装了 RetryMiddleware、RandomProxy 和 HttpProxyMiddleware。 以下是典型配置:

# Retry many times since proxies often fail
RETRY_TIMES = 10
# Retry on most error codes since proxies fail for different reasons
RETRY_HTTP_CODES = [500, 503, 504, 400, 403, 404, 408]

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.retry.RetryMiddleware': 90,
    'scrapy_proxies.RandomProxy': 100,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
}

PROXY_LIST 设置配置为指向包含代理列表的文件:

PROXY_LIST = '/path/to/proxy/list.txt'

然后,我们需要让 Scrapy 知道 PROXY_MODE:

# Proxy mode
# 0 = Every requests have different proxy
# 1 = Take only one proxy from the list and assign it to every requests
# 2 = Put a custom proxy to use in the settings
PROXY_MODE = 0

如果 PROXY_MODE 为 2,则必须指定 CUSTOM_PROXY:

CUSTOM_PROXY = "http://host1:port"

工作原理

此配置本质上告诉 Scrapy,如果页面请求因任何 RETRY_HTTP_CODES 失败,并且每个 URL 最多 RETRY_TIMES,则使用 PROXY_LIST 指定的文件内的代理,并使用 PROXY_MODE 定义的模式。 这样,您可以让 Scrapy 故障回复到任意数量的代理服务器,以重试来自不同 IP 地址和/或端口的请求。