Python3使用bencode库解析BT种子

Python3 使用 bencode库 解析BT种子

前言

由于本人也是初学者,所以,请多包涵,本文使用的IDE是PyCharm2019

由于第一次写博客,多少有点拘谨

废话不多说,直接上代码

源码下载

https://download.csdn.net/download/qq_43777162/11834495

代码部分

首先导入bencode库

from bencode import *

导库:
建议使用pip 命令导入dencode库,我的已经安装好的,
在这里插入图片描述
因为pip install bencode导入的bencode库可能出问题报以下错误,

在这里插入图片描述

所以使用 pip install py3-bencode

然后编写解析类:

class GetTorrent():
    def getBT(self, file_path):
        with open(file_path, 'rb+') as fp:
            message = bdecode(fp.read())
            return message

    def getMessage(self, message, mode='print'):
        # print(type(message))
        print("发现了一下信息:")
        i_lsit = []
        if mode == 'print':
            for i in message:
                i_lsit.append(i)
                print(i)
        elif mode == 'return':
            return i_lsit

    # 获得tracker数据
    def getannounce(self, message, mode='print'):
        if mode == 'print':
            print("=" * 50, "announce", "=" * 50)
            print("announce的数据类型为:", type(message[b'announce']))
            print("tracker服务器列表:")
            print(message[b'announce'].decode())
        elif mode == 'return':
            return message[b'announce'].decode()

    # 获得备用备用tracker服务器列表
    def getannounce_list(self, message, mode='print'):
        line_lsit = []
        if mode == 'print':
            print("=" * 50, "announce-list", "=" * 50)
            print("announce-list的数据类型为:", type(message[b'announce-list']))
            print("备用tracker服务器列表:")
            for udp_list in message[b'announce-list']:
                for line in udp_list:
                    line_lsit.append(line.decode)
                    print(line.decode())
        elif mode == 'return':
            return line_lsit

    # 获得种子文件的注释
    def getcomment(self, message, mode='print'):
        if mode == 'print':
            print("=" * 50, "comment", "=" * 50)
            print(message[b'comment'].decode())
        elif mode == 'return':
            return message[b'comment'].decode()

    # 获得创建人或创建程序的信息
    def getcreatedby(self, message, mode='print'):
        if mode == 'print':
            print("=" * 50, "created by", "=" * 50)
            print("创建人或创建程序的信息:", message[b'created by'].decode())
        elif mode == 'return':
            return message[b'created by'].decode()

    # 获得编码方式(经测试,有相当一部分的BT种子没有该信息)
    def getencoding(self, message, mode='print'):
        if mode == 'print':
            print("=" * 50, "encoding", "=" * 50)
            print("encoding的类型是:", type(message[b'encoding']))
            print("获得编码方式:", message[b'encoding'].decode())
        elif mode == 'return':
            return message[b'encoding'].decode()

    # 关于下载的文件的信息(包含了文件名,还有是单文件还是多文件)
    def getinfo(self, message):
        # 获得每个文件里面的类容方法
        def getfilename(files_v):
            # 判断值是否为列表
            if isinstance(files_v, list):
                # 历遍列表
                for file_name in files_v:
                    # 如果列表里面的字符串是bytes类型的则转码,否则直接输出
                    if type(file_name) == bytes:
                        return file_name.decode()
                    else:
                        return file_name
            # 当不是列表时,直接输出(一般为int型目前没发现其他类型)
            else:
                return files_v

        print("=" * 50, "info", "=" * 50)
        # print("info的数据类型为:", type(message[b'info']))
        # 历遍所有的keys
        for k in message[b'info'].keys():
            # print("key:", k)
            value = message[b'info'][k]
            # print("value", value)
            # 如果是files
            if k == b'files':
                # 遍历files列表
                print("该BT种子里总共有%d个文件" % len(value))
                v_i = 0
                for v_list_dic in value:
                    # 遍历列表里的字典得到每一个文件
                    print("第%d个文件" % v_i)
                    for files_k, files_v in v_list_dic.items():
                        data = getfilename(files_v)
                        if files_k == b'length':
                            print("文件大小:%0.2f%s" % (data / 1024 / 1024, "MB"))
                        elif files_k == b'path':
                            print("文件名:", data)
                        else:
                            print(files_k, ":", data)
                    v_i += 1;

            # 如果是是文件名:
            elif k == b'name':
                print("文件名:", value.decode())
            # 如果是文件的MD5校验和:
            elif k == b'md5sum  ':
                # print(type(value))
                print("长32个字符的文件的MD5校验和:", value)
            # 文件长度
            elif k == b'length':
                # print(type(value))
                print("文件长度,单位字节:", value / 1024, "KB")
            elif k == b'path':
                # print(type(value))
                print("文件的路径和名字:", value)
            elif k == b'piece length':
                # print(type(value))
                print("每个块的大小:", value / 1024 / 1024, "MB")
            elif k == b'pieces':
                # print(type(value))
                print("每个块的20个字节的SHA1 Hash的值(二进制格式) :", str(value))
            elif k == b'piece length':
                # print(type(value))
                print("每个块的大小,单位字节:", value, "B")

            # print("value", v)

    # 获得节点主机信息(好多BT种子没有)
    def getnode(self, message, mode='print'):
        if mode == 'print':
            print("=" * 50, "nodes", "=" * 50)
            print("nodes的数据类型为:", type(message[b'nodes']))
            print(message[b'nodes'])
        elif mode == 'return':
            return message[b'nodes']


