docs: 解锁器文档重写,以SDK为主;移至报价相关API下方(03-06)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -20,9 +20,9 @@ allowed-tools: "Read,Grep,Glob"
|
|||||||
|
|
||||||
| 前缀 | 类别 | 内容 |
|
| 前缀 | 类别 | 内容 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| 01-01 | 解锁器 | Unlocker API(Agent/Request 模式、异步轮询、mipu_requests SDK) |
|
|
||||||
| 02-xx | 缓存查询 | cache/search |
|
| 02-xx | 缓存查询 | cache/search |
|
||||||
| 03-01~03-05 | 报价相关 | search、select、baggage、seat、async-query |
|
| 03-01~03-05 | 报价相关 | search、select、baggage、seat、async-query |
|
||||||
|
| 03-06 | 解锁器 | Unlocker API(Agent/Request 模式、异步轮询、mipu_requests SDK) |
|
||||||
| 04-01~04-05 | 订单管理 | hold、payment、query、cancel、retry |
|
| 04-01~04-05 | 订单管理 | hold、payment、query、cancel、retry |
|
||||||
| 07-01~07-04 | 请求实体 | FlightSegmentRequest、Passenger、ContactInfo、Ancillary |
|
| 07-01~07-04 | 请求实体 | FlightSegmentRequest、Passenger、ContactInfo、Ancillary |
|
||||||
| 08-01~08-06 | 响应实体 | Itinerary、FlightFare、SegmentElement、FlightPolicy、AncillaryProduct、feeItems |
|
| 08-01~08-06 | 响应实体 | Itinerary、FlightFare、SegmentElement、FlightPolicy、AncillaryProduct、feeItems |
|
||||||
|
|||||||
@@ -1,381 +0,0 @@
|
|||||||
<!-- mipuyun-api-doc: unlocker -->
|
|
||||||
# 解锁器 (Unlocker)
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
|
|
||||||
解锁器是米普云的核心代理服务,允许你通过米普 API 代理发送 HTTP 请求到目标网站。所有请求经过米普网关转发,目标网站看到的是米普的 IP 和会话,而非你的真实信息。
|
|
||||||
|
|
||||||
### 典型用途
|
|
||||||
|
|
||||||
- 代理访问航司官网,模拟浏览器操作
|
|
||||||
- 通过 Agent 机制维持登录态和会话
|
|
||||||
- 获取航司网页数据(HTML、JSON)
|
|
||||||
|
|
||||||
### 两种模式
|
|
||||||
|
|
||||||
| 模式 | 端点 | 适用场景 |
|
|
||||||
|------|------|----------|
|
|
||||||
| Agent 模式 | `/unlocker/agent` | 通过 Agent 代理,Agent 维持登录态和会话,适合需要身份验证的场景 |
|
|
||||||
| Request 模式 | `/unlocker/request` | 直接代理请求,无需 Agent,适合简单的 HTTP 代理场景 |
|
|
||||||
|
|
||||||
## 认证
|
|
||||||
|
|
||||||
所有请求必须包含以下 Header:
|
|
||||||
|
|
||||||
| 参数 | 值 | 说明 |
|
|
||||||
|------|-----|------|
|
|
||||||
| Content-Type | application/json | 固定值 |
|
|
||||||
| Accept-Encoding | gzip, deflate, br | 必填 |
|
|
||||||
| client-key | (由米普云提供) | 客户端 key |
|
|
||||||
| client-secret | (由米普云提供) | 客户端 secret |
|
|
||||||
|
|
||||||
## 请求说明
|
|
||||||
|
|
||||||
### Agent 模式
|
|
||||||
|
|
||||||
| 项目 | 值 |
|
|
||||||
|------|-----|
|
|
||||||
| URL | `POST https://{endpoint}/unlocker/agent` |
|
|
||||||
| Content-Type | application/json |
|
|
||||||
|
|
||||||
**请求体:**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"url": "https://www.example.com/page",
|
|
||||||
"method": "GET",
|
|
||||||
"agent": "JQ",
|
|
||||||
"proxy": "res_mipu_xxx",
|
|
||||||
"async": true,
|
|
||||||
"headers": {
|
|
||||||
"user-agent": "Mozilla/5.0 ...",
|
|
||||||
"accept": "text/html"
|
|
||||||
},
|
|
||||||
"sessionId": ""
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| 字段 | 类型 | 必填 | 说明 |
|
|
||||||
|------|------|------|------|
|
|
||||||
| url | string | 是 | 目标 URL |
|
|
||||||
| method | string | 是 | HTTP 方法:GET、POST、PUT、DELETE 等 |
|
|
||||||
| agent | string | 是 | Agent 编码(在米普控制台创建) |
|
|
||||||
| proxy | string | 是 | 代理资源标识(在米普控制台获取) |
|
|
||||||
| async | boolean | 否 | 是否异步模式,默认 true |
|
|
||||||
| headers | object | 否 | 请求头(传递给目标网站) |
|
|
||||||
| body | string | 否 | 请求体(POST/PUT 时使用) |
|
|
||||||
| contentType | string | 否 | Content-Type 覆盖 |
|
|
||||||
| sessionId | string | 否 | 会话 ID(首次请求后自动返回,后续请求传入以保持会话) |
|
|
||||||
|
|
||||||
### Request 模式
|
|
||||||
|
|
||||||
| 项目 | 值 |
|
|
||||||
|------|-----|
|
|
||||||
| URL | `POST https://{endpoint}/unlocker/request` |
|
|
||||||
| Content-Type | application/json |
|
|
||||||
|
|
||||||
请求体与 Agent 模式相同,但**不需要 `agent` 字段**。请求直接到达网关,不经过 Agent。
|
|
||||||
|
|
||||||
## 响应说明
|
|
||||||
|
|
||||||
### 同步响应
|
|
||||||
|
|
||||||
当 `async=false` 或目标网站快速返回时,直接返回结果:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 0,
|
|
||||||
"sessionId": "abc123",
|
|
||||||
"statusCode": 200,
|
|
||||||
"responseBody": "<html>...</html>",
|
|
||||||
"responseHeaders": {
|
|
||||||
"content-type": "text/html"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
|
||||||
|------|------|------|
|
|
||||||
| code | int | 0 = 成功,其他见错误码 |
|
|
||||||
| sessionId | string | 会话 ID,后续请求传入以保持会话连续性 |
|
|
||||||
| statusCode | int | 目标网站返回的 HTTP 状态码 |
|
|
||||||
| responseBody | string | 目标网站返回的响应体 |
|
|
||||||
| responseHeaders | object | 目标网站返回的响应头 |
|
|
||||||
|
|
||||||
### 异步响应
|
|
||||||
|
|
||||||
当 `async=true` 时,首次提交返回:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 202,
|
|
||||||
"agentRequestId": "req_xxx"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
需要通过异步查询接口轮询获取结果。
|
|
||||||
|
|
||||||
## 异步查询
|
|
||||||
|
|
||||||
| 项目 | 值 |
|
|
||||||
|------|-----|
|
|
||||||
| URL | `GET https://{endpoint}/async/query/{agentRequestId}` |
|
|
||||||
|
|
||||||
**请求头:**
|
|
||||||
|
|
||||||
| 参数 | 值 |
|
|
||||||
|------|-----|
|
|
||||||
| client-key | 客户端 key |
|
|
||||||
| client-secret | 客户端 secret |
|
|
||||||
|
|
||||||
**轮询策略:**
|
|
||||||
|
|
||||||
1. 提交请求后等待 2 秒
|
|
||||||
2. 每隔 3 秒查询一次
|
|
||||||
3. 最多查询 20 次(约 62 秒)
|
|
||||||
4. 返回 `code=0` 表示完成
|
|
||||||
5. 超过最大次数仍无结果则视为超时
|
|
||||||
|
|
||||||
## 错误码
|
|
||||||
|
|
||||||
| 码 | 含义 | 处理建议 |
|
|
||||||
|----|------|----------|
|
|
||||||
| 0 | 成功 | — |
|
|
||||||
| 100 | 鉴权失败 | 检查 client-key 和 client-secret |
|
|
||||||
| 102 | 超过限流 | 降低请求频率,稍后重试 |
|
|
||||||
| 103 | Proxy 错误 | 检查 proxy 标识是否正确,IP 是否可用 |
|
|
||||||
| 104 | Agent 不存在 | 检查 agent 编码,新创建的 Agent 需等待 5 分钟生效 |
|
|
||||||
| 202 | 异步处理中 | 继续轮询 /async/query/{id} |
|
|
||||||
|
|
||||||
更多错误码请查阅 `10_error-codes.md`。
|
|
||||||
|
|
||||||
## 会话管理(sessionId)
|
|
||||||
|
|
||||||
sessionId 用于保持与目标网站的会话连续性。工作流程:
|
|
||||||
|
|
||||||
```
|
|
||||||
第 1 次请求: 传入 sessionId = ""(空或不传)
|
|
||||||
↓
|
|
||||||
响应返回: sessionId = "abc123"
|
|
||||||
↓
|
|
||||||
第 2 次请求: 传入 sessionId = "abc123"
|
|
||||||
↓
|
|
||||||
响应返回: sessionId = "abc123"(相同会话)
|
|
||||||
```
|
|
||||||
|
|
||||||
- 首次请求不传 sessionId
|
|
||||||
- 从第一次响应中获取 sessionId
|
|
||||||
- 后续请求都传入该 sessionId
|
|
||||||
- 同一 sessionId 共享 Cookie、登录态等
|
|
||||||
|
|
||||||
## 直接调用示例
|
|
||||||
|
|
||||||
### cURL
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "https://api-eu.mipuyun.com/unlocker/agent" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "client-key: <YOUR_CLIENT_KEY>" \
|
|
||||||
-H "client-secret: <YOUR_CLIENT_SECRET>" \
|
|
||||||
-d '{
|
|
||||||
"url": "https://www.example.com/api/data",
|
|
||||||
"method": "GET",
|
|
||||||
"agent": "JQ",
|
|
||||||
"proxy": "res_mipu_xxx",
|
|
||||||
"async": true,
|
|
||||||
"headers": {
|
|
||||||
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Python (requests)
|
|
||||||
|
|
||||||
```python
|
|
||||||
import requests
|
|
||||||
|
|
||||||
API_URL = "https://api-eu.mipuyun.com/unlocker/agent"
|
|
||||||
HEADERS = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"client-key": "<YOUR_CLIENT_KEY>",
|
|
||||||
"client-secret": "<YOUR_CLIENT_SECRET>",
|
|
||||||
}
|
|
||||||
|
|
||||||
# 提交请求
|
|
||||||
payload = {
|
|
||||||
"url": "https://www.example.com/api/data",
|
|
||||||
"method": "GET",
|
|
||||||
"agent": "JQ",
|
|
||||||
"proxy": "res_mipu_xxx",
|
|
||||||
"async": True,
|
|
||||||
"headers": {"user-agent": "Mozilla/5.0"},
|
|
||||||
}
|
|
||||||
resp = requests.post(API_URL, json=payload, headers=HEADERS)
|
|
||||||
data = resp.json()
|
|
||||||
|
|
||||||
# 异步轮询
|
|
||||||
if data["code"] == 202:
|
|
||||||
import time
|
|
||||||
query_url = f"https://api-eu.mipuyun.com/async/query/{data['agentRequestId']}"
|
|
||||||
for _ in range(20):
|
|
||||||
time.sleep(3)
|
|
||||||
result = requests.get(query_url, headers=HEADERS).json()
|
|
||||||
if result["code"] == 0:
|
|
||||||
print(result["responseBody"])
|
|
||||||
break
|
|
||||||
```
|
|
||||||
|
|
||||||
## 使用 mipu_requests SDK
|
|
||||||
|
|
||||||
[`mipu-requests`](https://pypi.org/project/mipu-requests/) 是米普官方 Python SDK,兼容 `requests` 接口,封装了解锁器的提交、异步轮询、会话管理等细节。
|
|
||||||
|
|
||||||
### 安装
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip install mipu-requests
|
|
||||||
```
|
|
||||||
|
|
||||||
### 基础用法
|
|
||||||
|
|
||||||
```python
|
|
||||||
import mipu_requests
|
|
||||||
|
|
||||||
# 创建 Session(凭据通过构造参数传入)
|
|
||||||
s = mipu_requests.session(
|
|
||||||
base_url="https://api-eu.mipuyun.com",
|
|
||||||
client_key="<YOUR_CLIENT_KEY>",
|
|
||||||
client_secret="<YOUR_CLIENT_SECRET>",
|
|
||||||
agent="JQ",
|
|
||||||
)
|
|
||||||
|
|
||||||
# 设置代理
|
|
||||||
s.proxies = "res_mipu_xxx"
|
|
||||||
|
|
||||||
# 发送 GET 请求(SDK 自动处理异步轮询)
|
|
||||||
resp = s.get("https://www.example.com/page",
|
|
||||||
headers={"user-agent": "Mozilla/5.0"})
|
|
||||||
|
|
||||||
print(resp.status_code) # 200
|
|
||||||
print(resp.text) # 目标网站 HTML
|
|
||||||
print(resp.session_id) # 自动管理的 sessionId
|
|
||||||
|
|
||||||
# 发送 POST 请求
|
|
||||||
resp = s.post("https://www.example.com/api",
|
|
||||||
json={"key": "value"},
|
|
||||||
headers={"content-type": "application/json"})
|
|
||||||
print(resp.json())
|
|
||||||
```
|
|
||||||
|
|
||||||
### Agent 模式 vs Request 模式
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Agent 模式 — 通过 Agent 代理(默认)
|
|
||||||
s = mipu_requests.session(..., agent="JQ")
|
|
||||||
|
|
||||||
# Request 模式 — 直接代理,无需 Agent
|
|
||||||
s = mipu_requests.session(..., mode="request")
|
|
||||||
```
|
|
||||||
|
|
||||||
### 异步模式
|
|
||||||
|
|
||||||
SDK 默认启用异步模式,自动处理提交和轮询:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# 默认异步(推荐)
|
|
||||||
s = mipu_requests.session(..., async_mode=True)
|
|
||||||
|
|
||||||
# 关闭异步(同步等待,可能因长连接断连)
|
|
||||||
s = mipu_requests.session(..., async_mode=False)
|
|
||||||
|
|
||||||
# 自定义轮询参数
|
|
||||||
s = mipu_requests.session(
|
|
||||||
...,
|
|
||||||
poll_interval=3, # 轮询间隔(秒)
|
|
||||||
poll_max=20, # 最大轮询次数
|
|
||||||
submit_timeout=60, # 提交超时(秒)
|
|
||||||
poll_timeout=(5, 30), # 轮询超时 (connect, read)
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 会话管理
|
|
||||||
|
|
||||||
SDK 自动管理 sessionId,无需手动传递:
|
|
||||||
|
|
||||||
```python
|
|
||||||
s = mipu_requests.session(...)
|
|
||||||
|
|
||||||
# 第 1 次请求 — SDK 自动获取 sessionId
|
|
||||||
resp1 = s.get("https://example.com/login")
|
|
||||||
# s.session_id 已自动设置
|
|
||||||
|
|
||||||
# 第 2 次请求 — SDK 自动传入 sessionId,保持会话
|
|
||||||
resp2 = s.get("https://example.com/dashboard")
|
|
||||||
```
|
|
||||||
|
|
||||||
### 错误处理
|
|
||||||
|
|
||||||
```python
|
|
||||||
import mipu_requests
|
|
||||||
|
|
||||||
try:
|
|
||||||
resp = s.get("https://example.com/api")
|
|
||||||
resp.raise_for_status() # 目标网站 4xx/5xx 时抛出异常
|
|
||||||
except mipu_requests.HTTPError as e:
|
|
||||||
print(f"目标网站错误: {e.response.status_code}")
|
|
||||||
except mipu_requests.APIError as e:
|
|
||||||
print(f"米普 API 错误: {e}")
|
|
||||||
except mipu_requests.PollTimeoutError as e:
|
|
||||||
print(f"异步轮询超时: {e}")
|
|
||||||
except mipu_requests.RequestException as e:
|
|
||||||
print(f"请求异常: {e}")
|
|
||||||
```
|
|
||||||
|
|
||||||
### 完整流程示例
|
|
||||||
|
|
||||||
```python
|
|
||||||
import mipu_requests
|
|
||||||
|
|
||||||
with mipu_requests.session(
|
|
||||||
base_url="https://api-eu.mipuyun.com",
|
|
||||||
client_key="<YOUR_CLIENT_KEY>",
|
|
||||||
client_secret="<YOUR_CLIENT_SECRET>",
|
|
||||||
agent="JQ",
|
|
||||||
) as s:
|
|
||||||
s.proxies = "res_mipu_xxx"
|
|
||||||
|
|
||||||
# 访问首页
|
|
||||||
resp = s.get("https://www.example.com/home")
|
|
||||||
resp.raise_for_status()
|
|
||||||
|
|
||||||
# 提交表单(sessionId 自动传递)
|
|
||||||
resp = s.post("https://www.example.com/submit",
|
|
||||||
data={"field": "value"},
|
|
||||||
headers={"content-type": "application/x-www-form-urlencoded"})
|
|
||||||
resp.raise_for_status()
|
|
||||||
print(resp.json())
|
|
||||||
```
|
|
||||||
|
|
||||||
## 从 requests 迁移
|
|
||||||
|
|
||||||
如果已有 `requests` 代码,迁移只需两步:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# ── 迁移前 ──
|
|
||||||
import requests
|
|
||||||
s = requests.Session()
|
|
||||||
s.proxies = {"https": "http://proxy:8080"}
|
|
||||||
resp = s.get("https://example.com/api")
|
|
||||||
|
|
||||||
# ── 迁移后 ──
|
|
||||||
import mipu_requests
|
|
||||||
s = mipu_requests.session(
|
|
||||||
base_url="https://api-eu.mipuyun.com",
|
|
||||||
client_key="<YOUR_CLIENT_KEY>",
|
|
||||||
client_secret="<YOUR_CLIENT_SECRET>",
|
|
||||||
agent="JQ",
|
|
||||||
)
|
|
||||||
s.proxies = "res_mipu_xxx"
|
|
||||||
resp = s.get("https://example.com/api")
|
|
||||||
```
|
|
||||||
|
|
||||||
`.get()`、`.post()`、`.json()`、`.raise_for_status()` 等方法完全兼容,其余代码无需改动。
|
|
||||||
275
plugins/mipu-api/skills/mipu-api/docs/03-06_unlocker.md
Normal file
275
plugins/mipu-api/skills/mipu-api/docs/03-06_unlocker.md
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
<!-- mipuyun-api-doc: unlocker -->
|
||||||
|
# 解锁器 (Unlocker)
|
||||||
|
|
||||||
|
解锁器是米普云的核心代理服务,通过米普 API 代理发送 HTTP 请求到目标网站。目标网站看到的是米普的 IP 和会话,而非你的真实信息。
|
||||||
|
|
||||||
|
## 安装 SDK
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install mipu-requests
|
||||||
|
```
|
||||||
|
|
||||||
|
升级到最新版本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install --upgrade mipu-requests
|
||||||
|
```
|
||||||
|
|
||||||
|
查看当前版本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip show mipu-requests
|
||||||
|
```
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
```python
|
||||||
|
import mipu_requests
|
||||||
|
|
||||||
|
s = mipu_requests.session(
|
||||||
|
base_url="https://api-eu.mipuyun.com",
|
||||||
|
client_key="<YOUR_CLIENT_KEY>",
|
||||||
|
client_secret="<YOUR_CLIENT_SECRET>",
|
||||||
|
agent="JQ",
|
||||||
|
)
|
||||||
|
s.proxies = "res_mipu_xxx"
|
||||||
|
|
||||||
|
# 发送请求(SDK 自动处理异步轮询、会话管理)
|
||||||
|
resp = s.get("https://www.example.com/page",
|
||||||
|
headers={"user-agent": "Mozilla/5.0"})
|
||||||
|
resp.raise_for_status()
|
||||||
|
print(resp.text)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 从 requests 迁移
|
||||||
|
|
||||||
|
只需两步:
|
||||||
|
|
||||||
|
1. `import requests` → `import mipu_requests`
|
||||||
|
2. 构造时传入凭据,`proxies` 改为字符串
|
||||||
|
|
||||||
|
```python
|
||||||
|
# ── 迁移前 ──
|
||||||
|
import requests
|
||||||
|
s = requests.Session()
|
||||||
|
s.proxies = {"https": "http://proxy:8080"}
|
||||||
|
resp = s.get("https://example.com/api")
|
||||||
|
|
||||||
|
# ── 迁移后 ──
|
||||||
|
import mipu_requests
|
||||||
|
s = mipu_requests.session(
|
||||||
|
base_url="https://api-eu.mipuyun.com",
|
||||||
|
client_key="<YOUR_CLIENT_KEY>",
|
||||||
|
client_secret="<YOUR_CLIENT_SECRET>",
|
||||||
|
agent="JQ",
|
||||||
|
)
|
||||||
|
s.proxies = "res_mipu_xxx"
|
||||||
|
resp = s.get("https://example.com/api")
|
||||||
|
```
|
||||||
|
|
||||||
|
`.get()`、`.post()`、`.json()`、`.raise_for_status()` 等方法完全兼容,其余代码无需改动。
|
||||||
|
|
||||||
|
## 请求方法
|
||||||
|
|
||||||
|
```python
|
||||||
|
resp = s.get(url, params={"key": "value"}, headers={...})
|
||||||
|
resp = s.post(url, data={"key": "value"}, headers={...})
|
||||||
|
resp = s.post(url, json={"key": "value"}, headers={...})
|
||||||
|
resp = s.put(url, data=body, headers={...})
|
||||||
|
resp = s.delete(url, headers={...})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Agent 模式 vs Request 模式
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Agent 模式 — 通过 Agent 代理,维持登录态和会话(默认)
|
||||||
|
s = mipu_requests.session(..., agent="JQ")
|
||||||
|
|
||||||
|
# Request 模式 — 直接代理,无需 Agent
|
||||||
|
s = mipu_requests.session(..., mode="request")
|
||||||
|
```
|
||||||
|
|
||||||
|
## 异步模式
|
||||||
|
|
||||||
|
SDK 默认启用异步模式,自动处理提交和轮询:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 默认异步(推荐)
|
||||||
|
s = mipu_requests.session(..., async_mode=True)
|
||||||
|
|
||||||
|
# 关闭异步
|
||||||
|
s = mipu_requests.session(..., async_mode=False)
|
||||||
|
|
||||||
|
# 自定义轮询参数
|
||||||
|
s = mipu_requests.session(
|
||||||
|
...,
|
||||||
|
poll_interval=3, # 轮询间隔(秒)
|
||||||
|
poll_max=20, # 最大轮询次数
|
||||||
|
submit_timeout=60, # 提交超时(秒)
|
||||||
|
poll_timeout=(5, 30), # 轮询超时 (connect, read)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 会话管理
|
||||||
|
|
||||||
|
SDK 自动管理 sessionId,无需手动传递:
|
||||||
|
|
||||||
|
```python
|
||||||
|
s = mipu_requests.session(...)
|
||||||
|
|
||||||
|
# 第 1 次请求 — SDK 自动获取 sessionId
|
||||||
|
resp1 = s.get("https://example.com/login")
|
||||||
|
|
||||||
|
# 第 2 次请求 — SDK 自动传入 sessionId,保持会话
|
||||||
|
resp2 = s.get("https://example.com/dashboard")
|
||||||
|
```
|
||||||
|
|
||||||
|
## 错误处理
|
||||||
|
|
||||||
|
```python
|
||||||
|
import mipu_requests
|
||||||
|
|
||||||
|
try:
|
||||||
|
resp = s.get("https://example.com/api")
|
||||||
|
resp.raise_for_status()
|
||||||
|
except mipu_requests.HTTPError as e:
|
||||||
|
print(f"目标网站错误: {e.response.status_code}")
|
||||||
|
except mipu_requests.APIError as e:
|
||||||
|
# 米普 API 返回非零 code,如反爬失败、鉴权失败等
|
||||||
|
print(f"API 错误: {e}")
|
||||||
|
except mipu_requests.PollTimeoutError as e:
|
||||||
|
print(f"异步轮询超时: {e}")
|
||||||
|
except mipu_requests.RequestException as e:
|
||||||
|
print(f"请求异常: {e}")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Response 对象
|
||||||
|
|
||||||
|
与 `requests.Response` 完全兼容:
|
||||||
|
|
||||||
|
```python
|
||||||
|
resp.status_code # int 目标网站 HTTP 状态码
|
||||||
|
resp.text # str 响应体文本
|
||||||
|
resp.content # bytes 响应体字节
|
||||||
|
resp.headers # dict 响应头
|
||||||
|
resp.ok # bool status_code 在 200-399
|
||||||
|
resp.url # str 请求 URL
|
||||||
|
resp.json() # dict 解析 JSON
|
||||||
|
resp.raise_for_status() # >=400 抛异常
|
||||||
|
resp.session_id # str 当前会话 ID
|
||||||
|
```
|
||||||
|
|
||||||
|
## 完整流程示例
|
||||||
|
|
||||||
|
```python
|
||||||
|
import mipu_requests
|
||||||
|
|
||||||
|
with mipu_requests.session(
|
||||||
|
base_url="https://api-eu.mipuyun.com",
|
||||||
|
client_key="<YOUR_CLIENT_KEY>",
|
||||||
|
client_secret="<YOUR_CLIENT_SECRET>",
|
||||||
|
agent="JQ",
|
||||||
|
) as s:
|
||||||
|
s.proxies = "res_mipu_xxx"
|
||||||
|
|
||||||
|
# 访问首页
|
||||||
|
resp = s.get("https://www.example.com/home")
|
||||||
|
resp.raise_for_status()
|
||||||
|
|
||||||
|
# 提交表单(sessionId 自动传递)
|
||||||
|
resp = s.post("https://www.example.com/submit",
|
||||||
|
data={"field": "value"},
|
||||||
|
headers={"content-type": "application/x-www-form-urlencoded"})
|
||||||
|
resp.raise_for_status()
|
||||||
|
print(resp.json())
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 原始 API 参考
|
||||||
|
|
||||||
|
以下为直接调用解锁器 API 的参考,推荐优先使用上方 SDK。
|
||||||
|
|
||||||
|
### 认证
|
||||||
|
|
||||||
|
所有请求必须包含以下 Header:
|
||||||
|
|
||||||
|
| 参数 | 值 | 说明 |
|
||||||
|
|------|-----|------|
|
||||||
|
| Content-Type | application/json | 固定值 |
|
||||||
|
| client-key | (由米普云提供) | 客户端 key |
|
||||||
|
| client-secret | (由米普云提供) | 客户端 secret |
|
||||||
|
|
||||||
|
### Agent 模式
|
||||||
|
|
||||||
|
| 项目 | 值 |
|
||||||
|
|------|-----|
|
||||||
|
| URL | `POST https://{endpoint}/unlocker/agent` |
|
||||||
|
|
||||||
|
**请求体:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"url": "https://www.example.com/page",
|
||||||
|
"method": "GET",
|
||||||
|
"agent": "JQ",
|
||||||
|
"proxy": "res_mipu_xxx",
|
||||||
|
"async": true,
|
||||||
|
"headers": {"user-agent": "Mozilla/5.0"},
|
||||||
|
"sessionId": ""
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| 字段 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| url | string | 是 | 目标 URL |
|
||||||
|
| method | string | 是 | HTTP 方法 |
|
||||||
|
| agent | string | 是 | Agent 编码 |
|
||||||
|
| proxy | string | 是 | 代理资源标识 |
|
||||||
|
| async | boolean | 否 | 异步模式,默认 true |
|
||||||
|
| headers | object | 否 | 传递给目标网站的请求头 |
|
||||||
|
| body | string | 否 | 请求体 |
|
||||||
|
| contentType | string | 否 | Content-Type 覆盖 |
|
||||||
|
| sessionId | string | 否 | 会话 ID |
|
||||||
|
|
||||||
|
### Request 模式
|
||||||
|
|
||||||
|
| 项目 | 值 |
|
||||||
|
|------|-----|
|
||||||
|
| URL | `POST https://{endpoint}/unlocker/request` |
|
||||||
|
|
||||||
|
请求体与 Agent 模式相同,但不需要 `agent` 字段。
|
||||||
|
|
||||||
|
### 同步响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 0,
|
||||||
|
"sessionId": "abc123",
|
||||||
|
"statusCode": 200,
|
||||||
|
"responseBody": "<html>...</html>",
|
||||||
|
"responseHeaders": {"content-type": "text/html"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 异步响应
|
||||||
|
|
||||||
|
首次提交返回 `{"code": 202, "agentRequestId": "req_xxx"}`,通过轮询接口获取结果:
|
||||||
|
|
||||||
|
| 项目 | 值 |
|
||||||
|
|------|-----|
|
||||||
|
| URL | `GET https://{endpoint}/async/query/{agentRequestId}` |
|
||||||
|
|
||||||
|
### 错误码
|
||||||
|
|
||||||
|
| 码 | 含义 | 处理建议 |
|
||||||
|
|----|------|----------|
|
||||||
|
| 0 | 成功 | — |
|
||||||
|
| 100 | 鉴权失败 | 检查 client-key 和 client-secret |
|
||||||
|
| 102 | 超过限流 | 降低请求频率,稍后重试 |
|
||||||
|
| 103 | Proxy 错误 | 检查 proxy 标识是否正确 |
|
||||||
|
| 104 | Agent 不存在 | 检查 agent 编码,新创建的 Agent 需等待 5 分钟生效 |
|
||||||
|
| 202 | 异步处理中 | 继续轮询 |
|
||||||
|
| 403 | 反爬拦截 | 目标网站触发了反爬机制 |
|
||||||
|
|
||||||
|
更多错误码请查阅 `10_error-codes.md`。
|
||||||
Reference in New Issue
Block a user