主题
下载器的自动化链路:搜、下、搬、清
我的下载流程早就不打开界面了。整套是五个环节串起来的:
搜索资源 → 加任务 → 监控完成 → 归档到媒体库 → 删种子每一环单独看都很简单,但它们之间有四个"手动的坑",如果不管,你就会每天花时间在搬文件上。这篇讲这五环怎么用 HTTP API 串起来。
一、搜索:拿到磁力链接
自己找资源站的搜索接口,比用浏览器自动化稳定一百倍。核心是看它的搜索页有没有一个可以直接拼的 URL:
https://<资源站>/search?q=<关键词>&p=<页码>很多站返回的是 HTML,用正则抓就行,不需要无头浏览器:
python
results = []
for page in range(1, 4):
html = get(f"{BASE}/search?q={quote(keyword)}&p={page}")
for m in re.finditer(r'magnet:\?xt=urn:btih:[a-zA-Z0-9]{32,40}[^"<\s]*', html):
results.append(m.group(0))页数给 3 页就够了。 同一个片子,前十来条结果基本覆盖了所有还活着的源。
⚠️ 注意资源站的域名经常换、国内访问可能需要代理。搜索失败时先判断是内容没有还是网络不通(curl -o /dev/null -w '%{http_code}' 看一眼),别混为一谈。
二、加任务:qBittorrent 的 WebAPI
qBittorrent 有个挺完整的 HTTP API。整套流程只需要三个调用:
bash
# 1) 登录,拿 cookie
curl -s -c /tmp/qbt.txt \
--data "username=admin&password=<密码>" \
http://127.0.0.1:8080/api/v2/auth/login
# 返回 "Ok." 就是成功。注意:它用 cookie,不是 token
# 2) 加任务(磁力记得带 tracker,见后面)
curl -s -b /tmp/qbt.txt \
http://127.0.0.1:8080/api/v2/torrents/add \
--data-urlencode "urls=$MAGNET" \
--data-urlencode "savepath=/data/downloads"
# 3) 查进度(按 hash 或看全量列表)
curl -s -b /tmp/qbt.txt http://127.0.0.1:8080/api/v2/torrents/info | jq '.[] | {name, progress, state}'state 的取值很关键:
metaDL—— 还在要元数据(卡住就是死种,见磁力那篇)downloading/stalledDL—— 在下 / 卡住了uploading/stalledUP—— 下完了(BT 客户端下完即做种,所以"完成"的标记是uploading)
"完成"的判断不要用 progress == 1 一个条件,stalledDL 时进度可能是 0.999。用 state in (uploading, stalledUP, pausedUP) 更稳。
三、监控:怎么知道下完了
两种做法,各有适用场景:
A. 轮询 API(推荐)
python
while True:
info = qbt_torrents()
if all(t["state"].startswith(("uploading", "pausedUP", "stalledUP")) for t in info):
break
time.sleep(300) # 5 分钟一次就够B. 看文件系统(下载器的"临时文件"特征)
很多下载器边下边写临时文件,下完了才改成正式扩展名:
movie.mkv.!qB ← 下载中(qBittorrent 的临时后缀)
movie.mkv ← 完成
video.xltd ← 迅雷的临时文件所以一个"每 5 分钟检查有没有新 .mkv 出现"的脚本,也能判断完成。但这是启发式的,BT 分片下载可能很早就创建了目标文件。能查 API 就别猜文件系统。
四、归档:搬进媒体库
这一步是大多数人手工做的部分。搬到媒体库有两个必须注意的点:
1. 先看目录结构。 下载下来的通常是 [站名] 片名 (年份) [分辨率][编码]/ 这种目录,里面才是视频文件。搬的时候整个目录搬,别只搬文件,否则字幕、nfo、样片全丢。
2. 顺序:先移文件,再删任务。
反过来做(先删任务、勾选删除文件)就把片子一起删了。这个错我犯过一次,不用再犯。
3. 目录名带中文/全角括号/emoji 是常态。 脚本里所有路径都要加引号,用 --data-urlencode 或等价方式传参,别自己拼 shell 字符串。
五、清理:删种子,防 PCDN
这一步被严重低估。BT 客户端下完之后默认继续做种,持续上传。家用宽带下这可能触发两个后果:
- 运营商把"持续大流量上行"当成 PCDN 特征,限速甚至断网
- 上传占满,别的服务(远程访问、同步)全卡
所以下完就该清:
bash
# 删任务但保留文件(文件已经搬到媒体库了)
curl -s -b /tmp/qbt.txt http://127.0.0.1:8080/api/v2/torrents/delete \
--data-urlencode "hashes=$HASH" --data "deleteFiles=false"⚠️ deleteFiles=false 还是 true 取决于你的流程:
- 文件已经移动到媒体库 →
false(下载目录里那份已经不在了,删了也无所谓,但 false 更安全) - 文件还在下载目录、你要保留它 →
false,然后自己搬 - 确定不要了 →
true
另外顺手看一眼种子备份目录,清完之后应该是空的或只有活着的任务:
bash
ls /path/to/qbt/config/BT_backup/ | wc -l整条链路的骨架
python
def grab(keyword, target_dir):
magnets = search(keyword) # 搜索,拿候选
if not magnets:
return "没找到资源"
magnet = pick(magnets[0]) # 选一个(带 tracker)
h = add_torrent(magnet, SAVE_PATH) # 加任务
wait_until_done(h) # 轮询到完成
move_to_library(h, target_dir) # 归档(先搬)
delete_torrent(h, delete_files=False) # 清种子(后删)
return "好了"四个"手动的坑"总结
- 磁力链接不带 tracker → 卡 metaDL(单独的坑)
- 完成判断只看进度 →
stalledDL的 0.999 让你白等 - 先删任务再搬文件 → 片子没了
- 下完不清种子 → 持续上传,可能被限速
一句话版本:搜索抓 HTML 就够,别上浏览器;完成判断看
state不看progress;归档永远"先搬后删";下完就删种子。