用Python做一个下载器,从获取数据到编写GUI界面

news/2025/1/11 15:07:10/

本片文章目录

      • 前言
      • 案例基本实现思路?
      • 代码实现
        • 一、单张小说下载
        • 二、整本小说下载
        • 三、多线程采集
        • 四、采集排行榜所有小说
        • 五、搜索小说功能
        • 六、GUI界面
      • 尾语

前言

嗨喽,大家好呀~这里是爱看美女的茜茜呐

对于广大书虫而言,没有小说看是最痛苦的,你身边有这样的人吗?

今天咱们分享一个小说下载器代码,打包成exe后,发给你的小伙伴也能直接使用…

案例基本实现思路?

一、数据来源分析

明确需求:

  • 采集的网站是什么?

  • 采集的数据是什么?

    标题/内容

    分析 标题/内容 是从哪里来的

    通过浏览器自带工具: 开发者工具抓包分析

  • 打开开发者工具: F12 / 鼠标右键点击检查选择network

  • 刷新网页

  • 搜索数据, 找到数据包

二. 代码实现步骤

  1. 发送请求, 模拟浏览器对于url地址发送请求

  2. 请求链接: https://www.***.net/1_1631/3047505.html

  3. 获取数据, 获取服务器返回响应数据内容

    开发者工具: response

  4. 解析数据, 提取我们想要的数据内容

    标题/内容

  5. 保存数据, 把数据保存本地文件

代码实现

在开始之前,为了防止大家代码看不懂,我特地录制了一套详细教程

教程和代码,直接在文末名片自取就好了 点击此处跳转文末名片

一、单张小说下载

发送请求, 模拟浏览器对于url地址发送请求

获取数据, 获取服务器返回响应数据内容

import requests
# 请求链接
url = 'https://www.****.net/1_1631/3047505.html'
# 模拟浏览器 headers 请求头
headers = {# user-agent 用户代理 表示浏览器基本身份信息'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)
# <Response [200]> 响应对象, 表示请求成功
print(response)print(response.text)

解析数据,提取我们想要的数据内容。

import requests  # 数据请求
import re  # 正则
import parsel # 数据解析# 请求链接
url = 'https://www.****.net/1_1631/3047505.html'
# 模拟浏览器 headers 请求头
headers = {# user-agent 用户代理 表示浏览器基本身份信息'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)
# <Response [200]> 响应对象, 表示请求成功
print(response)# 获取下来response.text <html字符串数据>, 转成可解析对象
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.****.net/1_1631/3047505.html'
# 模拟浏览器 headers 请求头
headers = {# user-agent 用户代理 表示浏览器基本身份信息'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)
# <Response [200]> 响应对象, 表示请求成功
print(response)# 获取下来response.text <html字符串数据>, 转成可解析对象
完整源码、解答、教程皆+VX:pytho8987获取,记得验证备注“777”
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)
# title <文件名> '.txt' 文件格式  a 追加保存 encoding 编码格式 as 重命名
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 请求头
headers = {# user-agent 用户代理 表示浏览器基本身份信息'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
url_list = re.findall('<dd> <a style="" href="(.*?)">', html_data)
# for循环遍历
for url in url_list:index_url = 'https://www.****.net' + urlprint(index_url)headers = {# user-agent 用户代理 表示浏览器基本身份信息'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)# <Response [200]> 响应对象, 表示请求成功print(response)# 获取下来response.text <html字符串数据>, 转成可解析对象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)# title <文件名> '.txt' 文件格式  a 追加保存 encoding 编码格式 as 重命名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 请求头headers = {# user-agent 用户代理 表示浏览器基本身份信息'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).text# 提取小说名字name = re.findall('<h1>(.*?)</h1>', html_data)[0]# 提取章节urlurl_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).text# 提取标题title = re.findall('<h1>(.*?)</h1>', html_data)[0]# 提取内容完整源码、解答、教程皆+VX:pytho8987获取,记得验证备注“777”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):# index_url = 'https://www.biqudu.net' + urltitle, 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 请求头headers = {# user-agent 用户代理 表示浏览器基本身份信息'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).text# 提取小说名字name = re.findall('<h1>(.*?)</h1>', html_data)[0]# 提取章节urlurl_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).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, 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 请求头headers = {# user-agent 用户代理 表示浏览器基本身份信息'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]# 提取章节urlurl_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).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.****.net/searchbook.php?keyword={word}'# 发送请求search_data = get_response(html_url=search_url).text# 解析数据, 提取小说名字/作者/小说ID完整源码、解答、教程皆+VX:pytho8987获取,记得验证备注“777”selector = 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..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.****.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)
# 设置下载按钮
完整源码、解答、教程皆+VX:pytho8987获取,记得验证备注“777tk.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.ppmy.cn/news/436607.html

相关文章

android中手机模式还是平板模式

ro.build.characteristics这个系统变量的值&#xff0c;如果为tablet则为平板&#xff0c;如果为phone则为手机。

057_Windows10平板模式

早就知道很多电脑现在就支持触屏&#xff0c;也知道surface系列就是这种电脑的典型代表。但是我自己确实是没有去体验过&#xff0c;今天一点点体验Windows10的过程中发现了一个平板模式&#xff0c;开启试了一下确实是跟先前的体验大不相同。 开启方式Win A 激活其中的平板模式…

修改设置显示为平板模式

路径&#xff1a;android4.2.2\frameworks\base\core\res\res\values\bools.xml 方法&#xff1a;<bool name"preferences_prefer_dual_pane">false</bool> 改成true 路径&#xff1a;android\packages\apps\Settings\src\com\android\settings\Settings…

Android 系统禁用触摸屏

需求&#xff1a;设置开关可以打开或者关闭屏幕触摸 实现&#xff1a; 1.打开文件 ./frameworks/base/core/java/android/view/ViewGroup.java 2.找到 public boolean dispatchTouchEvent(MotionEvent ev) 方法中开头添加如下代码 if(SystemProperties.get("system.…

平板电脑中应用的触摸面板

平板电脑也叫便携式电脑&#xff08;Tablet Personal Computer&#xff0c;Tablet PC&#xff09;&#xff0c;是一种小型、方便携带的个人电脑&#xff0c;以触摸屏作为基本的输入设备。它拥有的触摸屏&#xff08;也称为数位板技术&#xff09;允许用户通过触控笔或数字笔来进…

Win11系统怎么开启平板模式

Win11系统怎么开启平板模式&#xff1f;很多平板电脑朋友以为使用Win11系统需要自己开启平板模式&#xff0c;其实Win11已经没有了手动开启平板模式的开关。 Win11取消了原本的“平板模式”开关&#xff0c;取而代之的是更加智能的自动检测机制。在Win11中&#xff0c;系统通过…

win11触屏模式在哪 Windows11触屏模式的设置方法

win11系统的功能是非常多的,比如win11触屏模式就是win11平板模式,只有开启了这个模式就可以触屏了,那么win11平板模式在哪呢?下面小编就教大家win11怎么开启平板模式。更多Windows11安装教程&#xff0c;可以参考小白刷机网。 1、根据微软的消息来看&#xff0c;win11取消了平…

android平板模式适配

手机模式配置成平板模式 /build/tools/buildinfo.sh中&#xff1a; “ro.build.characteristics$TARGET_AAPT_CHARACTERISTICS" 去查找build文件夹一个mk文件中TARGET_AAPT_CHARACTERISTICS:default &#xff0c;修改成tablet。 同时修改分辨率&#xff1a; ro.sf.lcd_den…