Python编写GUI界面,实现小说下载器

news2025/8/2 8:08:10

嗨害大家好鸭!我是小熊猫~

在这里插入图片描述

源码资料电子书:点击此处跳转文末名片获取

思路

一、数据来源分析

1. 明确需求:

  • 采集的网站是什么?
    https://www.biqudu.net/1_1631/3047505.html
  • 采集的数据是什么?
    标题/内容
    分析 标题/内容 是从哪里来的
    通过浏览器自带工具: 开发者工具抓包分析
  • 打开开发者工具: F12 / 鼠标右键点击检查选择network
  • 刷新网页
  • 搜索数据, 找到数据包
    https://www.biqudu.net/1_1631/3047505.html

二. 代码实现步骤

1. 发送请求, 模拟浏览器对于url地址发送请求
请求链接: https://www.biqudu.net/1_1631/3047505.html
2. 获取数据, 获取服务器返回响应数据内容
开发者工具: response
3. 解析数据, 提取我们想要的数据内容
标题/内容
4. 保存数据, 把数据保存本地文件

在这里插入图片描述


代码实现

有个视频教程给大家录好啦,但是C站放不上来

源码资料电子书:点击此处跳转文末名片获取

在这里插入图片描述

一、单章小说下载

- 发送请求
- 获取数据

import requests
url = '网站链接'
headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
}
response = requests.get(url=url, headers=headers)
print(response)
print(response.text)

- 解析数据

import requests  
import re 
import parsel 

url = 'https://www.biqudu.net/1_1631/3047505.html'
headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
}
response = requests.get(url=url, headers=headers)
print(response)

selector = parsel.Selector(response.text)
title = selector.xpath('//*[@class="bookname"]/h1/text()').get()
content = '\n'.join(selector.xpath('//*[@id="content"]/text()').getall())
print(title)
print(content)

- 保存数据

import requests
import re
import parsel
 
url = 'https://www.biqudu.net/1_1631/3047505.html'
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
}
response = requests.get(url=url, headers=headers)
print(response)

selector = parsel.Selector(response.text)
title = selector.xpath('//*[@class="bookname"]/h1/text()').get()
content = '\n'.join(selector.xpath('//*[@id="content"]/text()').getall())
print(title)
print(content)
with open(title + '.txt', mode='a', encoding='utf-8') as f:
    """
    第一章 标题
        小说内容
    第二章 标题
        小说内容
    """
    f.write(title)
    f.write('\n')
    f.write(content)
    f.write('\n')

二、整本小说下载

import requests
import re
import parsel
import os
 
 
list_url = 'https://www.biqudu.net/1_1631/'
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
}
html_data = requests.get(url=list_url, headers=headers).text
name = re.findall('<h1>(.*?)</h1>', html_data)[0]
file = f'{name}\\'
if not os.path.exists(file):
    os.mkdir(file)
 
url_list = re.findall('<dd> <a style="" href="(.*?)">', html_data)
for url in url_list:
    index_url = 'https://www.biqudu.net' + url
    print(index_url)

    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
    }
    response = requests.get(url=index_url, headers=headers)
    print(response)

    selector = parsel.Selector(response.text)
    title = selector.xpath('//*[@class="bookname"]/h1/text()').get()
    content = '\n'.join(selector.xpath('//*[@id="content"]/text()').getall())
    print(title)

    with open(file + title + '.txt', mode='a', encoding='utf-8') as f:
        """
        第一章 标题
            小说内容
        第二章 标题
            小说内容
        """
        f.write(title)
        f.write('\n')
        f.write(content)
        f.write('\n')

三、多线程采集

import requests
import re
import parsel
import os
import concurrent.futures
 
def get_response(html_url):
    """
    发送请求函数
    :param html_url: 请求链接
    :return: response响应对象
    """
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
    }
    response = requests.get(url=html_url, headers=headers)
    return response
 
 
def get_list_url(html_url):
    """
    获取章节url/小说名
    :param html_url: 小说目录页
    :return:
    """
    html_data = get_response(html_url).text
    name = re.findall('<h1>(.*?)</h1>', html_data)[0]
    url_list = re.findall('<dd> <a style="" href="(.*?)">', html_data)
    return name, url_list
 
 
