# 如何在 Python 中使用支持 IP 轮换的移动代理

> 4G/5G移动代理的 Python 代码示例：基于 HTTP 或 SOCKS5 的 requests 和 httpx，使用 API 轮换 IP，处理 429 限制及粘性会话。无需 KYC。

- URL: https://cellmast.com/zh/guides/python-mobile-proxy/
- 最后更新: 2026-10-13
- Publisher: CellMast (https://cellmast.com)

为CellMast专用端口或轮换移动池提供一键复制 Python 代码：连接、轮换、等待新地址，并且不频繁调用 API。

**快速回答 — 怎么在 Python 中使用带 IP 轮换的移动代理？**

将代理 URL `http://USERNAME:PASSWORD@gw.cellmast.com:7777`传给`requests`或`httpx`，想切换运营商 IP 时调用带有 API 密钥的`POST /api/v1/mobile/{portId}/rotate`。等待响应，通常是 5–15 秒，轮换间隔至少 30 秒。**CellMast** 专用4G/5G端口起价每天$2.63，无需 KYC，可用加密货币支付。

## 所需环境

| 属性 | 值 |
| --- | --- |
| Python | 3.10 及以上版本 |
| 所需库 | `requests`（HTTP），`requests[socks]` 或 `httpx[socks]`（SOCKS5） |
| 网关 | `gw.cellmast.com`，HTTP 端口7777，SOCKS5 端口7778 |
| 端口凭证 | 用户名和密码见客户端区域；支持移端口后，请重新查看主机、端口和密码，因为可能变动 |
| API 密钥 | `proxies`作用域，用于轮换 |
| 轮换池用户名 | `USERNAME-country-{cc}-session-{id}-ttl-{minutes}` |

## 我如何通过移动端口发送请求？

为 `http` 和 `https` 设置相同的代理 URL。对于 HTTPS 目标，`requests` 会通过网关打开一个 CONNECT 隧道，因此目标看到的是运营商 IP，你的 TLS 连接仍保持端到端加密。

*通过 HTTP 的请求*

```python
import requests

PROXY = "http://USERNAME:PASSWORD@gw.cellmast.com:7777"
proxies = {"http": PROXY, "https": PROXY}

r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=30)
print(r.json())  # {'ip': '<carrier IP>'}
```

*SOCKS5（使用 pip 安装 "requests[socks]"）*

```python
import requests

# socks5h: the proxy resolves the hostname, not your machine
PROXY = "socks5h://USERNAME:PASSWORD@gw.cellmast.com:7778"
r = requests.get("https://api.ipify.org", proxies={"http": PROXY, "https": PROXY}, timeout=30)
print(r.text)
```

## 我如何用 Python 轮换 IP？

将轮换调用包装在一个能够处理 429 响应的辅助函数中。下面的辅助函数在你轮换过快时等待 `Retry-After`，然后确认运营商确实分配了新的地址。

*轮换辅助函数*

```python
import time
import requests

API = "https://cellmast.com/api/v1"
KEY = "API_KEY"

def rotate(port_id: str, tries: int = 3) -> str:
    """Ask the modem for a new carrier IP and return it."""
    for _ in range(tries):
        r = requests.post(f"{API}/mobile/{port_id}/rotate",
                          headers={"Authorization": f"Bearer {KEY}"}, timeout=60)
        if r.status_code == 429:  # rotation_too_soon
            time.sleep(int(r.headers.get("Retry-After", "30")))
            continue
        r.raise_for_status()
        data = r.json()
        if data["ip"] != data.get("previousIp"):
            return data["ip"]
        time.sleep(30)  # same IP from the carrier: wait and try again
    raise RuntimeError("no new IP after several tries")

print("new IP:", rotate("PORT_ID"))
```

## 我如何在任务之间轮换，而不是任务中间？

在一个地址上运行整个任务，然后在下一个任务之前轮换。这样可以保持任务内的 cookie 和登录状态一致，并给每个任务分配一个新的地址。

*每个任务一个 IP*

```python
import requests

PROXY = "http://USERNAME:PASSWORD@gw.cellmast.com:7777"

def run_job(urls):
    with requests.Session() as s:
        s.proxies = {"http": PROXY, "https": PROXY}
        for url in urls:
            resp = s.get(url, timeout=30)
            print(resp.status_code, url)

jobs = [["https://example.com/a", "https://example.com/b"],
        ["https://example.com/c"]]
for urls in jobs:
    run_job(urls)
    rotate("PORT_ID")  # helper from the previous example
```

## 我如何在 httpx 中使用带粘性会话的轮换池？

每 GB 计费的池没有单独的轮换调用：用户名决定。没有会话 ID 时，每个新连接都会获得一个新的 IP。HTTP 客户端会保持连接（keep-alive），所以若要每个请求用新 IP，需为每个请求打开一个新客户端，或发送 `Connection: close`。使用 `session-<id>-ttl-<minutes>` 时，请求在该时间内保持单一 IP。

*httpx（使用 pip 安装 httpx）*

```python
import uuid
import httpx

def pool_client(country: str = "us", minutes: int | None = None) -> httpx.Client:
    user = f"USERNAME-country-{country}"
    if minutes:
        user += f"-session-{uuid.uuid4().hex[:8]}-ttl-{minutes}"
    proxy = f"http://{user}:PASSWORD@gw.cellmast.com:7777"
    return httpx.Client(proxy=proxy, timeout=30)

with pool_client("gb", minutes=10) as c:   # same UK mobile IP for 10 minutes
    print(c.get("https://api.ipify.org").text)
    print(c.get("https://api.ipify.org").text)
```

## 我的脚本应该处理哪些错误？

- **来自轮换 API 的 HTTP 429：** 表示你少于 30 秒前已轮换。请等待 `Retry-After`。
- **HTTP 409 `port_not_active`：** 端口已过期或被暂停。请检查客户区。
- **轮换后代理连接错误：** 正常，调制解调器正在重新连接。稍等后重试。
- **网关返回 HTTP 407：** 端口的用户名或密码错误。
- **目标返回 403 或 429：** 首先放慢请求速度，然后轮换一次。移动 IP 是共享的，降低频率能解决大部分问题。

## Python 与移动代理：常见问题

### 我应该在 Python 中使用 HTTP 还是 SOCKS5？

HTTP 更简单，兼容普通的 `requests`。SOCKS5 需要额外的 `requests[socks]`，但能承载所有 TCP 流量，并且 `socks5h://` 在代理端解析 DNS，而非本机。两者都连接至相同的 CellMast 调制解调器：HTTP 用端口 7777，SOCKS5 用端口 7778。

### 我能用 asyncio 搭配移动代理吗？

可以。`httpx.AsyncClient(proxy=...)` 和 `aiohttp` 均接受 HTTP 代理 URL。在单个专用端口保持适度并发：它只有一个调制解调器和一个运营商连接，数十个并行请求共用同一无线链路。

### 我如何让 Selenium 或 Playwright 使用端口？

在 Playwright 里，将 `proxy={"server": "http://gw.cellmast.com:7777", "username": "USERNAME", "password": "PASSWORD"}` 传给 `launch()` 或 `new_context()`。Selenium 的代理选项无密码字段：通过 Selenium 4 BiDi 网络认证完成代理登录，或者使用 Playwright。请在浏览器上下文间轮换，不要在页面加载时轮换。

**获取端口和 API 密钥** 来自 每天$2.63 的专用 4G/5G 端口，来自 US$1.50/GB 的轮换移动数据。支持加密货币支付。 [查看价格](https://cellmast.com/zh/pricing/) · [移动 API 参考](https://cellmast.com/docs/api/mobile/)

---

CellMast: CellMast 是一家 4G/5G 4G 移动代理提供商：配备专用运营商猫，流量不限，同时提供按 GB 计费的轮换移动代理池，支持加密货币支付，无需上传身份信息。
