--- name: "jav-media-sorter" description: "JAV 视频整理:组装文件、按演员分组、刮削 nfo 元数据与封面图" --- # JAV 媒体整理与元数据刮削技能 将 qbittorrent 下载完成的 JAV 视频( mp4 + srt + nfo )文件整理成 `/mnt/f/av/` 格式,按演员分类,并尝试刮削封面图。 ## 目录结构规范 目标格式(参考 `/mnt/f/av/`): ``` /mnt/f/av/ ├── 演员名/ │ ├── 番号-C 演员名/ ← 如果已有番号-C 目录则保留原名 │ │ ├── 番号.mp4 │ │ ├── 番号.chs.srt │ │ ├── 番号.nfo │ │ ├── poster.jpg │ │ └── fanart.jpg │ └── ... ├── 未知演员/ │ └── ... ``` 另一套目录结构(参考 `/mnt/e/01_automated/日本电影/`): ``` /mnt/e/01_automated/日本电影/ ├── 演员名/ │ ├── 番号 演员名/ │ │ ├── 番号.mp4 │ │ ├── 番号.nfo │ │ ├── 番号-poster.jpg │ │ └── 番号-thumb.jpg │ └── ... ``` ## 前置条件 - Clash 代理运行在 Docker(端口 7443,认证 `proxy:5gynj20J`) - FlareSolverr 运行在 Docker(已下线,按需启动) - Python3(用于 nfo 和整理脚本) - Docker(FlareSolverr + Clash) ## 操作流程 ### 1. 检查下载目录 ```bash ls /mnt/f/qbittorrent/failed/ ``` 通常结构是 `failed/` 目录下平铺所有 mp4、srt(.chs.srt)、nfo 文件。 ### 2. 按演员创建目标文件夹 在 `failed/` 目录内创建 `番号-C 演员名/` 文件夹,方便手动拖到 `/mnt/f/av/` 中对应演员目录。 ```bash cd /mnt/f/qbittorrent/failed mkdir -p "ADN-016-C 明日見未来" # ... 以此类推 ``` ### 3. 按演员分组(移动目录到演员子目录) 若目录直接放在 `/mnt/f/av/` 根目录下,需要移动到对应演员子目录: ```bash cd /mnt/f/av mkdir -p "明日見未来" mv "ADN-016-C 明日見未来" "明日見未来/" # ... 以此类推 ``` ### 4. 读取 nfo 获取演员信息 每个作品的 nfo 文件包含元数据,用 Python 解析: ```python import xml.etree.ElementTree as ET tree = ET.parse('番号.nfo') root = tree.getroot() actors = [a.find('name').text for a in root.findall('actor')] dvd_id = root.find('num').text ``` ### 5. 封面图刮削 尝试从以下来源下载封面图: #### 5.1 FlareSolverr + Clash 代理(首选) ```bash FLARE="http://127.0.0.1:8191/v1" CLASH_PROXY="http://proxy:***@host.docker.internal:7443" # FlareSolverr API 请求格式 curl -s "$FLARE" -d '{ "cmd":"request.get", "url":"https://javdb.com/search?q=番号&f=all", "maxTimeout":45000, "proxy":{"url":"'$CLASH_PROXY'"} }' -H "Content-Type: application/json" ``` 从返回的 JSON 中提取 `solution.response` 中的 HTML,解析出: - 详情页链接 `href="/v/xxx"` - 详情页中 `class="video-cover"` 的 `src` 属性(封面图片 URL) 然后通过 Clash 代理下载图片: ```bash curl -x "http://proxy:***@127.0.0.1:7443" -s -L -o "poster.jpg" \ -H "Referer: https://javdb.com/" "$POSTER_URL" ``` #### 5.2 备用:Python socks5 直连 ```python import socks, socket socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 7443, username="proxy", password="***", rdns=True) socket.socket = socks.socksocket import urllib.request, re req = urllib.request.Request("https://javdb.com", headers={ "User-Agent": "Mozilla/5.0"}) ``` #### 5.3 已知限制 - JavDB 有 Cloudflare 反爬,Python `requests`/`cloudscraper` 均可能被拦截 - FlareSolverr 走 HTTP 代理时可能无法完成 Cloudflare JS 挑战 - FANZA/DMM 图片 CDN 返回小图(~3KB),真实大图需 JS 渲染 - 最可靠方案:**Windows 端浏览器手动下载** ### 6. 图片命名规则 - `/mnt/f/av/` 格式: `poster.jpg` + `fanart.jpg`(两图相同) - `/mnt/e/01_automated/日本电影/` 格式: `番号-poster.jpg` + `番号-thumb.jpg` ## 注意事项 - **WSL 操作 /mnt 文件极慢**:大量小文件操作应在 Windows 原生 Python 中执行 - **代理密码注意 shell 展开**:Clash 密码 `5gynj20J` 在 bash 中写为 `"proxy:*"`(用双引号避免 `***` 展开) - **FlareSolverr 密码兼容性**:SOCKS5 代理认证不支持通过环境变量传递。HTTP 代理用 `proxy` 参数 - **Clash 端口**:mixed-port 7443,同时支持 HTTP 和 SOCKS5 - **删除冗余的字幕目录**:`*-中文字幕/` 目录中的 `.srt` 与 `failed/` 目录中的 `.chs.srt` 多数是重复文件(MD5 一致) ## 依赖检查 ```bash # FlareSolverr docker ps | grep flaresolverr # Clash docker ps | grep clash # Python python3 --version pip3 list 2>/dev/null | grep -i cloudscraper ```