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

news/2024/4/20 11:45:20/文章来源:https://blog.csdn.net/m0_67575344/article/details/129188610

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

在这里插入图片描述

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

思路

一、数据来源分析

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 parselurl = '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 oslist_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' + urlprint(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.futuresdef 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 responsedef get_list_url(html_url):"""获取章节url/小说名:param html_url: 小说目录页:return:"""html_data = get_response(html_url).textname = re.findall('<h1>(.*?)</h1>', html_data)[0]url_list = re.findall('<dd> <a style="" href="(.*?)">', html_data)return name, url_listdef get_content(html_url):"""获取小说内容/小说标题:param html_url: 小说章节url:return:"""html_data = get_response(html_url).texttitle = 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, contentdef 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' + urlexe.submit(main, index_url)exe.shutdown()

四、采集排行榜所有小说

import requests
import re
import parsel
import osdef 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 responsedef get_list_url(html_url):"""获取章节url/小说名:param html_url: 小说目录页:return:"""html_data = get_response(html_url).textname = re.findall('<h1>(.*?)</h1>', html_data)[0]url_list = re.findall('<dd> <a style="" href="(.*?)">', html_data)return name, url_listdef get_content(html_url):"""获取小说内容/小说标题:param html_url: 小说章节url:return:"""html_data = get_response(html_url).texttitle = 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, contentdef 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).textselector = parsel.Selector(novel_data)href = selector.css('.l .s2 a::attr(href)').getall()href = [i.replace('/', '') for i in href]return hrefdef 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' + urltitle, content = get_content(html_url=index_url)save(name, title, content)breakif __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).textname = 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).texttitle = 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).textselector = 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).textselector = parsel.Selector(search_data)lis = selector.css('.novelslist2 li')novel_info = []tb = pt.PrettyTable()tb.field_names = ['序号', '书名', '作者', '书ID']num = 0for 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 += 1novel_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' + urltitle, 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 ttkdef 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.luyixian.cn/news_show_73561.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

金仓数据库安装

一、麒麟操作系统安装金仓数据库 操作系统 DISTRIB_IDKylin DISTRIB_RELEASEV10 DISTRIB_CODENAMEjuniper 按照安装文档的步骤安装&#xff0c;记得记住设置的数据库的用户名、密码 二、window安装连接数据库的工具软件 三、jdbc连接数据库 &#xff08;1&#xff09;连接工…

错误记录:py2neo.errors.ProtocolError: Cannot decode response content as JSON

py2neo.errors.ProtocolError: Cannot decode response content as JSON 原因&#xff1a;目前不清楚 解决方法&#xff1a;进入\lib\site-packages\py2neo\database.py中更改graph_name为neo4j 程序正常运行

Linux命令及CPU占用过高的定位分析思路

一、vim命令不要使用vim打开大文件&#xff0c;vim会一次性读取所有内容到内存&#xff0c;容易造成宿主机内存溢出。 打开文件前&#xff0c;可以使用du -h命令查看文件大小。一般&#xff0c;100MB以下为宜。1、普通模式j 向下30j 向下移动30行k 向上h 向左l 向右0 到行首^ 到…

分阶段构建golang运行环境Dockerfile镜像

在开始这项工作之前大家可以先去看一下docker官方给出关于空镜像scratch的说明&#xff0c;采用官方简单的一句话就是&#xff1a;scratch是一个明确的空图像&#xff0c;特别是对于“从头开始”构建图像。分阶段构建镜像就会用到scratch这个空镜像&#xff0c;这样的好处是可以…

Vulnhub靶场----7、DC-7

文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 DC-7下载地址&#xff1a;https://download.vulnhub.com/dc/DC-7.zip kali&#xff1a;192.168.144.148 DC-7&#xff1a;192.168.144.155 二、渗透流程 nmap -T5 -A -p- -sV -sT 192.168.144.155思路&#xff1a; …

【Rust 日报】2023-2-23 Ambient 0.1 发布

治理改革 RFC公告官方博客发布了治理改革RFC的公告&#xff0c;了解详情请点开链接查看。主要看点其实是新的RFC改革治理之后&#xff0c;提供了多语言的支持&#xff0c;其中包括简体中文&#xff0c;该PR目前还在讨论中。原文: https://blog.rust-lang.org/inside-rust/2023/…

RabbitMQ 实现延迟队列

业务场景&#xff1a;1.生成订单30分钟未支付&#xff0c;则自动取消&#xff0c;我们该怎么实现呢&#xff1f;2.生成订单60秒后,给用户发短信1 安装rabbitMqwindows安装ubuntu中安装2 添加maven依赖<!-- https://mvnrepository.com/artifact/org.springframework.boot/spr…

「JVM 编译优化」Graal 编译器

文章目录1. 历史背景2. 构建编译调试环境3. JVMCI 编译器接口4. 代码中间表示5. 代码优化与生成1. 历史背景 Graal 编译器在 JDK 9 以 Jaotc 提前编译工具的形式首次加入到官方的 JDK 中&#xff0c;JDK 10 开始提供替换&#xff08;得益于 HotSpot 编译器接口&#xff0c;Jav…

