| name | drpy-node-source-create |
| description | 适用于 drpy-node 新建 DS 源。用户提到"新建源""写个 drpy 源""分析这个站做 DS 源""创建新规则""从零开始做源""写源""做源""建源""生成源""爬虫源"时使用。专注站点分析、模板判断、规则生成与初步验证;已有源修复、播放专项和仓库上传应分流到对应 skill。 |
⚠️ 已归档(2026-07-17):本 skill 已被 drpy-node-coder 取代。coder 融合了 4 个旧 skill(workflow/create/play-debug/repo-upload)的全部工作流,并自带 scripts/cli.js CLI 替代 drpy-node-mcp 服务——一个 skill、无需安装 MCP。本文件保留仅供历史参考,新工作请直接用 drpy-node-coder。
drpy-node Source Create
快速索引
| 用户意图/站点特征 | 直接入口 | 成功判据 |
|---|
| 标准 CMS / 模板命中 | 路线 A:继承模板站 | 最小覆盖后 home/category/detail/search/play 可串联 |
| HTML 有内容但接口带签名 | 路线 B2:非模板签名接口站 | 一级/搜索使用真实签名请求,二级优先字典 |
| SPA / body 近空 / JSON API | 路线 C:纯 API 驱动 SPA 站 | 全 async,this.input/detailUrl/searchUrl 正确 |
| 漫画/小说/音乐/网盘 | 特殊内容类型 / 网盘补充清单 | lazy 返回对应特殊协议或按 flag 分派 |
执行契约
- 输入:用户给的 URL/站名/目标内容类型;若缺源名,先自行推导候选源名。
- 输出:
spider/js/[源名].js 最小可用源 + 接口验证结果 + 后续分流建议。
- 停手:已有源修复、播放专项、仓库上传分别交给 workflow/play-debug/repo-upload。
模式闸门:先判断是否允许写入
| 用户模式 | 允许动作 | 禁止动作 |
|---|
| 只读 / 规划 / dry-run / 不要改文件 | 读取、诊断、给建源方案、列验证计划 | drpy_write_file、drpy_edit_file、仓库上传/改标签 |
| 需要确认后再改 | 读取、诊断、输出方案 | 未确认前禁止写入源文件 |
| 明确要求执行 | 按本 skill 流程建源与验证 | 不跳过高风险确认点和最小验证链 |
| 自主全流程 | alive check、建源、L1/L2/L3、低风险最小修复、L3=100 后 handoff | 坏站硬写、未达 100 冒充最终版、仓库动作越界 |
如果用户说“只给方案 / 不要写文件 / dry-run”,本 skill 只能输出站型判断、源名候选、拟写字段和验证计划。
Reference Map
| 任务 | 首读 reference |
|---|
| 新建源总清单 | references/references-create-checklist.md |
| 模板继承 / 最小覆盖 | references/references-template-system.md、references/references-inherited-template-minimal-override-site.md |
| async 函数通用陷阱 | references/references-async-function-patterns.md、references/references-api-functions.md |
| 纯 API / SPA 站 | references/references-pure-api-async-site.md |
| 非模板签名接口站 | references/references-non-template-signed-api-site.md |
| 二级字典 / 多集 | references/references-detail-dict-and-multiep.md |
| 搜索策略 | references/references-old-encoding-search-site.md |
| 特殊内容 | references/references-special-content.md |
调度优先级
当本地环境已安装本 Skill 时:
- 本 Skill 的工作流优先级 高于 drpy-node MCP 的通用 prompts
- MCP 通用 prompt 仅作为无本地 Skill 时的兜底说明
- 如果用户只提供网址、没有提供源名,必须先自行分析站点并推导合理源名
强约束
如果已经命中本 Skill 的使用场景,不要退回到通用 MCP 基础流程充当主流程。
30 秒最短建源路线(执行入口)
Step 0:URL 可用性预检
只要用户给 URL,就先判断站点是否活着,再决定是否写源。自主全流程模式下尤其不能跳过此步。
优先工具:
fetch_spider_url(url):确认连接、状态码、响应体、headers,识别 403/5xx/空响应。
guess_spider_template(url):判断是否命中模板,辅助识别 CMS 站。
analyze_website_structure(url):看页面是 HTML 直出、SPA 空壳还是错误页。
- 必要时用浏览器网络证据确认 SPA/API 请求;若仍需登录、验证码或动态凭据,停止。
停手条件:
| blocker_type | 表现 | 动作 |
|---|
broken_site | DNS/连接失败、超时、持续 5xx、错误页、空壳且无可复现 API | 不写源,回报证据 |
hard_anti_bot | 验证码、强 headless 检测、DRM/WASM 等 | 不绕过,回报需授权/人工处理 |
missing_credentials | 登录、Cookie、Authorization、Token 缺失 | 等用户提供凭据 |
可用站点才进入 Step 1。自主模式下,Step 0 通过后可连续建源、验证和低风险修复;普通模式仍按后续检查点确认。
evaluate-to-100 循环
当用户要求“修到100 / 满分后上传 / 自动完成”时,evaluate_spider_source 是必跑项,不是可选项。
循环规则:
L3 evaluate → 按丢分接口拆 L2 → 最小修复 → 复测该接口 → 重新 evaluate
- home/category 丢分:优先查
class_parse、url、double、一级 selector/API。
- detail 丢分:必须使用一级真实
vod_id,先修 detailUrl/二级字典/lists。
- search 丢分:先换高频宽匹配词,再判断
searchUrl、搜索 DOM/API。
- play 丢分:detail 稳定后带真实
ids/play_url/flag 转 drpy-node-play-debug。
- 达到 L3=100、A 档、
upload_preauthorized=true,且 tags、is_public、auto_replace 策略和目标对象明确时,返回 repo-upload handoff packet;缺任一项则返回 ambiguous_upload 或交回 workflow 确认。
- 遇到
broken_site/hard_anti_bot/missing_credentials/high_risk_change/score_below_target 时停止并回报。
Step 1:定源名
用户没给源名 → 从站名/标题/域名推导稳定候选。
Step 2:分站型(路线选择速判)
先调用 guess_spider_template(url),按结果分派:
guess_spider_template 结果 | 页面源码特征 | 走路线 | 首选实现 |
|---|
| 命中(mx/mxpro/首图等) | CMS 模板站,页面完整 | A 模板继承 | 最小覆盖 host/url/searchUrl |
| 未命中 | 有完整 HTML 列表/详情 DOM | B1 静态 DOM | 字符串规则 + 二级字典 |
| 未命中 | HTML 外壳完整但列表/搜索数据来自签名接口 | B2 签名接口 | 一级/搜索 async,详情/推荐可按模板默认 |
| 未命中 | <body> 几乎为空,数据走 JSON API | C 纯 API | 全 async 函数 |
| 未命中 | 影视列表/详情结构但内容实为漫画/小说/音乐/网盘 | D 特殊内容 | 按内容类型选协议 |
| 未命中 | 静态请求 403 或需要登录/验证码 | 停手 | 向用户确认授权 |
助记:模板命中走 A,DOM 完整走 B1,签名接口走 B2,body 空走 C,非影视走 D,403 停手
工具辅助判断:
analyze_website_structure(url) → 看列表区域是空容器(SPA)还是直出 HTML(B1/B2)
fetch_spider_url(url) → 看原始响应和 headers,确认是否 403 或需要签名
- 签名接口站需确认:浏览器真实请求是 GET/POST,带 time/sign/token 与否,需要 Ajax headers 与否
Step 3:确认建源方案(写入前)
在正式写入 spider/js/[源名].js 前,先向用户呈现:
## 建源方案
- 源名:...
- 站型判断:路线 A / B / C / 特殊内容
- 证据:guess_spider_template / DOM / API / 浏览器抓包摘要
- 拟使用模式:模板继承 / 字符串规则 / async / 网盘型
- 源元数据:`@header` 的 title/类型/lang/searchable/filterable/quickSearch 与实际能力一致
- 最小验证链:home → category → detail → search → play
自主全流程模式下,Step 0 已通过且用户明确授权自动完成时,可直接写入最小源并继续 L1/L2/L3;普通模式必须得到用户确认后再写入。如果涉及登录态、复杂反爬、批量抓取或高风险重写,任何模式都必须先确认。源内 metadata 只描述运行时源身份,不等同于仓库 tags;上传标签交给 repo-upload 处理。
Step 4:保住最小可用链路
工具调用顺序:
1. get_spider_template() → 获取标准模板
2. drpy_write_file() → 保存到 spider/js/[源名].js
3. drpy_check_syntax(path) → 语法检查
4. validate_spider(path) → 结构检查
### 🛑 检查点:确认写入结果再继续验证
普通模式下,源文件已写入并通过语法/结构检查,向用户确认后再跑接口验证链;自主全流程模式下,此处只记录 L1 证据并继续跑 L2/L3:
```markdown
## 写入确认
- 文件:spider/js/[源名].js
- 语法检查:通过 / 未通过
- 结构检查:通过 / 未通过
- 源 metadata(title/类型/lang/searchable):与实际预期一致 / 需修正
- 拟验证链:home → category → detail → search → play
确认后继续 Step 5-10 验证链;自主全流程模式下自动继续。若语法或结构未通过,先做最小修复再继续。
- test_spider_interface(home) → 测试首页
- test_spider_interface(category, class_id) → 测试一级
- test_spider_interface(detail, ids) → 测试二级
- test_spider_interface(search, keyword) → 测试搜索
- test_spider_interface(play, play_url) → 测试播放
- evaluate_spider_source() → 全流程评估(自主/最终版/上传前必跑,普通初步验证可选)
**单接口调试工具:**
- `debug_spider_rule(rule, mode)` → 测试 CSS/Regex 选择器
- `fetch_spider_url(url)` → 测试 API 连通性和响应
- `extract_website_filter(url)` → 提取分类筛选条件
**筛选 filter 处理要点:**
1. 分类页有地区/年份/排序等筛选时,先调用 `extract_website_filter(url)`;筛选很长时用 `gzip: true` 压缩输出。
2. 生成结果应落到 rule 的 `filter` / `filter_def` / `filter_url`,不要把筛选硬编码进一级 async。
3. 验证筛选时用 `test_spider_interface(category, class_id, ext)`,`ext` 传工具生成的 base64 筛选参数。
4. 如果筛选导致列表为空,先测无筛选 category,再逐个筛选项定位错误。
### 工具参数示例(MCP 真实字段)
```text
test_spider_interface(source_name='源名', interface='category', class_id='1', ext='')
test_spider_interface(source_name='源名', interface='detail', ids='一级返回的真实 vod_id')
test_spider_interface(source_name='源名', interface='search', keyword='高频宽匹配词')
test_spider_interface(source_name='源名', interface='play', play_url='二级返回的真实播放地址', flag='线路名')
失败兜底与停手边界
| 失败点 | 不要做 | 正确动作 |
|---|
guess_spider_template 不确定 | 硬套最像的模板 | 用 analyze_website_structure + fetch_spider_url 判 A/B/C,必要时按 B/C 最小 async |
| 静态请求 403/空 body | 直接判站点不可做 | 用浏览器网络请求复现 headers/method/body;若仍需登录/验证码则停手说明 |
| 签名算法找不到 | 搬整段前端 bundle | 只定位生成 sign/token 的最小函数;找不到就输出阻塞点,不写死抓包值 |
fetch_spider_url 能通但源内不通 | 反复改 selector | 对照 method、headers、body、this.input、searchUrl ** 是否一致 |
| 验证中途失败 | 继续补其它接口 | 停在第一个断点,用真实上游返回值复测后再继续 |
| 涉及登录态/验证码/强风控 | 绕过或批量尝试 | 向用户确认授权范围和可用凭据,未确认不继续 |
路线 A:继承模板站
当 guess_spider_template 命中内置模板时走此路线。
核心原则:模板内置优先,最小覆盖
能走模板内置就不要急着手写覆盖。很多问题是继承残留导致的,不是模板本身失效。
12 个内置模板选择指南
guess_spider_template 返回模板名后,理解其对应关系:
| 模板名 | CMS 类型 | URL 模式 | double | 二级 lazy |
|---|
| mx | 苹果CMS旧版 | /vodshow/fyclass--------fypage---/ | true | common_lazy(提取player_* JSON) |
| mxpro | 苹果CMS Pro | /vodshow/fyclass--------fypage---.html | true | common_lazy |
| mxone5 | One5主题 | /show/fyclass--------fypage---.html | true | common_lazy |
| 首图 | 首图CMS | /vodshow/fyclass--------fypage---/ | true | common_lazy |
| 首图2 | 首图CMS v2 | /list/fyclass-fypage.html | true | common_lazy |
| vfed | VFed CMS | /index.php/vod/show/id/fyclass/page/fypage.html | true | common_lazy |
| 海螺3 | 海螺CMS v3 | /vod_____show/fyclass--------fypage---.html | true | common_lazy |
| 海螺2 | 海螺CMS v2 | /index.php/vod/show/id/fyclass/page/fypage/ | true | common_lazy |
| 短视 | 短视频 | /channel/fyclass-fypage.html | true | common_lazy |
| 短视2 | 短视频v2 | API驱动(#type=fyclass&page=fypage) | true | common_lazy |
| 采集1 | 采集站 | API: ?ac=detail&pg=fypage&t=fyclass | false | cj_lazy(依赖parse_url) |
| 默认 | 通用兜底 | 空/自定义 | false | def_lazy(嗅探兜底) |
double: true 意味着推荐需要两层解析(先取外层容器,再从内层提取数据)。如果首页推荐空,优先检查是否误用了 double: true。
什么时候不要盲信模板命中
guess_spider_template 只说明 class_parse 特征相似,不保证 url/searchUrl/二级/lazy 都匹配。
- 命中模板但
get_resolved_rule(path) 显示 url/searchUrl 与真实站点不同 → 只覆盖 URL 模板,不重写整套规则。
- 命中模板但分类页实际是 API/签名接口 → 保留模板可用字段,一级/搜索局部切 async。
- 命中默认模板 → 视为兜底骨架,不等同于 CMS 模板站。
详细模板字段见 references/references-template-system.md。
模板继承核查清单(必须完成后再写规则)
class_parse 是否残留并覆盖 class_name/class_url?→ 显式补 class_parse: ''
double 是否导致首页推荐为空?→ 单层推荐优先 double: false
url 是否是真实分类模板?→ 必须验证真实分类页和翻页结构
searchUrl 是否是真实搜索模板?
- 首页推荐节点是否真实存在?
- 删除手写 一级/搜索,优先验证模板内置规则
最小覆盖示例(模板继承完整模板)
var rule = {
标题: '站点名',
模板: 'mxpro',
host: 'https://example.com',
url: '/vodshow/fyclass--------fypage---.html',
searchUrl: '/vodsearch/**----------fypage---.html',
class_parse: '.stui-header__item li;a&&href;/(\\d+)/',
};
必须用 get_resolved_rule(path) 验证继承后字段,再删除手写规则激活模板链。
强禁止
未完成核查清单前,禁止一上来就大面积手写 推荐/一级/搜索/二级。
常见排障
| 症状 | 优先检查 |
|---|
| 首页推荐空 | double 是否为 true,推荐节点是否真实存在 |
| detail 不通 | detailUrl 是否缺失(纯数字 vod_id 必须设 detailUrl) |
| 搜索空 | 搜索页 DOM 是否独立于一级(不要默认 搜索: '*') |
* 含义不清 | 先读 references/references-template-system.md,* 继承一级 |
参考资料
references/references-inherited-template-minimal-override-site.md
路线 B:非模板 HTML / 签名接口站
先把非模板站拆成两类,避免把普通静态 DOM 站过度分析成签名接口站:
| 子路线 | 判定 | 首选实现 | 升级条件 |
|---|
| B1 静态 DOM 站 | 分类/详情/搜索 HTML 直出 | 字符串规则 + 二级字典 | 选择器无法稳定覆盖时局部 async |
| B2 签名接口站 | 列表/搜索由 XHR/API 返回,带 time/sign/token/header | async 函数复现浏览器请求 | 签名算法复杂或需登录时停手确认 |
路线 B1:静态 DOM/字符串规则站
当 HTML 直接包含列表、详情和搜索结果时,不要先抓签名 API:
- 用
analyze_website_structure(url) 确认列表节点、标题、图片、链接字段。
- 用
debug_spider_rule 先验证一级字符串规则。
- 详情优先用二级字典
{title, img, desc, content, tabs, lists}。
- 搜索页如果 DOM 独立,单独写
搜索,不要默认 搜索: '*'。
- 只有翻页/搜索/章节依赖 XHR 时,才把对应接口局部升级为 async。
字符串规则源示例:
var rule = {
标题: '站点名',
host: 'https://example.com',
url: '/list/fyclass-fypage.html',
searchUrl: '/search/**-fypage.html',
一级: '.list-box li;a&&title;img&&data-src;.desc&&Text;a&&href',
二级: {
title: 'h1&&Text',
img: '.pic&&img&&src',
desc: '.meta&&Text',
content: '.intro&&Text',
tabs: '.tabs-box>.tab',
lists: '.tab-content ul:eq(#id) li;a&&title;a&&href'
},
搜索: '*',
};
路线 B2:非模板签名接口站
当站点不是内置模板,有完整 HTML 外壳,但分类/搜索等数据由前端带签名的接口驱动时走 B2。B2 介于路线 A(纯模板继承)和路线 C(全 async API)之间——页面结构可通过 HTML 解析,但数据加载依赖接口调用。
先判断一级是否由签名接口驱动
不要看到 data-api 就直接假设这是可裸 GET 的 JSON 接口。必须确认:
- 浏览器真实请求是 GET 还是 POST
- 是否带
time/key/token 等签名参数
- 是否需要 Ajax 请求头
已验证经验
裸 GET 可能只返回无效文本,浏览器真实请求却是带签名的 POST。
分级编写策略
按复杂度从低到高逐步尝试,不要一上来就写全 async:
- 先试二级字典:如果详情页是 HTML 而非 JSON,优先用二级字典映射(
{title, img, desc, content, tabs, lists})。lists 容器层级从 ul 下沉到 li 即可解决多集问题,无需切 async。
- 一级优先 async:签名接口必须用 async 函数处理,无法用字符串规则。用
this.MY_CATE / this.MY_PAGE 代替手动拼 URL。
- 搜索独立验证:签名站的搜索接口通常独立于一级,不要假设
搜索: '*' 继承生效。先用 fetch_spider_url 测试搜索 API 连通性。
- 模板可混合:签名接口站的首页推荐和播放页 lazy 可能仍可使用模板默认逻辑。优先保留模板的推荐/lazy,只覆盖一级/搜索。(此处的"模板"指
get_spider_template() 生成的代码骨架中的默认实现,不是路线 A 的 CMS 模板继承。)
参考资料
references/references-non-template-signed-api-site.md
路线 C:纯 API 驱动 SPA 站
当页面源码 <body> 几乎为空,所有数据来自 /api/xxx JSON 响应时走此路线。
立即参考
references/references-pure-api-async-site.md
核心:全 async 函数模式
不要尝试模板继承,不要写规则字符串,直接用全 async 函数。
必读(11 条跨站型规则见下方「通用规则」)
Route C 场景额外注意:
request POST 用 body(JSON.stringify)不是 data(通用规则 #3)
- 外部 API 可能需要
Authorization → 从浏览器抓包
- 推荐数据要全量聚合 → 别只取 featured(通用规则 #5)
核心要点
this.input 是渲染后的 URL 字符串 → 通用规则 #1
- 纯数字 vod_id 必须设
detailUrl → 通用规则 #2
searchUrl 必须带 ** → 通用规则 #4
全 async 源示例(Route C 骨架)
var rule = {
标题: '站点名',
host: 'https://example.com',
url: '/api/fyclass?page=fypage',
detailUrl: '/api/video/fyid',
searchUrl: '/api/search?wd=**&page=fypage',
class_parse: '.nav li;a&&Text;/api/(\\d+)',
推荐: async function() {
let html = await request(this.input);
let data = JSON.parse(html).list;
return data.map(v => ({
vod_id: v.id, vod_name: v.name, vod_pic: v.pic
}));
},
一级: async function() {
let html = await request(this.input);
let data = JSON.parse(html).list;
return data.map(v => ({
vod_id: v.id, vod_name: v.name, vod_pic: v.pic
}));
},
二级: async function() {
let html = await request(this.input);
let data = JSON.parse(html);
return { title: data.name, img: data.pic, desc: data.desc, content: data.content };
},
搜索: async function() {
let html = await request(this.input);
let data = JSON.parse(html).list;
return data.map(v => ({...}));
},
};
路线 D:特殊内容类型
漫画、小说、音乐、网盘不是普通影视 lazy 的变体,先确认内容形态再建源。合法的特殊内容源应满足:@header 的 类型 与实际内容一致,detail 产出章节/曲目/文件而不是普通视频集,lazy 返回对应特殊协议或真实音频/网盘输出。
| 类型 | detail 目标 | play/lazy 返回 | 验证重点 |
|---|
| 漫画 | 章节名 + 章节 URL | pics:// + 图片 URL 列表 | 图片顺序、分页/懒加载、反盗链 headers |
| 小说 | 章节名 + 正文页 URL | novel:// 或正文内容协议 | 编码、分页、正文清洗 |
| 音乐 | 歌曲名 + 音频页/接口 | mp3/m4a 直链或解析 | content-type、时效签名 |
| 网盘 | 资源标题 + 分享链接 | push:// 或网盘专用字段 | 提取码、失效提示、多网盘线路 |
特殊内容验证顺序仍是 home → category → detail → play;只是 play 的成功标准换成对应特殊协议,不要强行套 m3u8/mp4 判断。
lazy 返回示例
当源类型非影视时,lazy 需返回特殊协议而非普通视频链路:
| 类型 | lazy 实现 | 返回格式 |
|---|
| 漫画 | pdfa(html, '.comic-pages&&img') → pdfh(it, 'img&&data-src') | {parse:0, url: 'pics://' + urls.join('&&'), js: ''} |
| 小说 | 请求正文页 → 提取 title/content → JSON 化 | {parse:0, url: 'novel://' + JSON.stringify({title, content}), js: ''} |
| 音乐 | 请求播放页 → 提取 m4a/mp3 → urljoin 补全 | 返回音频 URL 字符串(框架自动 parse:0) |
| 网盘 | 按 flag 分派逻辑 → 提取直链 | {parse:0, url: 'push://...' } 或对应该网盘协议 |
通用规则(跨所有站型)
以下规则对模板站/签名接口站/纯 API 站都适用,只要源中有 async function 就必须遵守。
必读参考
references/references-async-function-patterns.md(async 函数通用模式与陷阱)
references/references-api-functions.md(沙箱边界、全局函数与 this 上下文)
运行时边界
DS 源运行在 drpy 沙箱中,不是普通 Node.js 模块;源内可用 request/pdfh/pd/pdfa/local/CryptoJS 等注入能力,但不要假设 fs/process/原生 require 或 MCP 工具能在源代码里调用。
7 条必背规则
this.input 是 URL 不是响应 → 必须 await request(this.input)
- 纯数字 vod_id 必须设
detailUrl → 引擎才能拼出详情 URL
- POST 用
body 不是 data → body: JSON.stringify({...})
searchUrl 必须带 ** → 否则 this.KEY 为空
- 推荐要完整聚合 → 全量聚合 + 按 vod_id 去重
- async 函数用
this.input 拿 URL → 不要手动拼 HOST + path
- 不写重复同名属性 → 删掉空占位,只保留有逻辑的
其他通用经验
- 一级 async 优先用
this.MY_CATE / this.MY_PAGE,不要拆 URL
request / post 是全局函数,不在 this 上
- detail 测试必须用一级真实返回的
vod_id
- 评估搜索时不要机械用默认词"斗罗大陆",要换高频宽匹配词
- 区分"规则不通"和"评估器没串起来"——单接口通但评估不通是串联问题
搜索策略(必须先判断)
处理搜索前,必须先读 references/references-old-encoding-search-site.md,判断属于:
- 原生搜索接口
- suggest / 联想搜索 fallback
- RSS fallback
parser 语法边界
|| 优先用于同一 selector 下的属性 fallback(如 img&&data-original||src)
- 不要生成
img&&data-original||img&&src 这种跨 selector fallback(超出 parser 稳定边界)
- 优先保守、可验证的规则写法
签名/API 请求重建清单
遇到路线 B/C 的动态接口时,用这个顺序把浏览器请求还原到源代码:
- 浏览器网络面板或 Playwright 确认 method、URL、query、body、headers。
- 区分固定 header、Cookie、Authorization、time/sign/key 等动态字段。
- 先用
fetch_spider_url(url, options) 复现原请求;POST 统一写 body: JSON.stringify(...)。
- 签名参数如果来自页面 JS,优先定位最小算法;不要把整段前端代码搬进源。
- 复现成功后再写 async;一级用
this.MY_CATE/MY_PAGE,搜索用 this.KEY。
- 签名有时效时,在 async 内即时计算,不要写死抓包值。
二级字典规范
完整参考:references/references-detail-dict-and-multiep.md
字段槽位语义
| 字段 | 语义 |
|---|
title | 片名;类型 |
img | 封面图规则 |
desc | 备注;年份;地区;演员;导演(5段固定槽位) |
content | 简介规则 |
tabs | 线路节点选择器 |
tab_text | 线路名提取规则 |
lists | 当前线路选集列表选择器(支持 #id/#idv) |
list_text | 每集标题(默认 body&&Text) |
list_url | 每集链接(默认 a&&href) |
排障要点(详见 reference)
- 页面多集但 detail 只吐 1 集 → 先查
lists 容器层级(从 ul 下沉到 li)
- detail 测试必须用一级真实返回的
vod_id,禁止主观简化
- 先让 detail 真通,再进入播放链排障
- 先保证 标题/描述/详情/图片/线路/列表 可用(最小化原则)
与其他 Skill 的分流
何时切换到 workflow
- 已变成系统性修源/评估/上传
- 源文件已存在,需要排查而非从零生成
- 任务包含仓库上传、标签修正
何时切换到 play-debug
- 主要卡在 lazy/直链/iframe/m3u8/parse 判断
转交前预诊断(Handoff 前必须做的)
在转交 workflow 之前,先收集关键证据让下游不必重头摸索:
1. drpy_read_file(path) → 确认现有源内容
2. drpy_check_syntax(path) → 语法检查
3. evaluate_spider_source(源名) → 全流程评分(记录各接口分数)
4. 若 evaluate 显示某接口丢分:
test_spider_interface(category, class_id='1')
test_spider_interface(detail, ids='从一级拿真实 vod_id')
test_spider_interface(play, play_url='从 detail 拿真实 url', flag='从 detail 拿')
test_spider_interface(search, keyword='高频宽匹配词')
→ 确定断点在哪个接口
5. 记录失败类型:A 规则不通 / B 评估串联 / C 播放链
转交时把预诊断结果写入 packet,不要只写"这个源有问题"。
Handoff Packet
转交时必须带最小上下文,避免下游重新摸索:
| 目标 skill | 必带字段 |
|---|
| workflow | 源名、文件路径、站型、home/category/detail/search/play 验证结果、失败接口、证据工具 |
| play-debug | source_name、真实 detail ids、vod_play_from、vod_play_url、flag、当前 play 返回 |
| repo-upload | 文件路径、源名、内容类型、L1/L2/L3 验证等级、A/B/C 建议、upload_preauthorized、用户标签要求、is_public、auto_replace 策略、目标对象是否明确 |
强制停手检查点
出现以上任一情况时,必须停止在 create skill 内扩写,明确切换。
五种编写模式速览
根据站型和复杂度,从以下五种模式中选一种。优先上层模式(代码量少、更稳定)。
| 模式 | 代码量 | 适用场景 | 关键字段 |
|---|
| 模板继承 | 7-15行 | guess_spider_template 命中内置模板 | 模板: 'mxpro', class_parse, url |
| 字符串规则 | 15-30行 | DOM 结构稳定的 B1 静态站 | 一级: 'ul li;a&&title;...' |
| js: 内联 | 1-2行表达式 | 字符串规则中嵌入少量计算 | 一级: 'js:let x=input...' |
| async 函数 | 50-200行 | B2 签名 API、路线 C、反爬、非标站 | 一级: async function() { ... } |
| 网盘型 | 100-300行 | 多网盘资源聚合 | hostJs, line_order, lazy 按 flag 分派 |
核心原则: 能用模板继承就不用字符串规则,能用字符串就不用 async 函数,逐步增加复杂度。
高级字段触发点
这些字段只在确有需求时使用,优先作为局部增强,不要替代简单规则:
| 字段 | 何时使用 | 注意 |
|---|
hostJs | 站点域名漂移、需从配置页/发布页动态取 host | 返回最终 host;与 line_order/lazy 的共享状态要保持最小 |
预处理 | 进入接口前需要初始化 cookie/token/全局变量 | 只做初始化,不在里面抓完整列表 |
模板修改 | 模板整体适配但少数字段需在继承前调整 | 比复制整份模板更安全;只改目标模板的必要字段 |
二级访问前 | 详情页需要追加参数或转换 URL | 返回新 URL,避免在二级主体里重复拼接 |
proxy_rule | 图片/播放/接口需要本地代理转换 | 仅用于必须代理的资源,避免扩大范围 |
play_json | lazy 表面返回与最终 parse/jx/url 不一致 | 先用 get_resolved_rule 确认继承结果,再转 play-debug 深排 |
play_parse | 需要显式控制是否启用解析/嗅探 | 不要用它掩盖错误的直链判断 |
sniffer | 播放依赖嗅探页面中的真实媒体请求 | 需要浏览器/网络证据支撑 |
isVideo | 站点 URL 后缀不稳定,需要自定义媒体识别 | 只用于媒体 URL 判断,不替代 lazy 逻辑 |
网盘/多线路源补充清单
hostJs 只负责确定可用 host 或公共配置,不要混入分类抓取。
line_order 用于稳定线路排序,避免客户端每次看到不同顺序。
lazy 必须按 flag 分派不同网盘/解析逻辑,不要用一个分支处理所有线路。
- 网盘转存、解析、直链提取应分层验证;单条线路失败不要影响其他线路。
收尾输出模板
## 建源结果
- 文件:spider/js/[源名].js
- 站型:路线 A / B / C / 特殊内容
- 实现方式:模板继承 / 字符串规则 / async / 混合 / 网盘型
- 验证:
- home:通过 / 未通过(依据)
- category:通过 / 未通过(class_id=...)
- detail:通过 / 未通过(ids=...)
- search:通过 / 未通过(keyword=...)
- play:通过 / 未通过(flag/url=...)
- 未覆盖风险:登录态 / 签名时效 / 搜索翻页 / 多线路 / 反爬 / metadata 与实际能力不一致
- 下一步:继续修源 / 播放专项 / 转 repo-upload / 结束