开始之前

  • Scrapy 2.13 或更新版本,下面用到的异步 start() 方法从这个版本开始提供。旧版本请把它改名为 start_requests,并去掉 async 关键字。
  • 服务页面上的 HOST、PORT、USERNAME 和 PASSWORD。
  • 一个 Scrapy 项目,或者一个用 scrapy runspider 运行的单文件爬虫。

你的连接信息

登录控制台,打开你购买的服务。服务页面上会显示该服务的主机、端口、用户名和密码。ProxyPanda 没有一个统一的固定地址,所以每次都请从那里复制。指南中的代码使用下面这些占位符,请逐一替换成你自己的值。

HOST
该服务的代理地址,按服务页面上显示的原样填写。
PORT
要连接的端口。请和主机一起复制,因为不同服务的端口可能不同。
USERNAME
你的代理登录名。它与你登录控制台所用的邮箱是分开的。
PASSWORD
请完整复制。住宅代理在控制台中选择的选项会附加在密码末尾,凭记忆手动输入的密码会丢失这些选项。

把你用来连接的 IP 地址加入服务的白名单,就可以不用用户名和密码。这时代码里只需要 HOST 和 PORT。

示例都使用 HTTP,它可以通过加密隧道访问 https 网站。SOCKS5 同样可用:住宅代理的端口两种都接受,ISP 和数据中心代理在控制台里切换协议。

步骤

  1. 在请求上设置 meta["proxy"]

    HttpProxyMiddleware 会读取每个请求的 proxy 键。URL 中带有 USERNAME:PASSWORD 时,中间件会把它们转成 Proxy-Authorization 头,不需要其他配置。

    ip_spider.py
    import scrapy
    
    PROXY = "http://USERNAME:PASSWORD@HOST:PORT"
    
    
    class IpSpider(scrapy.Spider):
        name = "ip"
    
        async def start(self):
            yield scrapy.Request("https://httpbin.org/ip", meta={"proxy": PROXY})
    
        def parse(self, response):
            yield response.json()
  2. 运行爬虫,查看出口 IP

    httpbin.org/ip 会返回它看到的地址。out.json 里的 origin 字段应该是代理 IP。

    terminal
    scrapy runspider ip_spider.py -O out.json
    cat out.json
  3. 用环境变量覆盖所有请求

    想让整个抓取都走代理又不想逐个修改 Request,可以在启动 Scrapy 前导出 https_proxy。中间件会在抓取开始时读取它。某个请求的 meta 里设置了代理时,以 meta 为准。

    terminal
    export https_proxy="http://USERNAME:PASSWORD@HOST:PORT"
    scrapy crawl your_spider

轮换 IP 与粘性 IP

Scrapy 会同时发出很多请求。住宅代理选“随机 IP”时,这些请求会从许多不同地址发出,列表页和搜索页的抓取就能分散到整个 IP 池。

登录、购物车以及任何依赖会话 Cookie 的流程,从头到尾都需要同一个地址。这类爬虫请用“粘性 IP”,或者用整个租期内保持不变的 ISP IP。

常见错误与解决办法

TunnelError: Could not open CONNECT tunnel with proxy ... {'status': 407}

代理 URL 中的凭据被拒绝。从服务页面重新复制 USERNAME 和 PASSWORD,并对其中的 @、: 等字符做百分号编码。

IP 回显服务返回 Crawled (400),但代理连接正常

有些 IP 回显服务即使不走代理也会拒绝 Scrapy 的默认客户端。怀疑代理之前,先像上面那样用 httpbin.org/ip 测试。

并发调高后开始超时

调低 CONCURRENT_REQUESTS_PER_DOMAIN,调高 DOWNLOAD_TIMEOUT。RETRY_TIMES 可以应对偶尔较慢的住宅节点,不至于让整个抓取失败。

大量 403 或 429 响应

网站在限流或封锁你。打开 AUTOTHROTTLE_ENABLED,设置一个真实的 USER_AGENT;如果换了 IP 还是被封,就从数据中心代理换成住宅代理。

选择哪条产品线

抓取不设防的网站,用数据中心 IP 就很合适。电商平台和搜索结果这类会封服务器 IP 段的目标,用住宅代理加“随机 IP”,请求就能不断换新地址。住宅代理按 GB 计费,所以只抓需要解析的页面。

卡在某一步了?

把命令和报错贴到 Discord,记得先删掉密码。那里的人大多遇到过这些错误。

加入 Discorddiscord.gg/proxypanda
$5 起步去 Discord 问