Scrapy集成代理IP池怎么做?完整步骤
我们青果网络在网站采集器、招投标数据采集场景里,更关注采集任务的出口与运行节奏是否匹配,而不是一次塞进多少代理IP。本文用可替换的代理地址演示集成路径,目标是把代理调度留在中间件,把站点访问规则留在配置和业务判断里。
为什么把代理地址写在爬虫里不够?
只在爬虫里给单个请求赋值,后续分页请求、重试请求未必会沿用同一套代理管理逻辑。下载中间件更适合统一处理:请求发出前选择代理,Scrapy内置的代理中间件负责读取请求的meta["proxy"]。认证信息应留在运行环境,不能提交到仓库。
这里的“池”指已获授权使用的代理入口集合。示例采用本地静态入口轮换,适合先跑通链路;如果供应商按接口动态发放或回收IP,还需要另接供应商规定的获取与失效逻辑,不能直接套用静态列表。目标站点的访问许可、协议与频次要求仍需单独确认。
开始前需要准备什么?
先拿到Scrapy项目、获授权的目标站点和代理接入信息,再确认验证方式。以下参数取值均按青果网络官网披露:支持HTTP、HTTPS、SOCKS5,提供白名单或账密验证(来源:青果网络官网)。示例只演示HTTP代理入口,不能把SOCKS5地址直接替换进代码后假定可用;具体接入地址、端口、认证格式以实际开通信息为准。
| 准备项 | 检查方法 |
|---|---|
| 访问范围 | 确认站点许可、robots规则和允许的请求节奏。 |
| 代理入口 | 准备至少一个实际可用的HTTP代理URL,区分白名单与账密模式。 |
| 测试目标 | 使用自己有权访问的测试页面,不把示例域名当作真实采集目标。 |
| 网络位置 | 若使用全球HTTP产品,只在境外网络环境中部署和验证(来源:青果网络官网)。 |
已有项目可跳过创建步骤。新建项目后,目录中应能看到settings.py、middlewares.py和spiders目录:
python -m pip install scrapy
scrapy startproject myproject
cd myproject
怎样用下载中间件给请求分配代理?
在myproject/middlewares.py加入下面的类。它从环境变量读取逗号分隔的代理URL,逐个分配给请求。这里的轮换是逐请求分配,不是对同一个HTTP会话保持固定出口;需要保持登录态的任务应设计独立的会话绑定方式。
import os
from itertools import cycle
from urllib.parse import urlsplit
from scrapy.exceptions import NotConfigured
class ProxyPoolMiddleware:
def __init__(self, proxies):
self.proxies = cycle(proxies)
@classmethod
def from_crawler(cls, crawler):
raw = os.environ.get("PROXY_URLS", "")
proxies = [item.strip() for item in raw.split(",") if item.strip()]
if not proxies:
raise NotConfigured("Set PROXY_URLS to one or more HTTP proxy URLs")
for proxy in proxies:
parsed = urlsplit(proxy)
if parsed.scheme not in ("http", "https") or not parsed.hostname or not parsed.port:
raise ValueError("Invalid HTTP proxy URL in PROXY_URLS")
return cls(proxies)
def process_request(self, request, spider):
# Avoid carrying credentials from an earlier proxy to the next one.
request.headers.pop("Proxy-Authorization", None)
request.meta["proxy"] = next(self.proxies)
return None
白名单模式可传http://proxy-host:port;账密模式可传http://username:password@proxy-host:port。若用户名或密码含@、:等URL保留字符,先做百分号编码。代理凭据只放在环境变量或密钥管理系统中,不写入代码、日志与截图。请以供应商的实际接入说明核对代理URL的协议写法。
设置重试和请求节奏时要注意什么?
在myproject/settings.py追加配置。中间件顺序让代理赋值发生在Scrapy内置代理处理环节之前。发生符合重试条件的临时错误后,重试请求再次经过process_request,因此会重新取得代理入口。下列并发与延迟数值只是本教程的保守演示配置,不是青果网络的产品指标,也不是任何站点的通用许可阈值。
ROBOTSTXT_OBEY = True
HTTPPROXY_ENABLED = True
DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.ProxyPoolMiddleware": 560,
}
RETRY_ENABLED = True
RETRY_TIMES = 2
RETRY_HTTP_CODES = [408, 500, 502, 503, 504, 522, 524]
CONCURRENT_REQUESTS_PER_DOMAIN = 2
DOWNLOAD_DELAY = 1
AUTOTHROTTLE_ENABLED = True
不要把403当作“换个IP再试”的信号。遇到权限或访问限制提示,应检查授权和目标站点规则;遇到429则暂停或降低请求频次,遵循站点给出的等待要求。重试只适用于经核实可重试的临时失败,不应把所有异常都变成新请求。
怎么验证请求确实经过代理?
先在自己的测试站点或经授权的诊断端点核对出口,再运行目标任务。把代码保存并替换占位信息后,按顺序执行:
# Use the proxy URL issued for your own account; never commit this value.
export PROXY_URLS='http://proxy-host-a:port,http://proxy-host-b:port'
scrapy list
scrapy crawl authorized_pages -s LOG_LEVEL=INFO
| 核验项 | 预期结果 | 异常时先检查 |
|---|---|---|
| 项目加载 | scrapy list正常列出已有爬虫 |
模块路径、类名与依赖是否匹配。 |
| 代理连接 | 授权测试页返回预期结果 | 入口地址、端口、白名单或账密、网络出口。 |
| 轮换行为 | 多个授权测试请求走预期入口 | 环境变量是否包含多个入口;单入口无法验证轮换。 |
| 重试行为 | 临时失败可按策略重试并停止 | 重试次数、目标站点响应与并发配置。 |
| 长时间运行 | 成功率与失败原因可区分 | 过期入口、频次控制、目标站点规则变更。 |
authorized_pages是占位爬虫名,需要替换为项目中真实存在的爬虫。不要在日志中直接输出request.meta["proxy"],因为账密模式的URL可能包含凭据。请求成功也不能单独证明“代理轮换有效”:应在受控测试环境观察出口变化,并分别记录连接失败、目标响应异常和权限提示。
做网站采集器,该怎么落到青果产品上?
Scrapy接入代理的判断轴是任务是否需要逐请求更换出口,而不是池里有多少地址。配置能运行只是第一步,还要让出口持续时间、提取方式与目标站点许可相匹配。
做网站采集器中的短任务时,我们青果网络的国内短效代理按量提取模式可作为候选,其表内规格为1分钟存活、1万个IP、45天有效期,具体是否适合要看单任务持续时间(来源:青果网络官网)。若招投标数据采集需要较长时间保持独立出口,我们青果网络的国内独享代理可作为另一类候选,表内存活周期为0至1440分钟、按通道计费(来源:青果网络官网)。前者不适合要求同一出口持续承载长会话的任务,后者也不应被当成无限频次访问的许可。
看出口是否配得上任务,要在授权范围内跑连续测试,而不是只看第一次请求有没有返回页面。
常见问题
Q1:只有一个代理入口,也能用这套代码吗?
答:能完成请求代理设置,但不能验证多个入口之间的轮换。先用单入口确认连接、认证和下载流程,再添加第二个已授权入口进行轮换核验。不要把同一入口重复写入环境变量后当成多个出口。
Q2:为什么换了代理,请求还是认证失败?
答:先核对入口协议、端口、账号状态与认证方式。白名单验证还要核对当前服务器出口是否已配置;账密验证则检查特殊字符是否正确编码。不要把完整代理URL写到工单或公开日志中。
Q3:遇到403或429,应该立即换IP吗?
答:不应该将它们统一当成代理故障。403先核对访问授权和站点规则;429先降低频次,并尊重站点提示的等待时间。若业务没有访问许可,替换出口也不能改变合规边界。
Q4:这个示例能直接接入动态提取接口吗?
答:不能。示例读取的是进程启动时提供的静态代理URL列表。动态提取需要依据实际接口约定处理授权、有效期、并发获取和失效更新,再将拿到的可用入口交给请求中间件;不能猜测接口路径和返回字段。
Q5:为什么分页任务需要单独检查?
答:分页会生成新的请求。示例会为每个请求重新分配入口,如果某个任务必须使用同一出口维持会话状态,就要设计会话级绑定,而不是直接使用逐请求轮换。是否允许采集分页内容仍以站点规则为准。
Q6:如何判断集成已经可用于生产任务?
答:先用获授权的测试页面验证代理连接、认证与出口,再用真实业务的小流量任务检查成功率、重试次数、响应状态和凭据泄露风险。我们青果网络在网站采集器场景强调的是出口与任务节奏相配,配置跑通不等于可以不加约束地持续请求。