IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python-qbittorrent+爬虫第二弹:爬取国内某bt站内容、分析页面,批量导入qbittorrent并下载归档 -> 正文阅读

[Python知识库]python-qbittorrent+爬虫第二弹:爬取国内某bt站内容、分析页面,批量导入qbittorrent并下载归档

????????书接上文,说到想批量下载电影,通过一个数据库获取了所有下载内容的链接,所以这个数据库从那里来呢?当然要依靠我们万能的python了,正好我最近在用一个bt站,又很想从上面找日剧看,奈何一个一个搜索下载太麻烦了,更不要说搭建好qbittorrent的webui,然后从nas下载了。

?

? ? ? ? ?基本架构:用python获取日剧信息,然后从中间获得清晰度最高的种子,然后传输到局域网的nas下载。

????????

? ? ? ? 先来看看爬虫的核心部分吧~后面有源码!

? ? ? ? 首先当然是打开搜索页面,发现即使按照日本+日语两个关键词搜索,仍然会有007这样的电影混进其中,因此需要改进,改进方法就是从html中抓取是否包含“语 ? ??言 日语”以及“地 ? ? 域 日本”这样的关键词。第一个部分的源代码如下:

import requests
import re
import time
import random


def getdetail(file, id):
    """
    分析详情页函数
    :param file: 详情页html文件对象
    :return: 一个字典,包含id、译名、清晰度信息、其他版本id、带passkey的url,如果不是日剧就返回空
    """
    with open('log.txt', 'r', encoding='utf8') as logfile:
        logtext = logfile.read()
    if logtext.find(f"'id': {str(id)}") != -1:
        print('getted!:', id)
        return
    return_dic = {
        'id': id,
        'name': '',
        'res': '',
        'url': '',
        'other': []
    }
    text = file.read()
    if text.find('产  地 日本') == -1 or text.find('语  言 日语') == -1:
        return
    res_re = re.compile('<b>分辨率:&nbsp;</b>(.*?)[pi]')
    try:
        return_dic['res'] = int(res_re.findall(text)[0])
    except:
        return_dic['res'] = 0
    other_re = re.compile('a href="https://www\.hdarea\.co/details\.php\?id=(.*?)&amp;hit=1"')
    return_dic['other'] = other_re.findall(text)
    name_re = re.compile('译  名 (.*?)<')
    name_list = name_re.findall(text)
    if name_list:
        if name_list[0].find('/') != -1:
            return_dic['name'] = name_list[0][:name_list[0].find('/')]
        else:
            return_dic['name'] = name_list[0]
    else:
        bad_name = re.compile('">副标题</td><td class="rowfollow" valign="top" align="left">(.*?)</td></tr>').findall(text)[0]
        return_dic['name'] = bad_name[:bad_name.find('/')]

    return_dic['url'] = f'https://www.hdarea.co/download.php?id={str(id)}&passkey=你的passkey~(还想看我的??)'
    print(return_dic)
    with open('log.txt', 'a+') as logfile:
        logfile.write(str(return_dic)+'\n')

????????下面详细介绍一下代码的每个部分在干什么:

? ? ? ? 输入一个html文件读取后的文件对象,以及这个页面对应的id

????????首先定义了一个return_dic的格式,从详情页分析会拿到id、译名、清晰度信息、其他版本id、带passkey的url,如果不是日剧就返回空

? ? ? ? 所以第一步自然是用刚刚订好的筛选条件看看是不是日剧,不是就可以下一个文件了。

? ? ? ? 第二步是用正则表达式尝试匹配一下清晰度,考虑到同时有1080p和1080i,咱们都要匹配上,如果不是按照这样格式写的(反正也不是很多),就给个0吧。随后调试过程中还发现,有一些格式写得很奔放,咱也看不懂但是就是不能这么比,但是会让我们的程序报错,那就给个try吧。

? ? ? ? 之后就是简单地字符串处理,用正则表达式匹配译名等信息(如果译名匹配不到就直接拿它的副标题),用来当作文件夹的名字,随后观察下载的url那一行,把相应的url给拼接好【我也是刚刚知道bt站给的这种https链接中决定下载的文件是什么的唯一凭证居然是那个唯一的id】

