API — 端口池

打开并管理端口池——从代理列表批量打开的端口,用于大规模并发任务——然后导出结果。

打开端口池

说明为保持向后兼容,端口池端点位于 /scraper 路径下——它与控制面板中的 + 端口池 按钮是同一功能。
POST/api/v1/scraper/tasks需要鉴权

从代理列表打开一个端口池。

参数类型必填说明
namestring是端口池名称。
sourceobject是代理列表的来源:kind 为 "file"、"url" 或 "inline";location 为路径或链接;"inline" 时由 content 直接承载列表。可选的 refresh_interval 用于重新读取来源,其值为纳秒整数:10 分钟为 600000000000,1 分钟为 60000000000,30 秒为 30000000000。默认 10 分钟;小于 30 秒的值会被静默提升为 30 秒,且响应中不会给出任何提示——直接填 600 表示 600 纳秒,来源(包括外部 URL)将每 30 秒被重新读取一次。default_scheme 适用于不带协议的 host:port 条目(默认 socks5)。
targetint是端口池需要开启的端口数量。
port_loint否端口池可使用的本地端口范围下限。
port_hiint否端口范围上限。
protocolstring否池中端口的监听协议:"socks5"(默认)或 "http"。
up_policyobject否端口更换出口代理的频率。mode 可为 "requests"(每 n 个连接)、"minutes"(每 n 分钟)或 "on_error"(保持代理不变,直到客户端收到错误响应)。默认每个请求更换一次。🔴 当 js_solver: true 时该频率不生效:up_policy 与 fp_policy 都会被强制改为“无频率”。端口在第一个连接上取得出口代理,并连同身份一直保持到端口关闭;出口只在连接出错后被临时更换(此时身份不变)。唯一的例外是 mode: on_error,它不受该强制影响,按上文所述工作。
fp_policyobject否端口更换身份的频率,结构与上述三种模式相同。默认每 10 个请求更换一次。🔴 当 js_solver: true 时同样被强制,参见上方 up_policy:端口身份完全不按频率轮换——on_error 模式除外。
devicestring否池内身份使用的浏览器类型,例如 "chrome"。可用组合见 GET /api/v1/scraper/device_matrix。
device_osstring否池内身份使用的操作系统,例如 "windows"。
profile_sourcestring否身份来源:"auto" 表示实时生成,"db" 表示取自精选数据库。
auto_uabool否按请求的 User-Agent 选择身份,而非使用端口池设置。
spoof_headersbool否将外发请求头改写为与当前浏览器一致。建议采集场景开启,默认已开启。
connect_timeout_secondsint否池中每个端口单次连接尝试的上限(秒)。默认 5。
request_timeout_secondsint否池中每个端口的静默预算(秒):包含重试的连接阶段,以及随后等待首字节的时间。默认 30,设为 0 则取消限制。
idle_timeout_secint否池中端口连接的空闲超时(秒):若在此时长内没有字节传输,连接将被关闭。默认 60。请勿与 idle_seconds 混淆,后者关闭的是端口本身。读取由早期版本保存的端口池时,仍接受旧名称 request_timeout_sec。
idle_secondsint否端口存活时长(秒)。端口池默认保持其端口开启(0)。
示例 (curl)
curl -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"tiktok-pool","target":100,"port_lo":20000,"port_hi":30000,
        "protocol":"socks5",
        "source":{"kind":"file","location":"C:/proxies.txt"},
        "up_policy":{"mode":"requests","n":1},
        "fp_policy":{"mode":"requests","n":10},
        "connect_timeout_seconds":5,"request_timeout_seconds":30}' \
  http://127.0.0.1:8891/api/v1/scraper/tasks
响应
{
  "id": "pool-7f3a",
  "export_token": "3b91c0d4e5f6",
  "warnings": null
}

🔴 id 与 export_token 来自此处:id 用于 /scraper/tasks/{id}/…,export_token 用于导出地址 /export/{token}/proxies.txt。除 GET /api/v1/scraper/tasks 外没有其他地方可以看到它们。warnings 只包含一条提示——当实际打开的端口少于请求的 target 时的“opened N of M ports (range LO-HI too small or ports busy)”;若全部打开,该字段返回 null。它不会报告代理源的任何情况:既不会给出未能解析的条目数,也不会告知源根本没有读取成功(URL 返回 404 或超时、文件缺失)。此时池仍会启动——出口列表为空——并返回 200,只能通过流量失败才能察觉。请事先使用单独的 POST /api/v1/scraper/probe 检查源:它会返回 total(可用条目数)与 bad(损坏条目数)。

在 Lite 套餐上返回 403 “the scraper port pool requires a Pro license (single-thread Lite cannot open a port pool)”;若该构建未接入端口池,返回 503 “scraper manager not configured”;若配置不自洽(port_lo 大于 port_hi、target 小于 1,或 profile_source、up_policy.mode、fp_policy.mode、vdns_mode 取值未知,或 device 与 device_os 未知/互不兼容),返回 400 并附说明。🔴 端口区间不足以容纳 target 并不是拒绝:端口池会打开能放下的端口——若全部被占用则一个也不打开——仍返回 200,并在 warnings 中给出形如 “opened 11 of 100 ports (range 20000-20010 too small or ports busy)” 的说明。因此不要只看状态码,请检查 warnings。

