Skip to content
Intermediate / 2 min read

Python Requests 轮换代理:如何为网页抓取轮换 IP(以及何时 WireGuard 网关更合适)

了解如何在 Python requests 中轮换代理,以实现可靠的网页抓取,包括 SOCKS5 支持、会话处理和错误恢复。比较轮换代理与专用 WireGuard 网关,以满足稳定 IP 需求。

SOCKS5 WireGuard 网页抓取 隐私/匿名性

概述

在 Python requests 中轮换代理是一种常见方式,可将网页抓取请求分散到多个 IP 地址,从而降低被限速或封禁的几率。本教程展示如何在 Python requests 中实现代理轮换,包括 HTTP 和 SOCKS5 代理、重试逻辑和验证。它还解释了何时专用 WireGuard 网关(例如 NordLayer)比轮换代理更合适。

先决条件

  • 已安装 Python 3.8 或更高版本。
  • requests 库。
  • 对于 SOCKS5 代理,安装 requests[socks],其中包含 PySocks。
  • 来自提供商的代理服务器列表(HTTP、HTTPS 或 SOCKS5)。

Python Requests 中的代理轮换如何工作

requests 通过 proxies 参数支持代理。如果在调用 requests.get() 之前轮换代理,每个请求都可以使用不同的代理。对于 SOCKS5,scheme 为 socks5:// 或 socks5h://(通过代理解析 DNS)。

步骤

  1. 安装所需的库。
    pip install requests requests[socks]
    
  2. 准备代理列表。将凭据保存在环境变量或配置文件中,不要放在源代码里。
    import os
    proxies_list = [
        'http://user:[email protected]:8080',
        'http://user:[email protected]:8080',
        'socks5://user:[email protected]:1080',
    ]
    
  3. 选择轮换策略。最简单的方式是循环遍历列表。
    from itertools import cycle
    proxy_pool = cycle(proxies_list)
    
  4. 使用轮换代理发送请求。包含超时并处理异常。
    import requests
    url = 'https://httpbin.org/ip'
    for i in range(5):
        proxy = next(proxy_pool)
        try:
            resp = requests.get(url, proxies={'http': proxy, 'https': proxy}, timeout=10)
            print(resp.json())
        except requests.exceptions.RequestException as e:
            print(f'Proxy {proxy} failed: {e}')
    
  5. 对于更稳健的轮换,将轮换与使用 requests.Session 和 HTTPAdapter 的重试逻辑结合。
    from requests.adapters import HTTPAdapter
    from urllib3.util.retry import Retry
    
    session = requests.Session()
    retries = Retry(total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504])
    session.mount('http://', HTTPAdapter(max_retries=retries))
    session.mount('https://', HTTPAdapter(max_retries=retries))
    
    proxy = next(proxy_pool)
    resp = session.get(url, proxies={'http': proxy, 'https': proxy}, timeout=10)
    print(resp.json())
    
  6. 验证 IP 是否变化。https://httpbin.org/ip 端点返回源 IP。为每个请求记录或打印它。
  7. 实现健康检查。将反复失败的代理从池中移除。
    def is_proxy_alive(proxy):
        try:
            requests.get('https://httpbin.org/ip', proxies={'http': proxy, 'https': proxy}, timeout=5)
            return True
        except requests.exceptions.RequestException:
            return False
    
    healthy_proxies = [p for p in proxies_list if is_proxy_alive(p)]
    

常见问题排查

  • 407 Proxy Authentication Required:检查代理 URL 中的用户名和密码。对特殊字符进行百分号编码。
  • SOCKS5 连接错误:确保已安装 requests[socks],并且代理 URI 使用 socks5:// 或 socks5h://。
  • SSL 错误:某些代理不支持 HTTPS 隧道。仅对 HTTP 目标使用 HTTP 代理,或切换到支持 CONNECT 的提供商。
  • 响应缓慢:增加超时、降低并发,或使用延迟更低的代理。
  • IP 未变化:通过检查 resp.json() 验证代理是否确实被使用。还要检查代码是否在每次请求前轮换代理。

何时专用 WireGuard 网关更合理

轮换代理非常适合大规模匿名抓取,其中每个请求都可以来自不同 IP。然而,有些任务需要稳定、专用的 IP 地址:

  • 在会标记 IP 变化的网站上维持已登录会话。
  • 从固定位置进行 SEO 排名跟踪。
  • 访问带 IP 允许列表的内部工具或 API。 对于这些情况,专用 WireGuard 网关(例如 NordLayer)可提供稳定的企业级 VPN 隧道,并按月统一计费。NordLayer 提供专用网关,因此你的团队可获得一致 IP,用于安全的网络访问。它不是轮换代理服务,但它通过覆盖需要固定出口 IP 的使用场景,与轮换代理形成互补。

总结

你可以通过循环代理列表、处理异常并验证源 IP,在 Python requests 中轮换代理。对于 SOCKS5,安装 requests[socks]。使用重试逻辑和健康检查来保持抓取可靠。当你需要稳定、专用的 IP 而不是轮换时,可考虑像 NordLayer 这样的专用 WireGuard 网关,用于团队访问和固定 IP 任务。