? ? ? ? 最后把它写到一个log里面,后续需要批量加入到qbittorrent,只需要连接好webui直接用这个log文件就可以了。

? ? ? ?

? ? ? ? 这段代码等于是整个工作的第二个部分,完成之后还有两个工作:第一个是获取这个getdetail函数中所需要的html文件,可以爬虫一下,然后抓取所有类似于链接的url,提取中间的id方便通信,第二个是读取log.txt,然后加入合适的量下载(一次下多了就怕分享率炸了),但是剩下的没有什么太多技术含量,所以就直接把所有文件的源码摆上来,之后再慢慢聊:

# hdarea_detail.py

import requests
import re
import time
import random


def getdetail(file, id):
    """
    分析详情页函数
    :param file: 详情页html文件对象
    :return: 一个字典,包含id、译名、清晰度信息、其他版本id、带passkey的url,如果不是日剧就返回空
    """
    with open('log.txt', 'r', encoding='utf8') as logfile:
        logtext = logfile.read()
    if logtext.find(f"'id': {str(id)}") != -1:
        print('getted!:', id)
        return
    return_dic = {
        'id': id,
        'name': '',
        'res': '',
        'url': '',
        'other': []
    }
    text = file.read()
    if text.find('产  地 日本') == -1 or text.find('语  言 日语') == -1:
        return
    res_re = re.compile('<b>分辨率:&nbsp;</b>(.*?)[pi]')
    try:
        return_dic['res'] = int(res_re.findall(text)[0])
    except:
        return_dic['res'] = 0
    other_re = re.compile('a href="https://www\.hdarea\.co/details\.php\?id=(.*?)&amp;hit=1"')
    return_dic['other'] = other_re.findall(text)
    name_re = re.compile('译  名 (.*?)<')
    name_list = name_re.findall(text)
    if name_list:
        if name_list[0].find('/') != -1:
            return_dic['name'] = name_list[0][:name_list[0].find('/')]
        else:
            return_dic['name'] = name_list[0]
    else:
        bad_name = re.compile('">副标题</td><td class="rowfollow" valign="top" align="left">(.*?)</td></tr>').findall(text)[0]
        return_dic['name'] = bad_name[:bad_name.find('/')]

    return_dic['url'] = f'https://www.hdarea.co/download.php?id={str(id)}&passkey=你自己的id~~~~~~~~'
    print(return_dic)
    with open('log.txt', 'a+', encoding='utf8') as logfile:
        logfile.write(str(return_dic)+'\n')
    # print(text)

def random_sleep(length):
    real_length = length + random.randint(-1000,1000) / 1000
    time.sleep(real_length)


if __name__ == '__main__':

    path = ''
    with open(path+'detail.html', encoding='utf8') as file:
        getdetail(file, 51665)
# hdarea_search.py

import requests
import re
import time
import random
from hdarea_detail import getdetail, random_sleep


def get_urls(file):
    """
    输入搜索页file对象,返回所有下载url的id
    :param file:
    :return:
    """
    return_list = []
    text = file.read()
    urls_re = re.compile('<a href="details\.php\?id=(.*?)&amp;hit=1&amp;')
    urls_re.findall(text)
    urls_re_return = urls_re.findall(text)
    for url in urls_re_return:
        if url not in return_list:
            return_list.append(url)
    print(return_list)
    print(len(return_list))
    return return_list

def get_all_info():

    header = {
        'Cookie': '你自己的cookie',
        'authority': 'www.hdarea.co',
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15'
    }

    path = ''
    with open(path+'search.html', 'r', encoding='utf8') as file:
        urls_list = get_urls(file)
    for id in urls_list:
        url = f'https://www.hdarea.co/details.php?id={str(id)}&hit=1'
        page = requests.get(url, headers=header)
        with open('detail.html', 'w', encoding='utf8') as detailfile:
            detailfile.write(page.text)
        with open('detail.html', 'r', encoding='utf8') as file:
            getdetail(file, int(id))
        random_sleep(1)


if __name__ == '__main__':
    get_all_info()
# hdarea.py

import requests
from hdarea_search import get_all_info
from hdarea_detail import random_sleep

header = {
    'Cookie': '你的cookie',
    'authority': 'www.hdarea.co',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15'
}

