操作指南
如何在 Python Requests 中使用亚洲住宅代理?
简短回答在 Python Requests 中使用代理,只需在每个请求中传入 proxies 字典,例如 {"https": "http://USERNAME-country-jp:[email protected]:7777"}。使用 Jade Proxies 时,用户名还可指定城市和粘性会话;SOCKS5 用法相同,使用 socks5h:// 和端口 7778。
开始之前需要准备什么?
你需要 Python 3、Requests 库和代理凭据。Jade Proxies 支持用户名和密码,或 IP 白名单(最多 10 个 IP);子用户拥有独立凭据和流量上限;API 密钥可随时撤销。所有示例都通过网关 gw.jadeproxies.com 发送流量:HTTP 和 HTTPS 使用端口 7777,SOCKS5 使用端口 7778。
- 01
安装带 SOCKS 支持的 Requests。
运行
pip install "requests[socks]",即可安装 Requests 和 PySocks。 - 02
保存凭据。
将 Jade Proxies 账户中的代理用户名和密码放入环境变量
PROXY_USER和PROXY_PASS,不要写在代码里。 - 03
构建 HTTP 代理字典。
将
http和https两个键都映射到http://USER:[email protected]:7777;HTTPS 网站通过 CONNECT 隧道访问,因此 TLS 保持端到端加密。 - 04
需要时切换到 SOCKS5。
使用
socks5h://USER:[email protected]:7778,让 DNS 在出口端、即目标国家解析。 - 05
定位国家和城市。
按照
USERNAME-country-{cc}-city-{city}-session-{id}-ttl-{minutes}格式,在用户名后追加-country-jp,再追加-city-osaka。 - 06
用粘性会话保持同一 IP。
添加
-session-ID-ttl-MINUTES并复用同一个requests.Session;IP 保持时长为最长 30 分钟(IP 可能提前变更)。 - 07
验证出口 IP。
在正式任务前,通过代理请求
https://ipinfo.io/json并检查country字段。 - 08
设置超时和重试。
传入
timeout=(10, 30),并挂载带Retry策略的HTTPAdapter,以处理 429 和 5xx 响应。 - 09
并行发送请求。
使用
ThreadPoolExecutor;每个连接只发送一个请求,即可让每个请求使用新 IP。
如何在 Python Requests 中设置 HTTP 代理?
传入一个 proxies 字典,并让其中的 http 和 https 两个键都指向网关的 HTTP 端口,即可设置 HTTP 代理。
import os
import requests
from urllib.parse import quote
USER = os.environ["PROXY_USER"]
PASS = quote(os.environ["PROXY_PASS"], safe="") # encodes @ : / in passwords
proxy = f"http://{USER}-country-jp:{PASS}@gw.jadeproxies.com:7777"
proxies = {"http": proxy, "https": proxy}
r = requests.get("https://example.com/", proxies=proxies, timeout=(10, 30))
print(r.status_code)
即使在 https 键下,代理 URL 也以 http:// 开头:Requests 会通过网关建立 CONNECT 隧道,TLS 会话在你的脚本与目标网站之间进行。返回 407 状态码表示网关拒绝了用户名或密码。
如何在 Requests 中使用 SOCKS5 代理?
将协议改为 socks5h、端口改为 7778 即可使用 SOCKS5,其余代码保持不变。
proxy = f"socks5h://{USER}-country-kr:{PASS}@gw.jadeproxies.com:7778"
proxies = {"http": proxy, "https": proxy}
r = requests.get("https://example.com/", proxies=proxies, timeout=(10, 30))
使用 socks5h 时,由网关在韩国解析主机名。使用普通的 socks5 时,则由你自己的机器解析,这会将查询暴露给本地 DNS,并可能返回目标国家以外的服务器。
如何选择国家和城市?
在用户名中添加参数即可选择出口。Jade Proxies 提供所有套餐均支持国家和城市定位;ASN 定位不额外收费;可用城市因地而异。
| 目标 | 用户名 |
|---|---|
| 日本任意 IP | USER-country-jp |
| 大阪 | USER-country-jp-city-osaka |
| 孟买 | USER-country-in-city-mumbai |
| 曼谷,10 分钟内保持同一 IP | USER-country-th-city-bangkok-session-a1b2c3-ttl-10 |
国家代码为 亚洲住宅代理 页面所列 13 个国家的两位 ISO 代码。用一个小函数即可集中管理格式:
def proxy_url(country, city=None, session=None, ttl=10, socks=False):
user = f"{USER}-country-{country}"
if city:
user += f"-city-{city}"
if session:
user += f"-session-{session}-ttl-{ttl}"
if socks:
return f"socks5h://{user}:{PASS}@gw.jadeproxies.com:7778"
return f"http://{user}:{PASS}@gw.jadeproxies.com:7777"
如何在多个请求之间保持同一 IP?
在用户名中添加会话 ID 和 TTL,并通过同一个 requests.Session 发送请求,即可保持同一 IP。
import uuid
p = proxy_url("jp", "tokyo", session=uuid.uuid4().hex[:8], ttl=30)
s = requests.Session()
s.proxies = {"http": p, "https": p}
for page in range(1, 4):
s.get(f"https://example.jp/list?page={page}", timeout=(10, 30))
不带会话 ID 时,每个新连接都会从 IP 池中获取一个 IP,通常与上一个不同;如需每个请求都更换 IP,请每个连接只发送一个请求(关闭 keep-alive)。requests.Session 会保持连接,因此如果希望每个请求都使用新 IP,请改用普通的 requests.get() 调用。轮换与粘性代理指南 说明了不同任务适合哪种模式。
如何确认出口 IP 位于正确的国家?
通过代理访问一个 IP 信息接口,并将返回的国家代码与你请求的代码进行比较,即可检查出口。
info = requests.get("https://ipinfo.io/json", proxies=proxies, timeout=15).json()
assert info["country"] == "JP", info
print(info["ip"], info.get("city"), info.get("org"))
org 字段显示拥有该 IP 的网络;住宅出口对应的是面向家庭用户的宽带运营商(ISP),而非托管公司。在长时间任务开始前,每个国家运行一次此检查。
如何处理超时和重试?
每次调用都设置连接超时和读取超时,并对临时错误进行带退避的重试,因为住宅出口是家庭网络连接,随时可能断开。
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
retry = Retry(total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], allowed_methods=["GET"])
s = requests.Session()
s.mount("http://", HTTPAdapter(max_retries=retry))
s.mount("https://", HTTPAdapter(max_retries=retry))
r = s.get("https://example.com/", proxies=proxies, timeout=(10, 30))
只有到达目标网站的重试才会消耗流量:用量统计通过代理发送和接收的全部数据(上传和下载,含请求头);1 GB = 1,000,000,000 字节;在到达目标之前失败的连接尝试不计入。
如何并行发送请求?
使用线程池并行发送请求,因为 Requests 是同步的,每个线程各自等待自己的连接。
from concurrent.futures import ThreadPoolExecutor
def fetch(url):
r = requests.get(url, proxies=proxies, timeout=(10, 30))
return url, r.status_code, len(r.content)
with ThreadPoolExecutor(max_workers=10) as pool:
for url, status, size in pool.map(fetch, urls):
print(status, size, url)
每次 requests.get() 调用都会建立独立连接,因此每个请求都会获得各自的 IP。建议从 10 个工作线程开始,在错误和 429 响应的比例保持稳定时再逐步增加,并遵守各网站的速率限制和使用条款。
Python Requests 抓取会消耗多少流量?
抓取流量约等于页面数乘以每个页面的平均传输量。下表按每个页面 100 KB 计算:包括压缩后的 HTML 以及请求和响应头,不含图片。该数值是用于计算的假设值,并非实测数据。
| 抓取规模 | 流量 | 套餐 | 费用 |
|---|---|---|---|
| 10,000 个页面 | 1 GB | 试用版 | $1.50 |
| 100,000 个页面 | 10 GB | 成长版 | $6.60 |
| 500,000 个页面 | 50 GB | 专业版 | $26 |
| 1,000,000 个页面 | 100 GB | 商业版 | $50 |
根据我们的价格表,按此页面大小计算,一百万个页面在 100 GB 套餐下的住宅代理流量费用为 $50。页面大小因网站而异,请先用 1,000 个页面的样本测出你自己的平均值;电商平台目标请参阅 Shopee 与 Lazada 指南。所有套餐见 价格页面,流量永不过期。
常见问题
为什么 Requests 没有使用我的代理?
Requests 只会对 proxies 字典中出现的 URL 协议使用代理,因此只有 http 键的字典会让 HTTPS 请求直接发出。请同时设置两个键,并检查 NO_PROXY 环境变量是否匹配了目标主机。
Requests 中 socks5 和 socks5h 有什么区别?
使用 socks5h 时,由代理在出口端解析主机名;使用 socks5 时,由你的机器在本地解析。访问亚洲目标时请使用 socks5h,使 DNS 解析结果与出口国家一致。
如何让每个请求都使用新 IP?
在用户名中不加会话 ID,并且每个连接只发送一个请求,例如使用普通的 requests.get() 调用,而不是共享的 Session。每个新连接都会从 IP 池中获取一个 IP,通常与上一个不同。
407 错误是什么意思?
407 Proxy Authentication Required 状态表示网关未接受凭据。请检查是否用 urllib.parse.quote 对密码进行了编码,以及用户名格式是否正确,例如 USER-country-jp-city-osaka。
首次测试需要多少钱?
1 GB 套餐价格为 $1.50,按上文 100 KB 的假设约可抓取 10,000 个页面。费用从加密货币余额中扣除,最低充值金额为 $25,未用完的流量永不过期。