python操作种子文件的几点心得

本文最后更新于:6 个月前

前言


之前在写种鸡的时候,免不了要对种子进行操作,python相对第三方库比较完备,所以整理一篇看看我们能够用python实现哪些功能,也欢迎大家补充。

实现功能


  1. 获取种子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"))
  1. 解析种子内部
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字段。同时还可以解析出文件的结构。

  1. 清洗种子

其实也是使用上边的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字段或者新增字段等等。

  1. 制作种子

有的时候源种子文件有一些图片,字幕,我们不想要,由于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
  1. 顺带说一下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', [])

好吧,今天的内容就到这里结束了。

总结


都是第三方包的应用,只要善于搜索尝试总结,就可以掌握了。



本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!