drpy视频源创建与调试技能。当用户需要创建、修改、调试drpy视频源(用于TVBox、海阔视界、ZYPlayer等播放器)时使用此技能。包括drpy源属性配置、模板继承、正则表达式编写、本地代理设置、不同类型源(影视/听书/漫画/小说)支持。
Scanned 9/6/2026
Install to Claude Code
npx -y skills add LeoYeAI/openclaw-master-skills --skill drpy-source-creator --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Drpy Source Creator?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/leoyeai-drpy-source-creator)More formats (shields.io, HTML) on the badges page.
---
name: drpy-source-creator
description: drpy视频源创建与调试技能。当用户需要创建、修改、调试drpy视频源(用于TVBox、海阔视界、ZYPlayer等播放器)时使用此技能。包括drpy源属性配置、模板继承、正则表达式编写、本地代理设置、不同类型源(影视/听书/漫画/小说)支持。
---
# drpy视频源创建与调试
## 概述
drpy源是一种用于TVBox、海阔视界、ZYPlayer等播放器的视频源格式,使用JavaScript编写,支持动态内容抓取和解析。本技能提供完整的drpy源创建指南,包含属性配置、模板继承、正则表达式编写、常见问题调试等。
## 快速开始
以下是基础的drpy源模板:
```javascript
var 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',
}
```
## 实战案例分析:皮皮影视
### 分析步骤
**第一步:获取网站源码**
```python
import 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',
```
**第四步:验证搜索功能**
- 测试发现搜索需要验证码
- 结论:searchable应设为0
**第五步:最终可用配置**
```javascript
var 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',
},
}
```
## drpy源属性详解
### 核心属性
| 属性 | 类型 | 说明 | 示例 |
|------|------|------|------|
| 类型 | 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)",
```
## 模板继承
### 方法一:Object.assign
```javascript
var 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`,
});
```
### 方法二:模板属性(新)
```javascript
var rule = {
title: 'cokemv',
模板: 'mxpro',
host: 'https://cokemv.me',
class_parse: `.navbar-items li:gt(1):lt(7);a&&Text;a&&href;/(\\d+).html`,
}
```
### 方法三:自动匹配模板
```javascript
var 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://`协议:
```javascript
lazy: async function () {
return "pics://图片链接1,图片链接2,图片链接3";
}
```
### 小说源
需要在`lazy`函数处理后返回`novel://`协议:
```javascript
lazy: async function () {
return 'novel://{"title":"章节名称","content":"章节内容"}';
}
```
## 正则表达式写法
在字符串属性(如`class_parse`)中使用正则表达式时需要注意转义:
| 需求 | JavaScript正则 | drpy字符串写法 |
|------|---------------|----------------|
| 数字 | `/(\d+)/` | `(\\d+)` |
| 任意字符 | `/.*/` | `.*` |
| 非贪婪匹配 | `/(.*?)/` | `(.*?)` |
| 多个分组 | `/(\d+)-(\w+)/` | `(\\d+)-(\\w+)` |
## 本地代理设置
```javascript
proxy_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'];
```
## 常见问题排查
### 1. 连接超时
- 检查`host`是否正确
- 调整`timeout`值(默认5000毫秒)
- 检查网络连接
### 2. 解析失败
- 确认选择器是否正确
- 使用`log()`函数调试输出
- 检查网页结构是否变化
### 3. 播放失败
- 检查`play_parse`设置
- 确认`lazy`函数返回正确格式
- 验证`sniffer`规则是否匹配视频链接
### 4. 分类获取失败
- 确认`class_parse`格式正确
- 检查正则表达式转义
- 验证分类页面是否可访问
## 工具和资源
### 代码格式化
```bash
# 安装uglify-js
npm install uglify-js -g
# 压缩JS文件
uglifyjs source.js -o source.min.js
```
### WebStorm配置
1. 获取uglifyjs路径:`where uglifyjs`
2. 配置外部工具:
- 程序: `C:\Users\username\AppData\Roaming\npm\uglifyjs.cmd`
- 参数: `$FileName$ -o $FileNameWithoutExtension$.min.js`
- 工作目录: `$FileDir$`
### 调试技巧
1. 使用`log()`函数输出调试信息
2. 分步测试各个解析函数
3. 验证模板继承是否正确
4. 检查属性拼写和格式
## 进阶功能
### RSA加解密
```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',
```
---
## Action与按钮
在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
除了按钮,action还可以包含其他指令:
```javascript
action: {
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/'
```
### WebStorm配置
1. 获取uglifyjs路径:`where uglifyjs`
2. 配置外部工具:
- 程序: `C:\Users\username\AppData\Roaming\npm\uglifyjs.cmd`
- 参数: `$FileName$ -o $FileNameWithoutExtension$.min.js`
- 工作目录: `$FileDir$`
详细格式化指南见:[formatting.md](references/formatting.md)
## 常见错误与排查
### 错误1:首页/分类空白(选择器不匹配)
**症状**:分类能显示,但点击后列表为空
**原因**:参考代码的选择器与实际HTML不符
**排查方法**:
```python
import 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',
```
### 错误2:搜索功能异常
**症状**:搜索返回空结果或报错
**排查方法**:
```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)
```
**常见情况**:
1. **需要验证码** → 设置 `searchable: 0` 禁用搜索
2. **URL格式错误** → 检查实际的搜索表单action
3. **需要登录/Cookie** → 添加Cookie到headers
### 错误3:二级详情页空白
**症状**:能进入详情页,但无播放列表
**排查方法**:
```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', // 剧集列表
}
```
### 错误4:URL模板错误
**症状**:分类点击后跳转错误页面
**排查方法**:
```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/', // 简单的分类格式
```
## 调试技巧
### 1. 添加日志输出
```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);
// 继续解析...
`,
```
### 2. 使用极简版本测试
```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: ''
};
```
### 3. 分步验证
1. **分类** → 是否能正常显示
2. **一级** → 点击分类后是否有列表
3. **二级** → 点击进入详情页是否正常
4. **播放** → 点击播放是否能正常解析
## 扩展阅读
### 详细参考资料
- **[属性详解](references/attributes.md)** - 所有属性的完整说明和示例
- **[模板继承](references/templates.md)** - 模板系统的详细使用方法
- **[解析函数](references/parsing.md)** - 选择器语法和解析函数编写指南
- **[问题排查](references/troubleshooting.md)** - 常见问题解决方案
- **[代码格式化](references/formatting.md)** - 代码压缩和格式化工具使用
### 实用模板文件
- **[基础模板](assets/basic_template.js)** - 适用于大多数CMS站的基础模板
- **[MXPro示例](assets/mxpro_example.js)** - MXPro模板继承完整示例
- **[皮皮影视实战](assets/pitv_example.js)** - 皮皮影视完整配置(含注释)
### 辅助脚本
- **[minify_drpy.js](scripts/minify_drpy.js)** - drpy源压缩脚本
- **[validate_drpy.js](scripts/validate_drpy.js)** - drpy源格式验证脚本
- **[analyze_site.py](scripts/analyze_site.py)** - 网站结构分析脚本
## 快速查找
| 任务 | 参考文档 |
|------|----------|
| 新建一个drpy源 | [基础模板](assets/basic_template.js) |
| 了解所有属性含义 | [属性详解](references/attributes.md) |
| 使用模板继承 | [模板继承](references/templates.md) |
| 编写解析函数 | [解析函数](references/parsing.md) |
| 调试源问题 | [问题排查](references/troubleshooting.md) |
| 压缩源代码 | [代码格式化](references/formatting.md) |
| 分析网站结构 | [analyze_site.py](scripts/analyze_site.py) |
**核心原则**:
1. **先验证,再编写** - 用Python获取HTML确认选择器存在
2. **从简到繁** - 先用极简版本测试,再逐步完善
3. **实际测试** - 不要完全相信参考代码,每个网站结构不同
4. **记录问题** - 遇到的选择器不匹配问题要记录,避免重复踩坑
**提示**:创建drpy源时,建议先使用简单的模板测试基础功能,再逐步添加高级功能。使用模板继承可以大大简化开发过程。Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!