for i in range(0, 36):
    url = f'你在该站点搜索需要的内容的时候上面的url'
    page = requests.get(url, headers=header)
    print(url)
    with open('search.html', 'w', encoding='utf8') as detailfile:
        detailfile.write(page.text)
    get_all_info()
    random_sleep(5)
# hdarea_qbittorrent.py

from qbittorrent import Client
import time


def connect_to_qbit():
    qb = Client('你的qbittorrent地址')

    qb.login('你的账号', '你的密码')
    # not required when 'Bypass from localhost' setting is active.
    # defaults to admin:admin.
    # to use defaults, just do qb.login()

    torrents = qb.torrents()
    return qb, torrents


def get_biggest(log_dic, id_num):
    """
    :param log_dic: 处理完成的id:信息 字典
    :param id_num: 待查找的id
    :return: 返回同类文件中清晰度最高的id
    """
    if not log_dic[id_num]['other']:
        return id_num
    else:
        biggest_res = -1
        return_id_num = 0
        for other_id_num in log_dic[id_num]['other']:
            try:
                if log_dic[other_id_num]['res'] > biggest_res:
                    return_id_num = other_id_num
            except:
                pass
        return return_id_num


def log_file_init():
    """
    :return:读取log.txt文件并将内容初始化成为id:内容的字典
    """
    log_list = []
    with open('log.txt', 'r', encoding='utf8') as file:
        lines = file.readlines()
        for line in lines:
            log_list.append(eval(line))
    log_dic = {}
    for log in log_list:
        log_dic.update({log['id']: log})
    return log_dic
    # 读入log文件,并将id作为字典的key,信息作为字典的值


def qbit_download(qb, log_keyarg, id_num):
    """
    :param qb: qb的client对象
    :param log_keyarg: 记录信息的字典
    :param id_num: 信息的id
    :return: no
    """
    savepath = f'/share/CACHEDEV4_DATA/movie/{log_keyarg["name"]}'  # 这是我希望的在nas内的存储位置
    qb.download_from_link(log_keyarg['url'], savepath=savepath)
    localtime = time.asctime(time.localtime(time.time()))
    with open('dl_log.txt', 'a', encoding='utf8') as dl_log_file:
        dl_log_file.write(str(id_num) + str(localtime) + '\n')
    print(f'download:{id_num}, time:{localtime},')


def qbit_main(start=0, end=0):
    qb, torrents = connect_to_qbit()
    log_dic = log_file_init()
    s = start
    for id_num in log_dic.keys():
        if id_num == get_biggest(log_dic, id_num):  # 这条就是最清楚的,可以下载!
            qbit_download(qb, log_dic[id_num], id_num)
        s += 1
        print(f'第{s}条任务:', log_dic[id_num])
        if s == end:
            break

if __name__ == '__main__':
    # qb, torrents = connect_to_qbit()
    qbit_main(0, 40)

每个文件实现的功能:

hdarea.py项目的最终main文件,在获得了log之后会控制直接读取log内的内容并将下载任务传到qbit的网页端
hdarea_search.py实现从搜索页提取详情页的功能,简单分析页面就可以写出来
hdarea_detail.py实现从详情页提取关键信息并输出到log文件的过程
hdarea_qbittorrent.py实现将下载任务传到qbit的网页端的过程

值得注意的是源代码中我隐藏了部分信息:

????????一个是cookie,读者们注册完bt站之后访问可以从开发者选项中看到本次请求的cookie,把自己的cookie换过来就好,注意不要被其他人看到啦~

????????另外一个就是torrent站的passkey,这个非常非常重要!它是torrent站识别身份的唯一信息,也就是说是谁在上传下载,纯靠这个passkey判定,如果被别人知道了,别人大概会拿你的账户猛下东西,你如果没来得及重制passkey,你大概就可以准备新账号了。

? ? ? ? 第三个是看似没有那么重要的qbit的webui的账号密码,别人最多使用你的qbit客户端,但是之前有通过qbit客户端入侵机器锁定文件然后勒索的先例,也请大家注意不要泄露出去啦~

如果有源码使用和优化、以及其余问题欢迎直接在评论区交流~

封面

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-12-02 16:42:32  更:2021-12-02 16:42:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:38:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码