Python代理

Python 是数据爬取和自动化的首选语言。但任何脚本迟早都会遇到 IP 封禁的问题。为了避免这种情况,需要合理地集成代理。

在本指南中,我们将探讨如何在四种最常见的场景中连接代理:从简单的请求到浏览器控制。


📌 方法 1. requests 库(最常用)

如果你正在编写一个简单的爬虫或使用 API,你会用到 requests。在这里,代理通过一个普通的字典(dict)传递。

代码:

import requests

# 格式:login:password@ip:port
# 在 CyberYozh App 中,我们为 HTTP 使用端口 5959
proxy = "http://user:pass@51.77.190.247:5959"

proxies = {
    "http": proxy,
    "https": proxy
}

try:
    # 务必指定超时时间!
    response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
    print(f"您的 IP: {response.json()['origin']}")
except Exception as e:
    print(f"错误: {e}")

建议: 不要将代理硬编码在代码中。最好将它们提取到环境变量中(os.getenv)。

如果您想在 Python 中使用 SOCKS5,您需要:

1. 安装额外的库: requests 本身不支持 SOCKS。您需要安装扩展:

pip install requests[socks]
# 或
pip install pysocks

 

2. 修改代码中的协议: 此处端口和语法更改为 9595socks5h://

import requests

# 使用 socks5h 以防止 DNS 泄漏(远程 DNS 解析)
socks_proxy = "socks5h://user:pass@51.77.190.247:9595"

proxies = {
    "http": socks_proxy,
    "https": socks_proxy
}

try:
    response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
    print(f"通过 SOCKS5 的 IP: {response.json()['origin']}")
except Exception as e:
    print(f"错误: {e}")

 


🤖 方法 2. Selenium 库(浏览器模拟)

如果网站使用复杂的 JavaScript (React, Vue)、单页应用 (SPA) 或 Cloudflare 防护,普通的 requests 将无法胜任 — 它无法执行 JS 代码。您需要 Selenium 来打开并控制真实的浏览器(Chrome/Firefox)。

⚠️ 主要问题:身份验证

标准的 Chrome 有一个令人不快的特性:它不支持通过启动参数传递代理登录名和密码。如果您尝试传递 http://user:pass@ip:port,浏览器会直接忽略身份验证并弹出窗口要求输入密码,从而导致自动化失败。

✅ 解决方案:selenium-wire

这是普通 Selenium 的一个插件,它能够拦截请求并自动填入代理的登录名和密码。

安装:

pip install selenium-wire

 

代码(带身份验证的正确配置):

# 注意:从 seleniumwire 而不是 selenium 导入 webdriver
from seleniumwire import webdriver 

# 来自 CyberYozh App 的代理数据
PROXY_HOST = "51.77.190.247"
PROXY_PORT = "5959" # HTTP 端口
PROXY_USER = "您的登录名"
PROXY_PASS = "您的密码"

# 形成配置字典
proxy_options = {
    'proxy': {
        'http': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
        'https': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
        'no_proxy': 'localhost,127.0.0.1' # 不对本地地址使用代理
    }
}

# 使用 seleniumwire_options 选项初始化浏览器
driver = webdriver.Chrome(seleniumwire_options=proxy_options)

print("浏览器已启动,正在检查 IP...")
driver.get("https://httpbin.org/ip")

# 输出页面内容(那里应该是您的代理 IP)
print(driver.find_element("tag name", "body").text)

driver.quit()

 

为什么这可行: selenium-wire 创建了一个本地中间服务器,负责与您的代理进行通信。浏览器以为是在无密码状态下工作,而库本身会自动“粘贴”必要的身份验证头。这是 Python 最可靠的方法。

Selenium 与 SOCKS5:

requests 相同,为了让 selenium-wire 与 SOCKS 代理配合使用,您需要安装 pysocks 库(如果尚未安装):

pip install pysocks

 

SOCKS5 代码 (Selenium Wire)