def get_content(html_url):
    """
    获取小说内容/小说标题
    :param html_url: 小说章节url
    :return:
    """
    html_data = get_response(html_url).text
    title = re.findall('<h1>(.*?)</h1>', html_data)[0]
    content = re.findall('<div id="content">(.*?)<p>', html_data, re.S)[0].replace('<br/><br/>', '\n')
    return title, content
 
 
def save(name, title, content):
    """
    保存数据函数
    :param name: 小说名
    :param title: 章节名
    :param content: 内容
    :return:
    """
    file = f'{name}\\'
    if not os.path.exists(file):
        os.mkdir(file)
    with open(file + title + '.txt', mode='a', encoding='utf-8') as f:
        """
        第一章 标题
            小说内容
        第二章 标题
            小说内容
        """
        f.write(title)
        f.write('\n')
        f.write(content)
        f.write('\n')
    print(title, '已经保存')
 
 
def main(home_url):
    title, content = get_content(html_url=home_url)
    save(name, title, content)
 
 
if __name__ == '__main__':
    url = 'https://www.biqudu.net/1_1631/'
    name, url_list = get_list_url(html_url=url)
    exe = concurrent.futures.ThreadPoolExecutor(max_workers=7)
    for url in url_list:
        index_url = 'https://www.biqudu.net' + url
        exe.submit(main, index_url)
    exe.shutdown()

四、采集排行榜所有小说

import requests
import re
import parsel
import os
 
def get_response(html_url):
    """
    发送请求函数
    :param html_url: 请求链接
    :return: response响应对象
    """
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
    }
    response = requests.get(url=html_url, headers=headers)
    return response
 
 
def get_list_url(html_url):
    """
    获取章节url/小说名
    :param html_url: 小说目录页
    :return:
    """
    html_data = get_response(html_url).text
    name = re.findall('<h1>(.*?)</h1>', html_data)[0]
    url_list = re.findall('<dd> <a style="" href="(.*?)">', html_data)
    return name, url_list
 
 
def get_content(html_url):
    """
    获取小说内容/小说标题
    :param html_url: 小说章节url
    :return:
    """
    html_data = get_response(html_url).text
    title = re.findall('<h1>(.*?)</h1>', html_data)[0]
    content = re.findall('<div id="content">(.*?)<p>', html_data, re.S)[0].replace('<br/><br/>', '\n')
    return title, content
 
 
def save(name, title, content):
    """
    保存数据函数
    :param name: 小说名
    :param title: 章节名
    :param content: 内容
    :return:
    """
    file = f'{name}\\'
    if not os.path.exists(file):
        os.mkdir(file)
    with open(file + title + '.txt', mode='a', encoding='utf-8') as f:
        """
        第一章 标题
            小说内容
        第二章 标题
            小说内容
        """
        f.write(title)
        f.write('\n')
        f.write(content)
        f.write('\n')
    print(title, '已经保存')
 
def get_novel_id(html_url):
    """
    获取小说ID
    :param html_url: 某分类的链接
    :return:
    """
    novel_data = get_response(html_url=html_url).text
    selector = parsel.Selector(novel_data)
    href = selector.css('.l .s2 a::attr(href)').getall()
    href = [i.replace('/', '') for i in href]
    return href
 
 
def main(home_url):
    href = get_novel_id(html_url=home_url)
    for novel_id in href:
        novel_url = f'https://www.biqudu.net/{novel_id}/'
        name, url_list = get_list_url(html_url=novel_url)
        print(name, url_list)
        for url in url_list:
            index_url = 'https://www.biqudu.net' + url
            title, content = get_content(html_url=index_url)
            save(name, title, content)
        break
 
 
if __name__ == '__main__':
    html_url = 'https://www.biqudu.net/biquge_1/'
    main(html_url)

五、搜索小说功能

- 模块

import requests
import re
import parsel
import os
import prettytable as pt

- 发送请求函数

def get_response(html_url):
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
    }
    response = requests.get(url=html_url, headers=headers)
    return response

- 获取章节url/小说名

