docs: add 两个BT spider design
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
# 两个BT Spider 设计
|
||||
|
||||
## 目标
|
||||
|
||||
在当前 Python 仓库中新增一个符合 `base.spider.Spider` 接口的 `两个BT` spider,参考用户提供的 JS 站点逻辑,实现首页、分类、搜索、详情和播放能力,目标站点为 `https://www.bttwoo.com`。
|
||||
|
||||
## 范围
|
||||
|
||||
本次实现包含:
|
||||
|
||||
- 新增 `py/两个BT.py`
|
||||
- 新增 `py/tests/test_两个BT.py`
|
||||
- 固定 14 个分类
|
||||
- 首页推荐、分类页与搜索页卡片解析
|
||||
- 详情页元数据与单线路剧集解析
|
||||
- 播放页直链提取、iframe 二次提取与失败回退
|
||||
|
||||
本次实现不包含:
|
||||
|
||||
- 修改 `py/base/` 共享基类
|
||||
- 迁移 JS 版本中的 `OmniBox.log`、`processScraping`、`getScrapeMetadata`、`sniffVideo`
|
||||
- 真实联网测试
|
||||
- 站外解析器或额外第三方线路适配
|
||||
|
||||
## 分类与 URL
|
||||
|
||||
首页固定返回以下分类:
|
||||
|
||||
- `zgjun` 国产剧
|
||||
- `meiju` 美剧
|
||||
- `jpsrtv` 日韩剧
|
||||
- `movie_bt_tags/xiju` 喜剧
|
||||
- `movie_bt_tags/aiqing` 爱情
|
||||
- `movie_bt_tags/adt` 冒险
|
||||
- `movie_bt_tags/at` 动作
|
||||
- `movie_bt_tags/donghua` 动画
|
||||
- `movie_bt_tags/qihuan` 奇幻
|
||||
- `movie_bt_tags/xuanni` 悬疑
|
||||
- `movie_bt_tags/kehuan` 科幻
|
||||
- `movie_bt_tags/juqing` 剧情
|
||||
- `movie_bt_tags/kongbu` 恐怖
|
||||
- `gf` 高分电影
|
||||
|
||||
`homeContent` 只返回 `class`,不返回 `filters`。参考脚本没有定义筛选项,Python 版本也不额外引入未经验证的筛选参数。
|
||||
|
||||
URL 规则如下:
|
||||
|
||||
- 首页推荐走 `/`
|
||||
- 分类页默认走 `/{tid}`
|
||||
- `movie_bt_tags/*` 保留原始路径
|
||||
- 页码大于 1 时追加 `paged` 查询参数
|
||||
- 搜索走 `/xssssearch?q=<keyword>`
|
||||
- 搜索翻页追加 `p=<page>`
|
||||
|
||||
分类和搜索结果返回仓库当前通用字段:
|
||||
|
||||
- `list`
|
||||
- `page`
|
||||
- `limit`
|
||||
- `total`
|
||||
|
||||
不返回 `pagecount`。
|
||||
|
||||
## 接口映射
|
||||
|
||||
- `homeContent`
|
||||
- 返回固定分类
|
||||
- `homeVideoContent`
|
||||
- 请求首页
|
||||
- 复用列表卡片解析函数返回推荐列表
|
||||
- `categoryContent`
|
||||
- 构造分类 URL
|
||||
- 解析卡片并返回分页字段
|
||||
- `searchContent`
|
||||
- 构造搜索 URL
|
||||
- 解析卡片并做轻量相关性过滤
|
||||
- `detailContent`
|
||||
- 请求详情页
|
||||
- 解析标题、封面、简介、导演、主演
|
||||
- 解析所有 `/v_play/` 剧集链接并组装单线路播放列表
|
||||
- `playerContent`
|
||||
- 解码 `play_id`
|
||||
- 请求播放页并优先提取站内直链
|
||||
- 必要时进入 iframe 二次提取
|
||||
- 提取失败时回退 `parse=1`
|
||||
|
||||
## 数据模型
|
||||
|
||||
### 列表卡片
|
||||
|
||||
首页推荐、分类和搜索统一复用卡片解析逻辑:
|
||||
|
||||
- 从包含 `/movie/<id>.html` 的链接提取详情入口
|
||||
- `vod_id` 只保留数字 ID,不返回绝对 URL
|
||||
- 标题按 `h3 a`、`h3`、`a[title]`、`.title`、`.name` 顺序提取
|
||||
- 图片按 `data-original`、`data-src`、`src` 顺序提取
|
||||
- 图片地址统一补全为绝对 URL
|
||||
- 备注从评分、状态或常见角标文本提取
|
||||
- 对重复卡片按 `vod_id` 去重
|
||||
|
||||
### 搜索精排
|
||||
|
||||
搜索结果在卡片解析后做一层轻量过滤,以贴近参考脚本:
|
||||
|
||||
- 标题直接包含关键词时保留
|
||||
- 否则按去空白后的字符集合计算交集比例
|
||||
- 关键词长度不超过 2 时只做直接包含判断
|
||||
- 未命中过滤条件的结果丢弃
|
||||
|
||||
### 详情
|
||||
|
||||
详情页字段按“DOM 优先,兜底选择器回退”的方式提取:
|
||||
|
||||
- 标题优先 `h1`、`h2`、`title`
|
||||
- 封面优先 `img.poster`、`.poster img`、首张可用图片
|
||||
- 简介优先 `.intro`、`.description`、`.desc`
|
||||
- 主演与导演优先标签文本,再用正则清理 `主演`、`导演` 前缀
|
||||
|
||||
播放列表统一输出为单线路:
|
||||
|
||||
- `vod_play_from`: `两个BT`
|
||||
- `vod_play_url`: `剧集名$playId#剧集名$playId`
|
||||
|
||||
选集按详情页上的 `/v_play/...html` 链接提取,顺序保持页面顺序。
|
||||
|
||||
### 播放 ID
|
||||
|
||||
`play_id` 使用轻量 JSON 编码后再 base64,至少包含:
|
||||
|
||||
- `pid`: 站内 `/v_play/` 的核心 ID
|
||||
- `sid`: 当前影片 `vod_id`
|
||||
- `name`: 原始剧集名
|
||||
|
||||
这样可以在播放解析阶段直接恢复播放页地址,并保留回退所需上下文。
|
||||
|
||||
## 播放解析
|
||||
|
||||
播放解析优先返回站内直链,处理顺序如下:
|
||||
|
||||
1. 解码 `play_id`
|
||||
2. 如果输入本身已是媒体直链,则直接返回 `parse=0`
|
||||
3. 构造并请求 `/v_play/<pid>.html`
|
||||
4. 优先从播放页 HTML 中提取显式媒体地址,例如 `.m3u8`、`.mp4`
|
||||
5. 若存在 iframe,则继续请求 iframe 页面并重复提取
|
||||
6. 若仍无法拿到直链,则回退返回播放页 URL,并设置 `parse=1`
|
||||
|
||||
播放器返回头至少包含:
|
||||
|
||||
- `User-Agent`
|
||||
- `Referer`
|
||||
- `Origin`
|
||||
|
||||
这部分只实现仓库现有能力边界内的站内解析,不迁移参考脚本对外部运行时的依赖。
|
||||
|
||||
## 错误处理
|
||||
|
||||
- HTML 请求失败时返回空字符串,不向上抛站点异常
|
||||
- 首页、分类、搜索失败时返回空列表和基本分页字段
|
||||
- 详情页解析失败时返回空列表
|
||||
- 播放解析失败时回退 `parse=1`
|
||||
- 坏的 `play_id`、空节点和无匹配正则都按空值处理,不抛未捕获异常
|
||||
|
||||
## 测试策略
|
||||
|
||||
使用 `unittest` 与 `unittest.mock`,不走真网。
|
||||
|
||||
至少覆盖:
|
||||
|
||||
- `homeContent` 返回固定 14 个分类
|
||||
- 列表卡片正确提取 `vod_id`、标题、图片、备注
|
||||
- `categoryContent` 正确拼接分类 URL 与页码参数
|
||||
- `searchContent` 正确请求搜索 URL 并执行相关性过滤
|
||||
- `detailContent` 正确提取元数据和剧集列表
|
||||
- `play_id` 编码与解码保持一致
|
||||
- `playerContent` 能直接返回已给定的媒体地址
|
||||
- `playerContent` 能从播放页提取媒体直链
|
||||
- `playerContent` 能进入 iframe 页面继续提取
|
||||
- `playerContent` 在拿不到直链时回退 `parse=1`
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 新增 spider 与测试文件后,可独立运行 `tests.test_两个BT`
|
||||
- 首页、分类、搜索、详情在离线夹具下输出稳定
|
||||
- 播放支持“直接媒体地址 -> 播放页提取 -> iframe 二次提取 -> 失败回退”四条路径
|
||||
- 不修改共享基类即可完成接入
|
||||
Reference in New Issue
Block a user