站点定义指南
格式
每个站点一个 YAML 文件(backend/definitions/<id>.yaml),启动时自动加载。
最简定义(5 行,选择器自动填充)
id: ourbits
name: 我堡
schema: nexusphp
urls:
- https://ourbits.clubadapter 在 Search/FetchUserInfo 前自动调用 EnsureDefaults(def):选择器为空时填入经好学源码校准的 NexusPHP 标准默认值。
完整自定义(覆盖默认值)
id: hxpt
name: 好学
schema: nexusphp
urls:
- https://www.hxpt.org
search_entry: torrents.php
search_param: search
selectors:
rows:
selector: "table.torrents tr"
fields:
title:
selector: 'a[href^="details.php"]:not([href*="#"])'
detail:
selector: 'a[href^="details.php"]:not([href*="#"])'
attr: href
download:
selector: 'a[href^="download.php"]'
attr: href
size:
selector: "td:nth-last-child(5)"
seeders:
selector: 'a[href*="#seeders"]'
leechers:
selector: 'a[href*="#leechers"]'
user_info:
path: usercp.php
fields:
level:
selector: 'td.rowhead:contains("等级") + td'
vip_levels: ["APP专属VIP"]
no_login:
url_pattern: ["login.php", "takelogin.php"]
content: ["登录"]ElementQuery 字段
| 字段 | 说明 |
|---|---|
selector | CSS 选择器(goquery:支持 :contains("中文") / + td / :not([href*="#"]) / nth-last-child) |
attr | 空/text 取文本;href/src 取属性 |
remove | 提取前移除的子选择器 |
filters | 后处理链:regexp/replace/trim/lower/upper/parse_number |
默认选择器(NexusPHP 标准,经好学源码校准)
| 字段 | 选择器 | 锚点依据 |
|---|---|---|
| title | a[href^="details.php"]:not([href*="#"]) | 标题链接无 #(种子/下载者带 #) |
| download | a[href^="download.php"] | 操作列 |
| seeders | a[href*="#seeders"] | |
| leechers | a[href*="#leechers"] | |
| completed | a[href^="viewsnatches.php"] | |
| size | td:nth-last-child(5) | 右数第 5 列(操作/完成/下载者/种子/大小) |
新增站点步骤
- 复制模板或写 5 行 YAML(id/name/urls)
- 重启后端(或热加载)
- Web UI「站点」→ 添加站点 → 选定义 → 输入 cookie
- 连接测试 → 确认登录态
- 搜索 → 确认选择器命中
- 选择器不对 → 用
/api/v1/sites/inspect(POST url+cookie+selectors)在线试错,然后覆盖 YAML
校准诊断端点
POST /api/v1/sites/inspect
{
"url": "https://www.hxpt.org/usercp.php",
"cookie": "...",
"fields": {
"level": {"selector": "td.rowhead:contains(\"等级\") + td"}
}
}
→ 返回每个选择器命中的文本 + 是否登录态 + 页面前 2KB已有站点定义(306 个,以 backend/definitions/ 目录实际为准)
好学(hxpt) / 财神(cspt) / 我堡(ourbits) / 天空(hdsky) / 家园(hdhome) / 时光(hdtime) / 春天(ssd) / 猫站(pterclub) / 彩虹岛(ptchdbits) / 好大(hdarea) / 梓喵(azusa) / 末日(agsvpt) / 大青虫(cyanbug) / 蟹黄堡(crabpt) / 红豆饭(hdfans) / 朋友(keepfrds) / 聆音(soulvoice) / 铂金家(pthome) / 拾刻(shike) / 馒头(mteam) + 模板
JSON API 站点(schema: mteam)
馒头(M-Team)不走 HTML 抓取,而走 api.m-team.cc JSON API + x-api-key 鉴权,因此定义无需 selectors/userinfo/no_login 段——数据由 mteam 适配器从 JSON 端点解析:
id: mteam
name: 馒头
schema: mteam
urls:
- https://api.m-team.cc
extra_param:
mode: normal # normal(综合) | movie | tvshow- 凭据走 api_key(非 cookie):登录 M-Team → 控制台 → 实验室 → 存储令牌 → 粘贴到站点
api_key字段(AES 加密存APIKeyEnc) - chain 按 schema 分发凭据:mteam 站传 API key 作
x-api-key头,其余站传 cookie - 搜索
POST /api/torrent/search,资料POST /api/member/profile
JSON API 站点(schema: fluxtorrent,FluxTorrent 建站系统)
FluxTorrent(Rust + Next.js 通用 PT 建站系统)页面为 Next.js RSC 渲染、无 NexusPHP 形状 HTML,抓取全部走其 /api/v1/compat JSON 兼容层,由 backend/internal/site/schemas/fluxtorrent.go 代码解析。所有 FluxTorrent 站点共用同一模板(API 口径由建站系统统一保证),添加站点时无需克隆 YAML:
- 搜索:
GET /api/v1/compat/nexusphp/torrents.json?keyword=&page=&pagesize=50(NP 字段口径;promotion 映射为免费/半价/双倍双因子) - 用户信息:
GET /api/v1/plugins/ptppUserInfo(PT-Plugin-Plus 聚合端点) - 下载:
GET /api/v1/compat/nexusphp/download.php?id={id}&passkey={passkey}(与 NexusPHP 同形,走 chain 通用 passkey 补全)
用户接入三步
- 站点网页端「我的 → API Token」签发一枚 Token(
fxo_开头,180 天有效期,可续期) - PTPatronus「添加站点」:定义选 FluxTorrent,地址填站点域名,API Key 粘贴 Token
- 首次用户信息抓取会自动从站点获取 passkey 并加密回写(无需手填;也可添加时手填兜底)
注意事项
- 鉴权头为
Authorization: Token fxo_...(前缀是Token不是Bearer);cookie 对 FluxTorrent 兼容层不可用 - Token 默认限流 60 次/分钟(响应带
X-RateLimit-*,429 自动退避重试);下载 30 次/分钟/passkey - Token 有效期 180 天,过期前请在站点网页端续期后更新站点 API Key
- passkey 属敏感凭据,出现在下载 URL 中,日志侧已按敏感信息处理