def get_list_url(html_url):
    html_data = get_response(html_url).text
    name = re.findall('<h1>(.*?)</h1>', html_data)[0]
    url_list = re.findall('<dd> <a style="" href="(.*?)">', html_data)
    return name, url_list

- 获取小说内容/小说标题

def get_content(html_url):
    html_data = get_response(html_url).text
    title = re.findall('<h1>(.*?)</h1>', html_data)[0]
    content = re.findall('<div id="content">(.*?)<p>', html_data, re.S)[0].replace('<br/><br/>', '\n')
    return title, content

- 保存数据函数

def save(name, title, content):
    file = f'{name}\\'
    if not os.path.exists(file):
        os.mkdir(file)
    with open(file + name + '.txt', mode='a', encoding='utf-8') as f:
        f.write(title)
        f.write('\n')
        f.write(content)
        f.write('\n')
    print(title, '已经保存')

- 获取小说ID

def get_novel_id(html_url):
    novel_data = get_response(html_url=html_url).text
    selector = parsel.Selector(novel_data)
    href = selector.css('.l .s2 a::attr(href)').getall()
    href = [i.replace('/', '') for i in href]
    return href

- 搜索功能

def search(word):
    search_url = f'https://www.biqudu.net/searchbook.php?keyword={word}'
    search_data = get_response(html_url=search_url).text
    selector = parsel.Selector(search_data)
    lis = selector.css('.novelslist2 li')
    novel_info = []
    tb = pt.PrettyTable()
    tb.field_names = ['序号', '书名', '作者', '书ID']
    num = 0
    for li in lis[1:]:
        name = li.css('.s2 a::text').get()
        novel_id = li.css('.s2 a::attr(href)').get().replace('/', '')
        writer = li.css('.s4::text').get()
        dit = {
            'name': name,
            'writer': writer,
            'novel_id': novel_id,
        }
        tb.add_row([num, name, writer, novel_id])
        num += 1
        novel_info.append(dit)
    print('你搜索的结果如下:')
    print(tb)
    novel_num = input('请输入你想要下载的小说序号: ')
    novel_id = novel_info[int(novel_num)]['novel_id']
    return novel_id

- 主函数

def main(word):
    novel_id = search(word)
    novel_url = f'https://www.biqudu.net/{novel_id}/'
    name, url_list = get_list_url(html_url=novel_url)
    print(name, url_list)
    for url in url_list:
        index_url = 'https://www.biqudu.net' + url
        title, content = get_content(html_url=index_url)
        save(name, title, content)
        
if __name__ == '__main__':
    word = input('请输入你搜索小说名: ')
    main(word)
  • 效果展示

在这里插入图片描述

六、GUI界面

import tkinter as tk
from tkinter import ttk
 
def show():
    name = name_va.get()
    print('输入的名字是:', name)
 
def download():
    name = num_va.get()
    print('输入的序号:', name)
 
root = tk.Tk()
root.title('完整代码添加VX:pytho8987')
root.geometry('500x500+200+200')
name_va = tk.StringVar()

search_frame = tk.Frame(root)
search_frame.pack(pady=10)

tk.Label(search_frame, text='书名 作者', font=('微软雅黑', 15)).pack(side=tk.LEFT, padx=10)
tk.Entry(search_frame, relief='flat', textvariable=name_va).pack(side=tk.LEFT)
 
num_va = tk.StringVar()

download_frame = tk.Frame(root)
download_frame.pack(pady=10)
tk.Label(download_frame, text='小说 序号', font=('微软雅黑', 15)).pack(side=tk.LEFT, padx=10)
tk.Entry(download_frame, relief='flat', textvariable=num_va).pack(side=tk.LEFT)
button_frame = tk.Frame(root)
button_frame.pack(pady=10)
tk.Button(button_frame, text='查询', font=('微软雅黑', 10), relief='flat', bg='#88e2d6', width=10, command=show).pack(side=tk.LEFT, padx=10)
tk.Button(button_frame, text='下载', font=('微软雅黑', 10), relief='flat', bg='#88e2d6', width=10, command=download).pack(side=tk.LEFT, padx=10)
 