代码测试

if __name__ == '__main__':
    # 创建解析对象
    gettorrent = GetTorrent()

    # 解析BT种子
    message = gettorrent.getBT(r"./test.torrent")

    # 将所有方法加入列表
    func_list = [gettorrent.getMessage,
                 gettorrent.getannounce,
                 gettorrent.getannounce_list,
                 gettorrent.getcomment,
                 gettorrent.getcreatedby,
                 gettorrent.getencoding,
                 gettorrent.getinfo,
                 gettorrent.getnode
                 ]

    # 利用循环使用方法
    # 可能有一些信息是没有的,所以引发异常
    for func in func_list:
        try:
            func(message)
        except Exception as e:
            print("异常为:", e)
            continue

效果图

在这里插入图片描述

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Android开发下载功能涉及到很多技术要点,包括网络通信、多线程、存储管理、数据解析等,下面是一些具体实现的思路: 1. 网络通信 下载功能需要通过网络获取资源,最基本的方式是使用HttpURLConnection或HttpClient等类来实现HTTP协议的传输。如果要实现Https协议的下载,需要使用HttpsURLConnection或HttpClient等类。 对于磁力链接和Thunder链接的下载,可以使用第三方如Aria2 RPC来实现,这样可以将下载任务交给Aria2服务器处理,Android客户端只需要提供下载链接即可。 对于BT下载,需要使用BT协议来下载资源,可以使用一些第三方如libtorrent等来实现。 2. 多线程 下载功能一般都需要实现多线程下载,以提高下载速度。具体实现可以使用Java中的多线程技术,比如使用Thread或Runnable接口来创建线程,使用ThreadPoolExecutor等类来管理线程池。 3. 存储管理 下载的文件需要存储到本地,Android系统提供了不同的存储方式,可以选择内部存储或外部存储。对于大文件的下载,可以使用断点续传技术来实现,这样可以在下载中断后恢复下载,减少用户的等待时间。 4. 数据解析 对于一些需要解析的资源,比如BT种子文件,需要使用相关的解析解析数据,获取下载链接等信息。常用的解析包括Bencode、TorrentParser等。 综上所述,Android开发下载功能需要涉及到网络通信、多线程、存储管理、数据解析等技术,需要根据具体的需求来选择实现方式和第三方
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值