有两个默认值是在创建时应用的,而不是保存在配置里:未设置时 protocol 变为 socks5(以便 UDP 与 HTTP/3 可用),vdns_mode 变为 forced——目标名称在出口侧解析,不会泄漏到您所在网络的 DNS。显式设置的 "off" 仍表示关闭。

说明on_error 模式会在出口代理与身份可用期间一直保持不变,一旦客户端收到 4xx 或 5xx 响应即进行更换。2xx 与 3xx 视为成功,因此重定向和缓存响应不会触发更换。判定依据是您的客户端实际收到的状态码:若请求遇到防护并被成功处理、客户端最终收到 200,则不算错误。同一个失效代理引发的一批错误只消耗一次更换,而非每个请求一次。该模式仅适用于端口池,且要求端口能够解析流量:以 tls_passthrough 开启的端口不存在可观测的 HTTP 状态码。

池端口的高级设置

端口池自行打开其端口,因此未传达到它的设置会保持默认值——而表单看上去却像已生效。下列字段会应用到池中的每个端口。

字段类型作用
js_solverbool在每个池端口上启用 Challenge Breaker:遇到验证的请求会转入解题池。需要拆解 TLS——与 tls_passthrough 不兼容。🔴 它会让端口变为固定:池的 up_policy 与 fp_policy 不再按频率生效——每个端口在其整个生命周期内只用一个出口 IP 和一个身份(例外:on_error 模式,以及连接出错后的临时换出口)。这是有意为之:破解验证所获得的会话与“出口 + 指纹”这一组合绑定,会话进行中更换其中任何一项都会使其作废。出口的多样性来自池中端口的数量,而不是轮换频率——请提高 target 并扩大端口范围。该替换在 API 上看不出来:GET /api/v1/scraper/tasks/{id}/config 仍会返回您原本提交的 up_policy 与 fp_policy,因为强制只作用于运行中的端口,而不改动已保存的配置。
captcha_actionstring遇到验证码(而非无人值守型验证)时的处理方式:rotate_retry(默认)更换身份并重试;return_to_script 把该验证交回您的代码。
captcha_max_attemptsint在 rotate_retry 下最多以新身份重试多少次。默认 3 次。
keep_sessionsbool每个池端口维护自己的按域名 Cookie 罐:吸收 Set-Cookie、注入 Cookie 并跟随重定向。与 js_solver 无关。
cache_modestring池端口上的缓存模式:normal、hard、hard-media 或 hard-autowarm。
cache_ignore_no_cachebool忽略 no-cache 头进行缓存。
vdns_modestring虚拟 DNS:off、on_leak 或 forced。🔴 对于新建的池,若未设置该字段则为 forced——目标名称在出口侧解析,不会泄漏到您所在网络的 DNS。
leak_guardstring池端口启动前的泄漏检查:off、warn 或 enforce。
force_ipv4bool仅通过 IPv4 出口。
tls_passthroughboolTLS 原样透传。此时池端口上的缓存、日志与 Challenge Breaker 都不起作用:内容不被读取。
tls_mirrorbool对外重放客户端自身的已采集指纹,而不是配置文件中的指纹。
h2_spoofingbool把 HTTP/2 设置伪装为浏览器配置文件的形态。
spoof_user_agentbool伪装 User-Agent。关闭时逐字节转发您的客户端自身的请求头。
enable_http3bool当站点提供 h3 时改用 HTTP/3 重新发起连接。
upstream_tls_insecurebool对 https 代理关闭证书校验。仅适用于使用自签名证书的自有代理。
allow_mitm_upstreambool允许自行拆解 TLS 的出口。默认禁止:此类出口会抹掉指纹。
max_concurrentint每个池端口的并发请求上限;0 表示不限。
sem_timeoutint请求在该上限内等待空位的秒数。
skip_retrybool网络错误后不重试请求。
retry_delay_msint重试之间的间隔(毫秒)。
注意js_solver 与 keep_sessions 正是构建端口池最常见的原因:突破验证,以及为每个端口维护独立会话。前者需要拆解 TLS,因此无法与 tls_passthrough 同时使用。

列出与停止端口池

GET/api/v1/scraper/tasks需要鉴权

所有端口池的快照:已打开多少端口、具体是哪些端口,以及它们所在的端口范围。

示例 (curl)
curl -H "X-API-Key: YOUR_API_KEY" \
  http://127.0.0.1:8891/api/v1/scraper/tasks