columns = ('num', 'writer', 'name', 'novel_id')
columns_value = ('序号', '作者', '书名', '书ID')
tree_view = ttk.Treeview(root, height=18, show='headings', columns=columns)
tree_view.column('num', width=40, anchor='center')
tree_view.column('writer', width=40, anchor='center')
tree_view.column('name', width=40, anchor='center')
tree_view.column('novel_id', width=40, anchor='center')
tree_view.heading('num', text='序号')
tree_view.heading('writer', text='作者')
tree_view.heading('name', text='书名')
tree_view.heading('novel_id', text='书ID')
tree_view.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
root.mainloop()

- 效果展示

在这里插入图片描述

👇问题解答 · 源码获取 · 技术交流 · 抱团学习请联系👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/367738.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【蓝桥集训】第七天——并查集

作者&#xff1a;指针不指南吗 专栏&#xff1a;Acwing 蓝桥集训每日一题 &#x1f43e;或许会很慢&#xff0c;但是不可以停下来&#x1f43e; 文章目录1.亲戚2.合并集合3.连通块中点的数量有关并查集的知识学习可以移步至—— 【算法】——并查集1.亲戚 或许你并不知道&#…

华为OD机试题,用 Java 解【喊 7 的次数重排】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…

大数据开发 - Java入门2

目录Java基础知识注释关键字常量标识符测试题回顾Java基础知识 注释 对程序的解释说明 分类&#xff1a; 单行注释&#xff1a;// 对本行后面的内容进行注释多行注释&#xff1a;/*解释内容 */文档注释 &#xff1a;/** 注释内容*/ --用于产生帮助文档&#xff0c;也有多行注…

高通平台开发系列讲解(SIM卡篇)SIM卡基础概念

文章目录 一、SIM卡基本定义二、卡的类型三、SIM卡的作用三、SIM卡基本硬件结构四、SIM卡的内部物理单元五、卡文件系统沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇文章将介绍SIM的相关组件。 一、SIM卡基本定义 SIM卡是一种智能卡(ICC Card/UICC Card) SIM…

在线客服系统接入网站会员,绑定会员ID,展示会员昵称头像,传递手机号等扩展字段【唯一客服】...

在客服系统聊天链接里&#xff0c;可以带上自己网站的会员信息&#xff0c;例如&#xff1a;昵称、头像、手机号等 具体使用方式如下 聊天链接中增加以下参数&#xff1a; visitor_id: 自有会员visitor_name: 自有会员名称avator: 自有会员头像lang: 多语言 cn 中文 &#xff0…

链接服务器查询导致的阻塞

背景客户反馈数据库在上午10点时出现严重阻塞&#xff0c;阻塞源头会话在等待OLEDB&#xff0c;没有见过这个等待类型&#xff0c;请我们协助分析。现象登录SQL专家云&#xff0c;进入趋势分析&#xff0c;下钻到10点钟的活动会话&#xff0c;看到发生了两次严重的阻塞。转到活…

指针的进阶【上篇】

文章目录&#x1f4c0;1.字符指针&#x1f4c0;2.指针数组&#x1f4c0;3.数组指针&#x1f4bf;3.1.数组指针的定义&#x1f4bf;3.2. &数组名VS数组名&#x1f4bf;3.3.数组指针的使用&#x1f4c0;1.字符指针 int main() {char ch w;char* pc &ch;// pc就是字符指…

数据结构之顺序表篇

一、顺序表概念 二、顺序表各类接口实现 *顺序表初始化 **顺序表销毁 ***顺序表插入操作 ****顺序表删除操作 *****顺序表查找操作 ******顺序表实现打印操作 三、顺序表整体实现源码 *SeqList.h **SeqList.c ***test.c 一、顺序表概念 讲顺序表之前先引入线性表概念&#xff…

可视化服务编排在金融APP中的实践

本文重点介绍了京东金融APP在BFF层实践过程中遇到的问题&#xff0c;并引出可视化服务编排在金融APP中的落地实践&#xff0c;其中重点介绍了可视化服务编排系统的核心功能及实现。 可视化服务编排系统已经稳定支持了金融APP从去年618到现在的所有发版迭代&#xff0c;对人效提…

Apache ActiveMQ安装和使用

