# 如何在 Python Requests 中使用亚洲住宅代理？

> 在 Python Requests 中使用代理，只需在每个请求中传入 proxies 字典，例如 {"https": "http://USERNAME-country-jp:PASSWORD@gw.jadeproxies.com:7777"}。使用 Jade Proxies 时，用户名还可指定城市和粘性会话；SOCKS5 用法相同，使用 socks5h:// 和端口 7778。

来源： https://jadeproxies.com/zh/how-to-use-a-proxy-with-python-requests/ · Jade Proxies · 更新于 2026年10月29日

**关键数据: $50** — 根据我们的价格表，按每个页面传输 100 KB 计算，使用 Python Requests 抓取一百万个页面，在 100 GB 套餐下的住宅代理流量费用为 $50。 (Jade Proxies 价格表，2026年10月29日；100 KB 页面大小为假设值，并非实测数据)


## 开始之前需要准备什么？

你需要 Python 3、Requests 库和代理凭据。Jade Proxies 支持用户名和密码，或 IP 白名单（最多 10 个 IP）；子用户拥有独立凭据和流量上限；API 密钥可随时撤销。所有示例都通过网关 `gw.jadeproxies.com` 发送流量：HTTP 和 HTTPS 使用端口 7777，SOCKS5 使用端口 7778。

1. **安装带 SOCKS 支持的 Requests。** 运行 `pip install "requests[socks]"`，即可安装 Requests 和 PySocks。
2. **保存凭据。** 将 Jade Proxies 账户中的代理用户名和密码放入环境变量 `PROXY_USER` 和 `PROXY_PASS`，不要写在代码里。
3. **构建 HTTP 代理字典。** 将 `http` 和 `https` 两个键都映射到 `http://USER:PASS@gw.jadeproxies.com:7777`；HTTPS 网站通过 CONNECT 隧道访问，因此 TLS 保持端到端加密。
4. **需要时切换到 SOCKS5。** 使用 `socks5h://USER:PASS@gw.jadeproxies.com:7778`，让 DNS 在出口端、即目标国家解析。
5. **定位国家和城市。** 按照 `USERNAME-country-{cc}-city-{city}-session-{id}-ttl-{minutes}` 格式，在用户名后追加 `-country-jp`，再追加 `-city-osaka`。
6. **用粘性会话保持同一 IP。** 添加 `-session-ID-ttl-MINUTES` 并复用同一个 `requests.Session`；IP 保持时长为最长 30 分钟（IP 可能提前变更）。
7. **验证出口 IP。** 在正式任务前，通过代理请求 `https://ipinfo.io/json` 并检查 `country` 字段。
8. **设置超时和重试。** 传入 `timeout=(10, 30)`，并挂载带 `Retry` 策略的 `HTTPAdapter`，以处理 429 和 5xx 响应。
9. **并行发送请求。** 使用 `ThreadPoolExecutor`；每个连接只发送一个请求，即可让每个请求使用新 IP。

## 如何在 Python Requests 中设置 HTTP 代理？

传入一个 `proxies` 字典，并让其中的 `http` 和 `https` 两个键都指向网关的 HTTP 端口，即可设置 HTTP 代理。

```python
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，其余代码保持不变。

```python
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` |

国家代码为 [亚洲住宅代理](https://jadeproxies.com/zh/asian-residential-proxies/) 页面所列 13 个国家的两位 ISO 代码。用一个小函数即可集中管理格式：

```python
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。

```python
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()` 调用。[轮换与粘性代理指南](https://jadeproxies.com/zh/rotating-vs-sticky-proxies/) 说明了不同任务适合哪种模式。

## 如何确认出口 IP 位于正确的国家？

通过代理访问一个 IP 信息接口，并将返回的国家代码与你请求的代码进行比较，即可检查出口。

```python
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），而非托管公司。在长时间任务开始前，每个国家运行一次此检查。

## 如何处理超时和重试？

每次调用都设置连接超时和读取超时，并对临时错误进行带退避的重试，因为住宅出口是家庭网络连接，随时可能断开。

```python
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 是同步的，每个线程各自等待自己的连接。

```python
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 指南](https://jadeproxies.com/zh/best-proxy-for-shopee-lazada-scraping/)。所有套餐见 [价格页面](https://jadeproxies.com/zh/pricing/)，流量永不过期。

## 常见问题

### 为什么 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 个页面。费用从加密货币余额中扣除，最低充值金额为 $1，未用完的流量永不过期。