响应
[
  {
    "id": "pool-7f3a",
    "name": "catalogue-pool",
    "target": 100,
    "ports_up": 98,
    "ports": [20000, 20001, 20002],
    "export_token": "3b91c0d4e5f6",
    "port_lo": 20000,
    "port_hi": 30000
  }
]
  • 空数组表示当前没有任何端口池——这不是错误。若该构建未接入端口池,返回 503 “scraper manager not configured”。
  • 响应中不含源代理数量,也不含轮换状态:源中有多少条目由 POST /api/v1/scraper/probe 给出(total 字段),配置了何种轮换由 GET /api/v1/scraper/tasks/{id}/config 给出(up_policy 与 fp_policy)。ports_up 是已开启端口的数量,ports 则是这些端口的编号。
DELETE/api/v1/scraper/tasks/{id}需要鉴权

停止端口池并关闭其全部端口。经由它们的流量会被切断。

示例 (curl)
curl -X DELETE -H "X-API-Key: YOUR_API_KEY" \
  http://127.0.0.1:8891/api/v1/scraper/tasks/pool-7f3a
响应
{
  "ok": true
}
  • 若不存在该 id 的端口池,返回 404 并附管理器文本。
POST/api/v1/scraper/tasks/{id}/test需要鉴权

在端口池的某个运行端口上执行完整的端口测试——与 POST /api/v1/port/{port}/test 相同——并返回被测试的端口。

示例 (curl)
curl -X POST -H "X-API-Key: YOUR_API_KEY" \
  http://127.0.0.1:8891/api/v1/scraper/tasks/pool-7f3a/test
响应
{
  "port": 20134,
  "report": { "leak": { "…": "…" }, "fingerprint": { "match": true },
                "udp": { "supported": true }, "ok": true }
}
  • 在端口池尚未启动任何端口时返回 409 “scraper task has no open ports yet”;端口已不再工作时返回 409 “scraper task ports are not live”。若端口池不存在,返回 404。
GET/api/v1/scraper/tasks/{id}/config需要鉴权

以 POST /api/v1/scraper/tasks 所接受的完全相同形态返回端口池的已保存配置:修改的方式是先停止再重新启动。

示例 (curl)
curl -H "X-API-Key: YOUR_API_KEY" \
  http://127.0.0.1:8891/api/v1/scraper/tasks/pool-7f3a/config
响应
{
  "id": "pool-7f3a",
  "name": "catalogue-pool",
  "port_lo": 20000,
  "port_hi": 30000,
  "target": 100,
  "protocol": "socks5",
  "source": { "kind": "file", "location": "C:/proxies.txt" },
  "up_policy": { "mode": "requests", "n": 1 },
  "fp_policy": { "mode": "requests", "n": 10 },
  "vdns_mode": "forced",
  "export_token": "3b91c0d4e5f6"
}
  • 404 “task not found”。该配置还包含打开表中未列出的高级字段:cache_mode、leak_guard、js_solver、keep_sessions、captcha_action 以及端口的三个超时。
GET/api/v1/scraper/device_matrix需要鉴权

列出可用于构建端口池的浏览器与操作系统组合。

示例 (curl)
curl -H "X-API-Key: YOUR_API_KEY" \
  http://127.0.0.1:8891/api/v1/scraper/device_matrix
响应
{
  "chrome": ["windows", "macos", "linux", "android", "ios"],
  "edge": ["windows", "macos", "linux", "android", "ios"],
  "firefox": ["windows", "macos", "linux", "android", "ios"],
  "safari": ["macos", "ios"]
}
  • 此处的取值用于打开端口池时的 device 与 device_os 字段。
  • 唯一不可能的组合是非 Apple 设备上的 Safari。该表描述的是显式指定时校验器所接受的范围;device: random 取自更窄的集合——Chrome、Firefox、Edge 不含 iOS,Firefox、Edge 不含 Android——这些组合只能显式指定。
POST/api/v1/scraper/probe需要鉴权

下载并解析代理源,但不启动端口池:可用条目数、损坏条目数、出现了哪些协议,以及供您自行测试连通性的随机样本。

参数类型必填说明
sourceobject是与打开端口池时相同的源对象:kind(file、url 或 inline)、location 与 content。
请求体
{ "source": { "kind": "url", "location": "https://example.com/proxies.txt" } }
示例 (curl)
curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"source":{"kind":"url","location":"https://example.com/proxies.txt"}}' \
  http://127.0.0.1:8891/api/v1/scraper/probe
响应
{
  "total": 13045,
  "bad": 210,
  "by_scheme": { "socks5": 12835, "http": 210 },
  "sample": ["socks5://203.0.113.10:1080", "socks5://203.0.113.11:1080"]
}
  • 若源无法下载或解析,返回 400 并附说明。请求体上限为 32 MiB——即整份粘贴列表的大小;探测上限为 35 秒。
  • 许可未激活时返回 403:与其他出口检查一样,该接口位于许可之后。

导出结果

GET/export/{token}/proxies.txt无需鉴权

将端口池的端口下载为纯文本代理列表。访问权限由 URL 中的令牌授予,因此无需 API 密钥。

示例 (curl)
curl http://127.0.0.1:8891/export/TASK_TOKEN/proxies.txt