文章目录Apache ActiveMQ安装和使用 环境下载安装配置启动登录Apache ActiveMQ安装和使用 环境 Ubuntu20.04 下载 官网&#xff1a;https://activemq.apache.org/download-archives 如下载5.14.4版本&#xff0c;apache-activemq-5.14.4-bin.tar.gz&#xff0c;测试过没问题…

分布式算法 - 一致性Hash算法

一致性Hash算法是个经典算法&#xff0c;Hash环的引入是为解决单调性(Monotonicity) 的问题&#xff1b;虚拟节点的引入是为了解决 平衡性(Balance) 问题。一致性Hash算法引入在分布式集群中&#xff0c;对机器的添加删除&#xff0c;或者机器故障后自动脱离集群这些操作是分布…

MySQL索引类型及原理?一文读懂

一、什么是MySQL索引&#xff1f; MySQL索引是一种数据结构&#xff0c;用于提高数据库查询的性能。它类似于一本书的目录&#xff0c;通过在表中存储指向数据行的引用&#xff0c;使得查询数据的速度更快。 在MySQL中&#xff0c;索引通常是在表上定义的&#xff0c;它们可以…

本地新创建的项目,关联/上传到码云

以下示例以mac为例&#xff0c;window将相关步骤改为windows对应的操作即可1、打开终端&#xff0c;通过终端命令 cd 切换到新建的本地项目目录下&#xff0c;如&#xff1a;&#xff08;/Users/wangcongming/Documents/TuoTuo/mobile_acitvity 为我的新建项目地址&#xff09;…

使用 ChatGPT ,通过自然语言编写 eBPF 程序和追踪 Linux 系统

eBPF 是一项革命性的技术&#xff0c;起源于 Linux 内核&#xff0c;可以在操作系统的内核中运行沙盒程序。它被用来安全和有效地扩展内核的功能&#xff0c;而不需要改变内核的源代码或加载内核模块。今天&#xff0c;eBPF被广泛用于各类场景&#xff1a;在现代数据中心和云原…

「RISC-V Arch」SBI 规范解读

术语 SBI&#xff0c;Supervisor Binary Interface&#xff0c;管理二进制接口 U-Mode&#xff0c;User mode&#xff0c;用户模式 S-Mode&#xff0c;Supervisor mode&#xff0c;监督模式 VS-Mode&#xff0c;Virtualization Supervisor mode&#xff0c;虚拟机监督模式 …

嵌入式 Linux Shell编程

目录 1、shell脚本 2、执行shell脚本 3、shell脚本编写 3.1 shell变量 3.2 标准变量或环境变量 3.4 变量赋值有五种格式 3.5 运算符和表达式 关系运算符 布尔运算符 3.6 Test命令用法 1、判断表达式 2、判断字符串 3.判断整数 4、判断文件 3.7 数组 1、数组定义…

什么是 RPA ?What is robotic process automation (RPA)?

目录 前言 What is a business process? 什么是业务流程? What does "robotic process automation" mean?“机器人过程自动化”是什么意思? What is robotic process automation (RPA)?什么是机器人流程自动化 (RPA)? What

SGI 空间配置器

前言 空间配置器是 STL 六大组件之一&#xff0c;它总是隐藏在容器的背后&#xff0c;默默工作&#xff0c;默默付出。本文为《STL 源码剖析》读书笔记&#xff0c;主要讨论 SGI 版本空间的配置和释放&#xff0c;对代码进行解读时会改变一些写法&#xff0c;使其更易于阅读。…

__stack_chk_fail问题分析

一、问题进程收到SIGABRT信号异常退出&#xff0c;异常调用栈显示__stack_chk_fail*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: Pico/A7H10/PICOA7H10:10/5.5.0/smartcm.1676912090:userdebug/dev-keys Revision: 0 ABI: arm64 Times…

VS Code下载安装教程

VS Code下载安装使用教程 目录VS Code下载安装使用教程一、下载二、安装三、使用教程3.1 VS Code中的第一个页面HelloWorld.html3.2 VS Code插件安装3.2.1 安装中文界面3.2.3 安装 Open in Browser插件3.2.4 安装Auto Rename Tag插件注意&#xff1a;3.3 code .命令&#xff0c…