逻辑保持不变:字典的键('http', 'https')告诉库要拦截哪些流量,而值(socks5://...)则告诉库将其导向何处。

from seleniumwire import webdriver  # 务必从 seleniumwire 导入!

# 您的 SOCKS5 代理数据
PROXY_HOST = "51.77.190.247"
PROXY_PORT = "9595"  # 确保这是 SOCKS5 的端口(通常与 HTTP 不同)
PROXY_USER = "您的登录名"
PROXY_PASS = "您的密码"

# 设置
proxy_options = {
    'proxy': {
        # 协议改为 socks5://
        'http': f'socks5://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
        'https': f'socks5://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
        'no_proxy': 'localhost,127.0.0.1'
    }
}

# 启动浏览器
# 可以通过 chrome_options=... 添加常规 Chrome 选项(如 headless 等)
driver = webdriver.Chrome(seleniumwire_options=proxy_options)

try:
    print("浏览器已启动,正在检查 IP...")
    driver.get("https://httpbin.org/ip")

    # 输出 IP
    print(driver.find_element("tag name", "body").text)

    # 建议在更详细的检测网站上验证代理类型
    # driver.get("https://browserleaks.com/ip")

except Exception as e:
    print(f"错误: {e}")
finally:
    driver.quit()

 

区别在哪里?

proxy_options 字典中,我们将协议从 http:// 更改为 socks5://

请注意字典的键: 我们将键 'http''https' 更改为 'socks'

  • 'https' 意味着:“当浏览器请求 HTTPS 网站时...”

  • socks5://... 意味着:“...通过这个 SOCKS5 隧道发送它们”。

那么 DNS (socks5h) 呢?

selenium-wire 中,DNS 解析由库的内部逻辑负责。通常,如果使用 socks5 协议,它本身就能很好地处理通过代理重定向 DNS 请求的问题,因为 selenium-wire 充当浏览器与互联网之间的中间人(Man-in-the-Middle)。

如果您突然发现 DNS 泄漏(在检测站能看到您的运营商),请尝试在连接字符串中指定 socks5h:// — 得益于底层使用的 requests 库,selenium-wire 支持此格式。


🚀 方法 3. aiohttp 库(异步)

当需要在一分钟内爬取 10,000 个页面时,会使用异步方法(async/await)。在这种情况下,标准的 requests 并不适用,需要 aiohttp

代码:

import aiohttp
import asyncio

async def fetch_ip():
    proxy_auth = aiohttp.BasicAuth('user', 'pass') # 登录名和密码分开
    proxy_url = "http://51.77.190.247:5959"

    async with aiohttp.ClientSession() as session:
        async with session.get("https://httpbin.org/ip", 
                               proxy=proxy_url, 
                               proxy_auth=proxy_auth) as resp:
            print(await resp.json())

asyncio.run(fetch_ip())

 

aiohttp 的 SOCKS5

对于 aiohttp,情况比 requests 稍微复杂一点。aiohttp 库本身不支持 SOCKS 代理。它只能与 HTTP 代理配合使用。

为了“教会”它使用 SOCKS5,需要使用特殊的连接器(Connector)

1. 安装

您需要额外的桥接库 aiohttp-socks

pip install aiohttp-socks

 

2. 代码(通过 Connector 的正确方法)

与 HTTP 示例(我们在每个请求中传递代理 session.get(..., proxy=...))不同,对于 SOCKS5,我们在创建会话时设置一次代理

这对性能也更好(保持连接活跃)。

import aiohttp
import asyncio
from aiohttp_socks import ProxyConnector # 导入连接器

async def fetch_ip():
    # 形成连接字符串。
    # 请注意:将登录名和密码直接嵌入 URL 字符串中。
    socks_url = "socks5://user:pass@51.77.190.247:9595"

    # 创建连接器
    # rdns=True 相当于 socks5h(防止 DNS 泄漏)。
    # 这对于匿名性是必须的。
    connector = ProxyConnector.from_url(socks_url, rdns=True)

    # 将连接器传递给 ClientSession
    # 现在整个会话都将通过 SOCKS5 工作
    async with aiohttp.ClientSession(connector=connector) as session:
        try:
            # 注意:在 .get() 内部不再需要写 proxy=...
            # 代理已经通过连接器“缝合”到了会话中。
            async with session.get("https://httpbin.org/ip") as resp:
                print(await resp.json())
        except Exception as e:
            print(f"错误: {e}")

if __name__ == '__main__':
    # 适用于 Windows/Linux 的正确启动方式
    asyncio.run(fetch_ip())

 

🔍 与 HTTP 版本的主要区别是什么?
  1. 库: 我们添加了 from aiohttp_socks import ProxyConnector

  2. 设置位置:

    • 之前:session.get(..., proxy=...)(在每个请求中设置)。

    • 现在:aiohttp.ClientSession(connector=...)(设置整个会话)。

  3. DNS (rdns=True): 参数 rdns=Truesocks5h 作用相同 — 强制在代理端解析域名,从而向运营商隐藏您访问的地址。

这段代码非常适合爬取 10,000 个页面,因为 connector 能高效地管理通过 SOCKS 隧道的连接池。


🔧 方法 4. 使用环境变量(最佳实践)

专业的开发人员不会在代码内部写死代理。这不安全(如果您将代码上传到 GitHub,您的代理会被盗用)。Python 能够自动从系统中获取代理设置。

在终端中 (Linux/Mac):

export HTTP_PROXY="http://user:pass@51.77.190.247:5959"

 

在代码中:

import requests
# 不需要传递任何 proxies=... 参数!
# 库会自动在系统中寻找设置。
requests.get("https://httpbin.org/ip")  

 


💡 为 Python 脚本选择哪种代理?

写好代码只是成功了一半。关键在于代理本身的质量和管理轮换的方式。根据任务的不同,脚本的架构也会随之改变。

1. 数据中心代理 IPv4, IPv6

非常适合: 简单的 API 请求、文件下载、处理没有严格防护的网站。

  • Python 逻辑: 如果某个 IP 被封禁 — 在脚本中直接更换为您代理列表中的下一个即可。

  • 优点: 速度快(高达 1 Gbps)且价格低廉。

2. 动态住宅代理 (Residential Rotating)

非常适合: 强力爬取(Amazon, 社交媒体)、绕过 Cloudflare 以及收集大数据量。

  • 轮换如何工作:不需要编写复杂的轮换代码。在 CyberYozh App 中,我们使用“智能凭据生成器”。您只需更改登录名即可更改代理的行为:

    • login-res-any:脚本的每次请求都会获得一个新的 IP(requests.get)。

    • login-res-any-sid-12345678:IP 会锁定在这一组数字(sid)上,最长可持续 1 分钟

       

    • login-resfix:脚本会固定 IP(粘性会话),以便进行身份验证。

  • 对 Python 的好处: 您只需使用一行连接字符串,即可访问数百万个 IP。

👉 点击此处了解更多关于住宅代理轮换的信息。

3. 移动代理 (Mobile 4G/LTE)

非常适合: 注册账号、社交媒体操作(Instagram, TikTok)以及通过 Selenium/Appium 模拟真实用户。拥有最高的信任级别。

代码中有两种管理场景:

  • 🅰️ 独享型(Private):通过链接轮换 您租用整个调制解调器。为了更换 IP,您的 Python 脚本必须“请求”一个特殊的 API 链接。

    • 逻辑示例:

      # 1. 执行一系列动作
      do_registration()
      # 2. 通过 API 重启调制解调器
      requests.get("https://app.cyberyozh.com/api/v1/...") 
      time.sleep(15) # 等待调制解调器上线
      # 3. 开始新一轮循环
  • 🅱️ 共享型(Shared):自动轮换 IP 根据服务的计时器自动更换(例如每 5 或 30 分钟)。

    • Python 逻辑: 您需要处理连接中断。如果请求期间调制解调器正在重启 — 脚本应捕获 ConnectionError,等待几秒钟并重试请求(Retry)。

👉 点击此处了解更多关于移动代理的信息。


总结

在 Python 中集成代理只需 3-5 行代码。关键在于根据任务选择正确的代理类型和库。

👉 准备好开始编程了吗?CyberYozh App 目录中,您可以找到列出的所有代理类型。只需为您的任务选择合适的套餐(爬取、注册或冲浪),复制访问权限并在几分钟内将其集成到您的项目中。

``` 您是否需要我帮您编写一个具体的脚本,例如使用 `aiohttp` 实现带自动重试功能的爬虫?