扬帆优配|“涨停敢死队”慌了?监管“盯紧”异常交易

日前&#xff0c;沪深买卖所发布《主板股票反常买卖实时监控细则》&#xff0c;对反常买卖行为的类型和标准作出规则。其间&#xff0c;针对“打板”“封板”等反常行为的监控遭到商场重视&#xff0c;有商场传闻称&#xff0c;新规或导致高频买卖毁灭&#xff0c;“量价型股票…

MySQL进阶知识

1 存储引擎1.1 MySQL体系结构1.2 存储引擎简介存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表的&#xff0c;而不是基于库的&#xff0c;同一个库的多个表可以采用不同的存储引擎&#xff0c;所以存储引擎也经常称为表类型。创建表时可以指…

pyhon笔记——Anaconda安装

一、简介 Anaconda包括Conda、Python以及一大堆安装好的工具包&#xff0c;比如&#xff1a;numpy、pandas等 Miniconda包括Conda、Python conda是一个开源的包、环境管理器&#xff0c;可以用于在同一个机器上安装不同版本的软件包及其依赖&#xff0c;并能够在不同的环境之…

Android:实现签名功能——signature-pad库

文章目录实现效果步骤1、添加 signature-pad 库的依赖。2、在 layout 文件中使用 SignaturePad 控件&#xff0c;另外添加“清空”和“保存”两个按钮。3、实现清空 SignaturePad 控件内容的功能4、实现保存 SignaturePad 控件内容的功能5、实现兼容Android10以下和Android10以…

Video 标签无法播放 mp4 的原因和解决办法

问题 用 QQ 的截图录屏功能录制的 mp4 视频&#xff0c;无法用 <video> 标签正常播放。 原因 通过搜索的说法是&#xff1a; 查阅文档&#xff08;不知道是啥文档&#xff09;&#xff0c;关于video标签所支持的视频格式和编码&#xff1a; MPEG4 带有H.264视频编码和…

大规模食品图像识别:T-PAMI 2023论文解读

美团基础研发平台视觉智能部与中科院计算所展开科研课题合作&#xff0c;共同构建大规模数据集Food2K&#xff0c;并提出渐进式区域增强网络用于食品图像识别&#xff0c;相关研究成果已发表于T-PAMI 2023。本文主要介绍了数据集特点、方法设计、性能对比&#xff0c;以及基于该…

【STM32MP157应用编程】2.GPIO输入、输出、中断

目录 GPIO文件 指令操作GPIO 程序操作GPIO 程序说明 程序代码 2_GPIO_4.c 启动交叉编译工具 编译 拷贝到开发板 测试 GPIO文件 在/sys/class/gpio目录下&#xff0c;存放了GPIO的文件。 gpiochipX&#xff1a;当前SoC所包含的GPIO控制器&#xff0c;STM32MP157一共包…

input 子系统

简介 先来了解什么是输入设备&#xff1f; 常见的输入设备有键盘、 鼠标、 遥控杆、 书写板、 触摸屏等等,用户通过这些输入设备与 Linux 系统进行数据交换。 什么是输入系统&#xff1f; 输入设备种类繁多&#xff0c; 能否统一它们的接口&#xff1f; 既在驱动层面统一&…

x64dbg和IDA pro 配置PDB 符号文件symbols

PDB 作用 PDB&#xff08;Program Debugging Database&#xff09;就是在生成EXE 和 DLL 文件的过程中生成的这个文件&#xff0c;可以帮助进行调试。 为什么x64dbg 没有将PDB 文件集成到软件中呢&#xff1f;主要是PDB 文件太大了&#xff0c;在分发安装包的时候会很大&#…

数据库浅谈之 DuckDB AGG 底层实现

数据库浅谈之 DuckDB AGG 底层实现 HELLO&#xff0c;各位博友好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 这里是数据库浅谈系列&#xff0c;收录在专栏 DATABASE 中 &#x1f61c;&#x1f61c;&#x1f61c; 本系列阿呆将记录一些数据库领域相关的知…

小米/红米手机数据恢复:从小米手机恢复已删除的数据

如果您不小心删除了小米手机上的数据&#xff0c;后来发现您需要它&#xff0c;那么本文适合您。我将向您介绍一些最可靠的小米恢复方法&#xff0c;以将您的数据恢复到您的设备上。无论您是否有备份&#xff0c;都可以处理。让我们开始吧&#xff01; 小米数据恢复 - 如何做&a…

我们应该如何优雅的处理 React 中受控与非受控

引言 大家好&#xff0c;我是19组清风。有段时间没有和大家见面了&#xff0c;最近因为有一些比较重要的事情&#xff08;陪女朋友和换了新公司&#xff09;在忙碌所以销声匿迹了一小段时间&#xff0c; 后续会陆陆续续补充之前构建 & 编译系列中缺失的部分&#xff0c;提…