python操作种子文件的几点心得
本文最后更新于:2 年前
前言
之前在写种鸡的时候,免不了要对种子进行操作,python相对第三方库比较完备,所以整理一篇看看我们能够用python实现哪些功能,也欢迎大家补充。
实现功能
- 获取种子hash值
一般来说,我们需要根据hash值获取客户端内的种子信息,或者在做备份或者更换种子路径的时候就需要比对。
import hashlib
import bencode # 注意安装的模块名叫bencode.py
def get_hash(filename):
with open(filename, 'rb') as f:
torrent_data = f.read()
metainfo = bencode.bdecode(torrent_data)
info = metainfo['info']
return hashlib.sha1(bencode.bencode(info)).hexdigest()
if __name__=="__main__":
print(get_hash(r"J:\PTP种子\[OpenCD].蔡琴 - 常青树 (2008) FLAC.torrent"))
- 解析种子内部
import torrent_parser as tp
torrent_path = r"E:\PTP种子\[NPUBits].Ad.Astra.2019.1080p.BluRay.DDP.7.1.x264-Geek.mkv.torrent"
data = tp.parse_torrent_file(torrent_path)
print(data)
输出结果(单文件):
{
'announce': 'http://6.npupt.com/announce.php?passkey=xxxxxxxxxxxxxxxxxxxxxxxxxxx',
'announce-list': [
[
'http://6.npupt.com/announce.php?passkey=xxxxxxxxxxxxxxxxxxxxxxxxxxx'
],
[
'http://4.npupt.com/announce.php?passkey=xxxxxxxxxxxxxxxxxxxxxxxxxxx'
]
],
'comment': 'http://passthepopcorn.me/torrents.php?id=207584&torrentid=734627',
'created by': 'qBittorrent v4.1.9.1',
'creation date': 1576502187,
'info': {
'length': 19108558519,
'name': 'Ad.Astra.2019.1080p.BluRay.DDP.7.1.x264-Geek.mkv',
'piece length': 8388608,
'pieces': [],
'private': 1,
'source': '[npupt.com] 蒲公英PT站'
}
}
多文件的其实也差不多,我们可以解析出来的东西包括tracker,种子制作时间,制作工具,文件大小,块的数量,以及source和comment字段。同时还可以解析出文件的结构。
- 清洗种子
其实也是使用上边的torrent_parse模块,比如我们需要更换trcker。
import torrent_parser as tp
torrent_path = r"E:\PTP种子\[NPUBits].Ad.Astra.2019.1080p.BluRay.DDP.7.1.x264-Geek.mkv.torrent"
data = tp.parse_torrent_file(torrent_path)
data['announce'] = 'what you want here'
new_torrent_path = './test.torrent'
tp.create_torrent_file(new_torrent_path, data)
这样就把tracker换了,友情提示,貌似换了tracker也不能改变种子的hash,可以尝试改改source字段或者新增字段等等。
- 制作种子
有的时候源种子文件有一些图片,字幕,我们不想要,由于pieces字段极长,我们也不太清楚其内部生成机理,所以还是重新制作种子比较方便。比如种鸡在遇到FileList内部含有字幕文件的时候就得重新制作了:
from torrentool.torrent import Torrent
import os
target_path = "the dir you want to bencode"
if os.path.isdir(target_path): # 判断是不是目录
files = os.listdir(target_path)
if any([item.endswith('.srt') for item in files]): # 目录中有字幕文件就重新制作,当然也可以解析种子源文件
# 进行重新制作,一般还比较花时间的~
file_data = Torrent.create_from(target_path)
file_data.announce_urls = [b'https://hudbt.hust.edu.cn/announce.php'] # 写入你自己想要填写的tracer
file_data.to_file(origin_torrent_path)
由于Torrent制作的时候如果碰到是文件夹,不会判断里边是不是有字幕文件等等,所以我们修改一下Torrent.py的源代码
@classmethod
def _get_target_files_info(cls, src_path: Path) -> Tuple[List[Tuple[str, int, List[str]]], int]:
is_dir = src_path.is_dir()
src_path = f'{src_path}' # Force walk() to return unicode names.
target_files = []
if is_dir:
for base, _, files in walk(src_path):
for file in files:
if file.endswith(('srt', 'ass', 'ssa')): # 这里我们把字幕文件移除了,当然也可以自己设定,或者改写函数传递一个filter更加合理
files.remove(file)
target_files.extend([join(base, fname) for fname in sorted(files)])
else:
target_files.append(src_path)
target_files_ = []
total_size = 0
for fpath in target_files:
file_size = getsize(fpath)
if not file_size:
continue
target_files_.append((fpath, file_size, normpath(fpath.replace(src_path, '')).strip(sep).split(sep)))
total_size += file_size
return target_files_, total_size
- 顺带说一下qb下的fastresume文件解析
经常qb会突然崩溃,然后种子文件啥的都还在就是需要重新校验。我们可以找到Back_Up下的种子和fastresume,解析fastresume找到保存路径,直接用qbittorrent-api重新加载种子并且跳过校验。
import bencoder
path = r"J:\BT_backup\000e17466dc95393df0dd92193955310597ac8db.fastresume"
f = open(path, "rb")
d = bencoder.decode(f.read())
for item in d.items():
print(item)
输出结果为:
(b'active_time', 1135879)
(b'added_time', 1599093382)
(b'allocation', b'sparse')
(b'auto_managed', 1)
(b'completed_time', 1599093382)
(b'download_rate_limit', -1)
(b'file-format', b'libtorrent resume file')
(b'file-version', 1)
(b'finished_time', 1135879)
(b'httpseeds', [])
(b'info-hash', b'\x00\x0e\x17Fm\xc9S\x93\xdf\r\xd9!\x93\x95S\x10Yz\xc8\xdb')
(b'last_download', 0)
(b'last_seen_complete', 1599205887)
(b'last_upload', 1793133)
(b'libtorrent-version', b'1.2.6.0')
(b'max_connections', 100)
(b'max_uploads', -1)
(b'num_complete', 4)
(b'num_downloaded', 16777215)
(b'num_incomplete', 0)
(b'paused', 0)
(b'peers', b'\xb7\xb2\xc5g\x86\x88p0F\\\xc78\xdd\xe8\xba\x1cA\xf2')
(b'peers6', b'')
(b'pieces', b'')
(b'qBt-category', b'\xe7\x94\xb5\xe5\xbd\xb1')
(b'qBt-hasRootFolder', 1)
(b'qBt-name', b'')
(b'qBt-queuePosition', 0)
(b'qBt-ratioLimit', -2000)
(b'qBt-savePath', b'W:\\HUDBT-2019-06-09\\')
(b'qBt-seedStatus', 1)
(b'qBt-seedingTimeLimit', -2)
(b'qBt-tags', [])
(b'qBt-tempPathDisabled', 0)
(b'save_path', b'W:\\HUDBT-2019-06-09\\')
(b'seed_mode', 0)
(b'seeding_time', 1135879)
(b'sequential_download', 0)
(b'stop_when_ready', 0)
(b'super_seeding', 0)
(b'total_downloaded', 0)
(b'total_uploaded', 15383212222)
(b'trackers', [[b'https://www.hddolby.com/announce.php?passkey=xxxxxxxxxxxxxxxxxxxxxxxxxxxx']])
(b'upload_rate_limit', -1)
(b'url-list', [])
好吧,今天的内容就到这里结束了。
总结
都是第三方包的应用,只要善于搜索尝试总结,就可以掌握了。