Install any skill in seconds. Free to start, no credit card required.
Get Started Free →drpy视频源创建与调试技能。当用户需要创建、修改、调试drpy视频源(用于TVBox、海阔视界、ZYPlayer等播放器)时使用此技能。包括drpy源属性配置、模板继承、正则表达式编写、本地代理设置、不同类型源(影视/听书/漫画/小说)支持。
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 246% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 125% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 160% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 192% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 115% | 0% |
drpy源是一种用于TVBox、海阔视界、ZYPlayer等播放器的视频源格式,使用JavaScript编写,支持动态内容抓取和解析。本技能提供完整的drpy源创建指南,包含属性配置、模板继承、正则表达式编写、常见问题调试等。
以下是基础的drpy源模板:
javascriptvar rule = { // 影视|听书|漫画|小说 类型: '影视', // 规则标题 title: '示例源', // 网页的域名根 host: 'https://www.example.com', // 网站的首页链接 homeUrl: '/latest/', // 分类页面链接 url: '/fyclass/fypage.html', // 搜索链接 searchUrl: '/vodsearch/紧箍咒/page/fypage.html', // 是否启用全局搜索 searchable: 1, // 是否启用快速搜索 quickSearch: 0, // 是否启用筛选 filterable: 0, // 请求头 headers: { 'User-Agent': 'MOBILE_UA', }, // 请求超时(毫秒) timeout: 5000, // 是否需要调用免嗅lazy函数 play_parse: true, // 静态分类名称 class_name: '电影&电视剧&动漫&综艺', // 静态分类标识 class_url: '1&2&3&4', }
第一步:获取网站源码
pythonimport requests headers = {'User-Agent': 'Mozilla/5.0...'} resp = requests.get('https://www.pitv.cc/', headers=headers) html = resp.text
第二步:确认关键选择器
✓ .hl-vod-list - 列表容器存在
✓ .hl-list-item - 列表项存在
✓ a&&title - 标题属性存在
✓ a&&data-original - 图片属性存在
✗ .remarks - 状态class不存在(实际是.hl-pic-text span)第三步:修正选择器
javascript// 错误(参考代码) 推荐: '.hl-vod-list;li;a&&title;a&&data-original;.remarks&&Text;a&&href', // 正确(实际HTML结构) 推荐: '.hl-vod-list;li;a&&title;a&&data-original;.hl-pic-text span&&Text;a&&href',
第四步:验证搜索功能
第五步:最终可用配置
javascriptvar rule = { title: '皮皮影视', host: 'https://www.pitv.cc', url: '/show/fyclassfyfilter/page/fypage/', searchable: 0, // 搜索需要验证码,禁用 class_name: '剧集&电影&动漫', class_url: '1&2&3', 推荐: '.hl-vod-list;li;a&&title;a&&data-original;.hl-pic-text span&&Text;a&&href', 一级: '.hl-vod-list&&.hl-list-item;a&&title;a&&data-original;.hl-pic-text span&&Text;a&&href', 二级: { title: 'h1&&Text', img: '.hl-lazy&&data-original', tabs: '.hl-plays-from&&a', lists: '.hl-plays-list:eq(#id)&&a', }, }
| 属性 | 类型 | 说明 | 示例 | |------|------|------|------| | 类型 | string | 源类型:'影视'、'听书'、'漫画'、'小说' | '影视' | | title | string | 规则标题,在播放器中显示的名称 | '鸭奈飞' | | host | string | 网站域名根,包含http/https协议 | 'https://yanetflix.com' | | homeUrl | string | 网站首页链接,用于获取分类和推荐 | '/latest/' | | url | string | 分类页面链接模板 | '/vod/show/id/fyclass/page/fypage.html' | | searchUrl | string | 搜索链接模板 | '/vodsearch/紧箍咒/page/fypage.html' | | searchable | number | 是否启用全局搜索 | 1(启用)或0(禁用) | | quickSearch | number | 是否启用快速搜索 | 1(启用)或0(禁用) | | filterable | number | 是否启用筛选 | 1(启用)或0(禁用) |
javascript// 静态分类配置 class_name: '电影&电视剧&动漫&综艺', class_url: '1&2&3&4', // 动态分类获取(推荐) class_parse: '#side-menu:lt(1) li;a&&Text;a&&href;com/(.*?)/', // 格式:列表选择器;标题选择器;链接选择器;正则提取(可选)
javascript// 请求头配置 headers: { 'User-Agent': 'MOBILE_UA', 'Cookie': 'searchneed=ok', 'Referer': 'https://www.example.com/' }, // 超时设置(毫秒) timeout: 5000, // 动态获取host(优先级最高) hostJs: async function () { let {HOST} = this; return HOST }, // 预处理(初始化时执行一次) 预处理: async function () { let {HOST} = this; return HOST },
drpy源的核心解析函数,用于获取不同页面的内容:
javascript// 推荐内容获取 推荐: async function () { let {input} = this; // input为homeUrl的内容 return [] }, // 一级列表获取 一级: async function () { let {input} = this; // input为url模板填入后的链接 return [] }, // 二级详情获取 二级: async function () { let {input} = this; // input为一级返回的链接 return {} }, // 搜索内容获取 搜索: async function () { let {input} = this; // input为searchUrl模板填入后的链接 return [] },
javascript// 免嗅播放解析 play_parse: true, // lazy函数处理播放地址 lazy: async function () { let {input} = this; return { url: input, parse: 0 } }, // 辅助嗅探规则 sniffer: 1, isVideo: "http((?!http).){26,}\\.(m3u8|mp4|flv|avi|mkv|wmv|mpg|mpeg|mov|ts|3gp|rm|rmvb|asf|m4a|mp3|wma)",
javascriptvar rule = Object.assign(muban.mxpro, { title: '鸭奈飞', host: 'https://yanetflix.com', url: '/index.php/vod/show/id/fyclass/page/fypage.html', class_parse: `.navbar-items li:gt(1):lt(6);a&&Text;a&&href;.*/(.*?).html`, });
javascriptvar rule = { title: 'cokemv', 模板: 'mxpro', host: 'https://cokemv.me', class_parse: `.navbar-items li:gt(1):lt(7);a&&Text;a&&href;/(\\d+).html`, }
javascriptvar rule = { 模板: '自动', 模板修改: $js.toString(() => { Object.assign(muban.自动.二级, { tab_text: 'div--small&&Text', }); }), title: '剧圈圈[自动]', host: 'https://www.jqqzx.cc/', url: '/vodshow/id/fyclass/page/fypage.html', searchUrl: '/vodsearch**/page/fypage.html', class_parse: '.navbar-items li:gt(2):lt(8);a&&Text;a&&href;.*/(.*?)\.html', cate_exclude: '今日更新|热榜', }
标准的视频源,支持电影、电视剧、动漫等内容。
用法与影视源一致,播放音频内容。
需要在lazy函数处理后返回pics://协议:
javascriptlazy: async function () { return "pics://图片链接1,图片链接2,图片链接3"; }
需要在lazy函数处理后返回novel://协议:
javascriptlazy: async function () { return 'novel://{"title":"章节名称","content":"章节内容"}'; }
在字符串属性(如class_parse)中使用正则表达式时需要注意转义:
| 需求 | JavaScript正则 | drpy字符串写法 | |------|---------------|----------------| | 数字 | /(\d+)/ | (\\d+) | | 任意字符 | /.*/ | .* | | 非贪婪匹配 | /(.*?)/ | (.*?) | | 多个分组 | /(\d+)-(\w+)/ | (\\d+)-(\\w+) |
javascriptproxy_rule: `js: log(input); input = [200,'text;plain','hello drpy'] `,
本地代理的input参数格式为三元素数组: [status_code, content_type, data]
示例:
javascript// 返回M3U8文件 input = [200,'application/vnd.apple.mpegurl', m3u8_content]; // 返回文本 input = [200,'text/plain', 'hello world'];
host是否正确timeout值(默认5000毫秒)log()函数调试输出play_parse设置lazy函数返回正确格式sniffer规则是否匹配视频链接class_parse格式正确bash# 安装uglify-js npm install uglify-js -g # 压缩JS文件 uglifyjs source.js -o source.min.js
where uglifyjsC:\Users\username\AppData\Roaming\npm\uglifyjs.cmd$FileName$ -o $FileNameWithoutExtension$.min.js$FileDir$log()函数输出调试信息javascript// 加密 RSA.encode(data, key, option); // 解密 RSA.decode(data, key, option);
javascript// 线路顺序 tab_order: ['lzm3u8', 'wjm3u8', '1080zyk'], // 线路名替换 tab_rename: { 'lzm3u8': '量子资源', '1080zyk': '1080看', }, // 移除线路 tab_remove: ['tkm3u8'],
javascript// 图片替换 图片替换: 'https://old-domain.com/=>https://new-domain.com/', // 图片来源(添加referer) 图片来源: '@Referer=http://www.example.com@User-Agent=custom-ua',
在drpy源的二级详情或其他交互页面中,可以通过返回action对象来定义按钮行为:
javascript二级: async function () { return { // 视频详情信息 vod_name: "影片名称", vod_play_from: "播放来源", vod_play_url: "第1集$播放地址", // Action配置 action: { button: 2, // 按钮类型:0-关闭, 1-取消, 2-确定和取消, 3-确定/取消/重置, 4-确定/取消/重置/预览 // 其他action属性... }, }; },
| 值 | 按钮组合 | 适用场景 | |----|----------|----------| | 0 | 关闭按钮 | 只提供关闭功能 | | 1 | 取消按钮 | 简单确认场景 | | 2 | 确定和取消 | 需要用户确认的操作 | | 3 | 确定、取消、重置 | 表单或设置页面 | | 4 | 确定、取消、重置、预览 | 复杂的编辑页面 |
除了按钮,action还可以包含其他指令:
javascriptaction: { button: 2, message: "操作提示信息", redirect: "目标URL", // 其他自定义属性 },
drpy源可以通过压缩减少文件大小:
bash# 安装uglify-js npm install uglify-js -g # 压缩JS文件 uglifyjs source.js -o source.min.js # 推荐配置 uglifyjs source.js -o source.min.js -c -m --comments '/@license|@preserve/'
where uglifyjsC:\Users\username\AppData\Roaming\npm\uglifyjs.cmd$FileName$ -o $FileNameWithoutExtension$.min.js$FileDir$详细格式化指南见:formatting.md
症状:分类能显示,但点击后列表为空
原因:参考代码的选择器与实际HTML不符
排查方法:
pythonimport requests from bs4 import BeautifulSoup headers = {'User-Agent': 'Mozilla/5.0...'} html = requests.get('https://example.com/', headers=headers).text soup = BeautifulSoup(html, 'html.parser') # 检查选择器是否存在 print('hl-vod-list:', bool(soup.find(class_='hl-vod-list'))) print('hl-list-item:', bool(soup.find(class_='hl-list-item'))) print('remarks:', bool(soup.find(class_='remarks'))) # 可能不存在 # 查找实际的class名 for elem in soup.find_all(class_=True): if 'pic' in str(elem.get('class')) or 'text' in str(elem.get('class')): print(elem.name, elem.get('class'))
解决方案:
javascript// 错误 推荐: '.hl-vod-list;li;a&&title;a&&data-original;.remarks&&Text;a&&href', // 正确(根据实际HTML调整) 推荐: '.hl-vod-list;li;a&&title;a&&data-original;.hl-pic-text span&&Text;a&&href',
症状:搜索返回空结果或报错
排查方法:
python# 测试搜索URL search_resp = requests.get('https://example.com/search/关键词/', headers=headers) print('状态码:', search_resp.status_code) print('是否包含验证码:', '验证码' in search_resp.text) print('是否包含结果:', 'hl-vod-list' in search_resp.text)
常见情况:
searchable: 0 禁用搜索症状:能进入详情页,但无播放列表
排查方法:
python# 获取详情页HTML detail_html = requests.get('https://example.com/vod/123/', headers=headers).text # 检查关键元素 print('h1:', 'h1' in detail_html) print('hl-plays-list:', 'hl-plays-list' in detail_html) print('hl-plays-from:', 'hl-plays-from' in detail_html)
解决方案:
javascript// 根据实际HTML调整二级选择器 二级: { title: 'h1&&Text', // 使用h1而不是.hl-dc-title img: '.hl-lazy&&data-original', tabs: '.hl-plays-from&&a', // 播放源 lists: '.hl-plays-list:eq(#id)&&a', // 剧集列表 }
症状:分类点击后跳转错误页面
排查方法:
python# 测试URL模板 # 参考代码: /show/fyclassfyfilter/page/fypage/ # 实际测试 for cls in ['1', '2', '3']: url = f'https://example.com/show/{cls}--------/page/1/' resp = requests.get(url, headers=headers) print(f'{url} -> {resp.status_code}')
解决方案:
javascript// 确认URL格式 url: '/show/fyclassfyfilter/page/fypage/', // fyclass和fyfilter连在一起 // 或 url: '/type/fyclass/', // 简单的分类格式
javascript推荐: `js: let html = request(input); log('首页HTML长度:', html.length); log('是否包含视频列表:', html.includes('hl-vod-list')); let items = pdfa(html, '.hl-vod-list li'); log('提取到视频数量:', items.length); // 继续解析... `,
javascript// 先测试基础功能 var rule = { title: '测试源', host: 'https://example.com', url: '/type/fyclass/', class_name: '分类1&分类2', class_url: '1&2', 推荐: 'a;a&&Text;;;a&&href', // 只取标题和链接 一级: 'a;a&&Text;;;a&&href', 二级: '*', lazy: '' };
| 任务 | 参考文档 | |------|----------| | 新建一个drpy源 | 基础模板 | | 了解所有属性含义 | 属性详解 | | 使用模板继承 | 模板继承 | | 编写解析函数 | 解析函数 | | 调试源问题 | 问题排查 | | 压缩源代码 | 代码格式化 | | 分析网站结构 | analyze_site.py |
核心原则:
提示:创建drpy源时,建议先使用简单的模板测试基础功能,再逐步添加高级功能。使用模板继承可以大大简化开发过程。
Other measured skills in the registry, with their headline benchmark lift.