知识点概览
- Python基础:了解Python语言的基本语法和结构。
- Requests库:使用Requests库发送HTTP请求。
- BeautifulSoup库:解析HTML文档,提取所需数据。
- Tkinter库:创建图形用户界面。
- 文件操作:学习如何在本地保存文件。
难点解析
- 网络请求的处理:如何正确处理网络请求和响应。
- HTML文档的解析:如何使用BeautifulSoup解析HTML并提取数据。
- GUI的设计:如何设计一个用户友好的界面。
代码详解
1. 导入所需库
import os
import requests
from bs4 import BeautifulSoup
from tkinter import Tk, Label, Entry, Button, filedialog, StringVar, messagebox, scrolledtext
from tkinter.ttk import Style
from collections import defaultdict
- os: 用于操作系统功能,如文件路径处理。
- requests: 发送HTTP请求,获取网页内容。
- BeautifulSoup: 从HTML或XML文件中提取数据。
- Tkinter: 创建GUI应用程序。
- defaultdict: 从collections模块,用于创建带有默认值的字典。
2. 定义爬取和分类函数
先确认请求网址是否成功,然后再扒网页的文字,最后进行分类
def scrape_and_classify(url):
# 爬取网页内容并分类
try:
# 发送 HTTP GET 请求到提供的 url
response = requests.get(url)
# 检查请求是否成功,如果响应码不是 200 系列,则抛出异常
response.raise_for_status()
# 使用 BeautifulSoup 解析器来解析 HTML 文档
soup = BeautifulSoup(response.text, 'html.parser')
# 创建一个默认字典,用于存储分类后的内容
result = defaultdict(list)
# 遍历所有标题 (h1, h2, h3) 和段落 (p) 标签
for tag in soup.find_all(['h1', 'h2', 'h3', 'p']):
# 如果标签是标题标签,将其文本添加到 '标题' 列表
if tag.name in ['h1', 'h2', 'h3']:
result['标题'].append(tag.get_text(strip=True))
# 如果标签是段落标签,将其文本添加到 '段落' 列表
elif tag.name == 'p':
result['段落'].append(tag.get_text(strip=True))
# 返回包含分类内容的字典
return result
except requests.exceptions.RequestException as e:
# 如果请求过程中发生异常,返回错误信息字符串
return f"爬取失败:{e}"
- 发送HTTP GET 请求到指定的
url
。 - 使用
BeautifulSoup
解析返回的HTML文档。 - 遍历所有标题 (
h1
-h3
) 和段落 (p
) 标签,提取文本。
在HTML中,<h1>, <h2>, <h3> 等标签被称为标题标签
<p> 标签代表段落
3. 保存爬取内容到文件
这里就涉及到读写文件操作
def save_classified_content(content, file_path):
"""
将分类后的内容保存到本地文件。
参数:
content (dict): 一个字典,包含分类后的文字内容。
键为分类名称(如 '标题' 或 '段落'),值为该分类下所有文本的列表。
file_path (str): 要保存内容的本地文件路径。
该函数会遍历 content 字典,将每个分类下的所有文本写入到指定的文件中。
"""
# 使用 'with' 语句打开文件,确保最后文件会被正确关闭
with open(file_path, 'w', encoding='utf-8') as file: # 注意:编码应为 'utf-8',可能是 'utf-8' 的错误写法
# 遍历 content 字典中的每个分类和对应的文本列表
for category, texts in content.items():
# 写入分类名称,并添加一个换行符,用于分隔不同分类
file.write(f"【{category}】\n")
# 遍历当前分类下的所有文本
for text in texts:
# 写入文本,并添加一个换行符,用于分隔同一分类下的文本
file.write(text + '\n')
# 在每个分类后添加一个额外的换行符,用于分隔不同分类的内容
file.write('\n')
4. GUI 设计与功能实现
GUI其实就是图形用户界面,一种通过图形化的方式进行交互,可以理解为这样做出来的界面更好看
def start_scraping():
"""
开始执行爬取操作的函数。
该函数首先从用户输入获取网址和保存路径,然后进行爬取操作。
如果网址或保存路径无效,将显示错误信息并终止操作。
如果爬取成功,将内容保存到指定路径,并显示成功信息。
如果保存过程中发生异常,将显示错误信息。
"""
# 从 Entry 控件获取用户输入的网址
url = url_entry.get()
# 从 StringVar 对象获取用户选择的保存路径
save_path = save_path_var.get()
# 检查网址是否输入,如果没有输入则弹出错误信息
if not url:
messagebox.showerror("错误", "请输入有效的网址!")
return # 如果没有输入网址,函数到此结束
# 检查保存路径是否选择,如果没有选择则弹出错误信息
if not save_path:
messagebox.showerror("错误", "请选择保存路径!")
return # 如果没有选择保存路径,函数到此结束
# 显示信息提示用户爬取正在进行
messagebox.showinfo("信息", "爬取中,请稍等...")
# 调用 scrape_and_classify 函数执行爬取操作,并将结果存储在 content 变量中
content = scrape_and_classify(url)
# 检查爬取结果是否为字符串且以 "爬取失败" 开头,如果是则显示错误信息
if isinstance(content, str) and content.startswith("爬取失败"):
messagebox.showerror("错误", content)
return # 如果爬取失败,函数到此结束
# 尝试将爬取的内容保存到文件,如果发生异常则捕获并显示错误信息
try:
save_classified_content(content, save_path)
messagebox.showinfo("成功", f"爬取完成!内容已保存到 {save_path}")
except Exception as e: # 捕获所有类型的异常
messagebox.showerror("错误", f"保存失败:{e}") # 显示保存失败的错误信息
5. 主窗口设置
这里就是很普通的设计UI界面,字体大小,颜色之类的
root = Tk()
root.title("文字爬取与分类工具")
root.geometry("700x500")
root.configure(bg="#f5f5f5")
# 美工样式
title_label = Label(root, text="阴暗的爬取", font=("Helvetica", 24, "bold"), bg="#f5f5f5", fg="#4A90E2")
title_label.pack(pady=20)
# URL输入
url_label = Label(root, text="输入网址:", font=("Helvetica", 14), bg="#f5f5f5")
url_label.pack(anchor="w", padx=20, pady=5)
url_entry = Entry(root, font=("Helvetica", 14), width=60)
url_entry.pack(padx=20, pady=5)
# 保存路径
save_path_label = Label(root, text="保存路径:", font=("Helvetica", 14), bg="#f5f5f5")
save_path_label.pack(anchor="w", padx=20, pady=5)
save_path_var = StringVar()
save_path_entry = Entry(root, textvariable=save_path_var, font=("Helvetica", 14), width=60)
save_path_entry.pack(padx=20, pady=5)
browse_button = Button(root, text="浏览", font=("Helvetica", 12), command=browse_save_path, bg="#4A90E2", fg="white")
browse_button.pack(pady=10)
# 开始爬取按钮
start_button = Button(root, text="开始爬取", font=("Helvetica", 16, "bold"), command=start_scraping, bg="#4CAF50", fg="white")
start_button.pack(pady=20)
footer_label = Label(root, text="艾欣同学出品,必属精品", font=("Helvetica", 10), bg="#f5f5f5", fg="#777777", anchor="se")
footer_label.pack(side="bottom", pady=10)
root.mainloop()
源代码附赠
import os
import requests
from bs4 import BeautifulSoup
from tkinter import Tk, Label, Entry, Button, filedialog, StringVar, messagebox, scrolledtext
from tkinter.ttk import Style
from collections import defaultdict
def scrape_and_classify(url):
"""
爬取文字内容并分类
:param url: 目标网址
:return: 分类的文字内容
"""
try:
response = requests.get(url)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
result = defaultdict(list)
# 分类爬取文字
for tag in soup.find_all(['h1', 'h2', 'h3', 'p']):
if tag.name in ['h1', 'h2', 'h3']:
result['标题'].append(tag.get_text(strip=True))
elif tag.name == 'p':
result['段落'].append(tag.get_text(strip=True))
return result
except requests.exceptions.RequestException as e:
return f"爬取失败:{e}"
def save_classified_content(content, file_path):
"""
保存分类内容到本地文件
:param content: 分类文字内容
:param file_path: 保存路径
"""
with open(file_path, 'w', encoding='utf-8') as file:
for category, texts in content.items():
file.write(f"【{category}】\n")
for text in texts:
file.write(text + '\n')
file.write('\n')
def start_scraping():
"""
开始爬取功能
"""
url = url_entry.get()
save_path = save_path_var.get()
if not url:
messagebox.showerror("错误", "请输入有效的网址!")
return
if not save_path:
messagebox.showerror("错误", "请选择保存路径!")
return
messagebox.showinfo("信息", "爬取中,请稍等...")
content = scrape_and_classify(url)
if isinstance(content, str) and content.startswith("爬取失败"):
messagebox.showerror("错误", content)
return
try:
save_classified_content(content, save_path)
messagebox.showinfo("成功", f"爬取完成!内容已保存到 {save_path}")
except Exception as e:
messagebox.showerror("错误", f"保存失败:{e}")
def browse_save_path():
"""
浏览保存路径
"""
file_path = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[("Text Files", "*.txt")],
title="选择保存路径"
)
save_path_var.set(file_path)
# 创建主窗口
root = Tk()
root.title("文字爬取与分类工具")
root.geometry("700x500")
root.configure(bg="#f5f5f5")
# 美工样式
title_label = Label(root, text="阴暗的爬取", font=("Helvetica", 24, "bold"), bg="#f5f5f5", fg="#4A90E2")
title_label.pack(pady=20)
# URL输入
url_label = Label(root, text="输入网址:", font=("Helvetica", 14), bg="#f5f5f5")
url_label.pack(anchor="w", padx=20, pady=5)
url_entry = Entry(root, font=("Helvetica", 14), width=60)
url_entry.pack(padx=20, pady=5)
# 保存路径
save_path_label = Label(root, text="保存路径:", font=("Helvetica", 14), bg="#f5f5f5")
save_path_label.pack(anchor="w", padx=20, pady=5)
save_path_var = StringVar()
save_path_entry = Entry(root, textvariable=save_path_var, font=("Helvetica", 14), width=60)
save_path_entry.pack(padx=20, pady=5)
browse_button = Button(root, text="浏览", font=("Helvetica", 12), command=browse_save_path, bg="#4A90E2", fg="white")
browse_button.pack(pady=10)
# 开始爬取按钮
start_button = Button(root, text="开始爬取", font=("Helvetica", 16, "bold"), command=start_scraping, bg="#4CAF50", fg="white")
start_button.pack(pady=20)
# 标注
footer_label = Label(root, text="艾欣同学出品,必属精品", font=("Helvetica", 10), bg="#f5f5f5", fg="#777777", anchor="se")
footer_label.pack(side="bottom", pady=10)
# 启动主循环
root.mainloop()
总结
- 用Python的
Requests
和BeautifulSoup
库来爬取网页数据 - 利用
Tkinte
r库创建一个基本的GUI应用程序
对于刚接触这种东西来说,算是小试牛刀了。