还不知道假期看啥剧?跟着我用爬虫试试

写在前面:python综合实验大作业
欢迎大家指点交流

一、代码模块设计

(1)通过request_douban函数发送HTTP请求并获取电影Top250网页的HTML内容。
(2)save_to_folder函数用于将抓取到的电影数据保存到本地文件夹。它创建一个文件夹,并将每个电影的文本信息保存到名为info.txt的文件中,将电影海报图像保存为名为poster.jpg的文件,同时将数据保存到Excel文件douban_top250.xlsx中。
(3)save_data_to_local函数用于选择保存数据的文件夹,并调用save_to_folder函数将数据保存到指定的文件夹中。
(4)save_to_excel函数从网页内容中解析电影数据,并将数据存储在data列表中。同时,它将电影数据显示在程序的GUI界面的treeview中。
(5)scrape_data函数用于抓取指定范围的电影Top250数据。它循环发送HTTP请求,解析网页内容,并调用save_to_excel函数保存数据。
(6)show_filtered_data函数用于根据指定的序号范围筛选数据,并在GUI界面的treeview中显示筛选结果。
(7)show_details函数用于显示选定电影的详细信息。它在程序的GUI界面上创建一个新的窗口,并显示电影的序号、名称、评分、链接、作者和引用评价等信息。
(8)主程序部分使用tkinter库创建了一个GUI界面,包括一个标题、输入框、按钮和treeview控件。用户可以通过点击按钮执行相应的操作,如抓取数据、筛选数据、保存数据到本地和查看详细信息。

二、各模块解析

2.1 各类调用的库

import requests
from bs4 import BeautifulSoup
from PIL import ImageTk, Image
import tkinter as tk
from tkinter import ttk
from io import BytesIO
import os
import base64
import pandas as pd
from tkinter import filedialog
from tkinter import messagebox

在这次实训代码实现中,侧面证明python目前的强大,各类功能可以通过调用不同的库来实现,大家在尝试实现过程中,首先要确定自己已经安装所需要的库。

2.2 request模块

def request_douban(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36',
    }

    try:
        response = requests.get(url=url, headers=headers)
        if response.status_code == 200:
            return response.text
    except requests.RequestException:
        return None

发送一个带有指定请求头的GET请求,并返回响应内容(如果请求成功)。如果请求出错或响应状态码不是200,则返回None。

2.3 save模块

def save_to_folder(folder_path):
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)

    for item in data:
        item_index, item_name, item_score, item_link, item_img, item_author, item_quote = item

        # 创建电影的子文件夹
        movie_folder = os.path.join(folder_path, str(item_index).zfill(3))
        if not os.path.exists(movie_folder):
            os.makedirs(movie_folder)

        # 保存文本信息
        text_file = os.path.join(movie_folder, 'info.txt')
        with open(text_file, 'w', encoding='utf-8') as file:
            file.write(f"序号: {item_index}\n")
            file.write(f"名称: {item_name}\n")
            file.write(f"评分: {item_score}\n")
            file.write(f"链接: {item_link}\n")
            file.write(f"作者: {item_author}\n")
            file.write(f"引用: {item_quote}\n")

        # 保存图片
        img_file = os.path.join(movie_folder, 'poster.jpg')
        img_data = ImageTk.getimage(item_img)
        img_data = img_data.convert('RGB')  # 将图像转换为RGB模式
        img_data_bytes = BytesIO()
        img_data.save(img_data_bytes, format='JPEG')
        img_data_bytes = img_data_bytes.getvalue()
        img_base64 = base64.b64encode(img_data_bytes).decode('utf-8')
        with open(img_file, 'wb') as file:
            file.write(base64.b64decode(img_base64))

    # 保存数据为xlsx文件
    file_path = os.path.join(folder_path, 'douban_top250.xlsx')
    df = pd.DataFrame(data, columns=['序号', '名称', '评分', '链接', '作者', '引用', '图片'])
    df.to_excel(file_path, index=False)
    messagebox.showinfo("保存成功", "数据保存成功")

依赖于os、PIL、base64、pandas和tkinter.messagebox等库。用于保存数据

2.4 tosave模块

def save_data_to_local():
    folder_path = filedialog.askdirectory()
    if folder_path:
        save_to_folder(folder_path)
    else:
        messagebox.showwarning("保存失败", "保存路径未选择")


def save_to_excel(soup, start_index):
    items = soup.find(class_='grid_view').find_all('li')

    for i, item in enumerate(items, start=start_index):
        item_title = item.find(class_='title')
        item_link = item_title.find('a')
        if item_link:
            item_link = item_link['href']
        else:
            item_link = ''
        item_name = item_title.get_text(strip=True)
        item_index = i
        item_score = item.find(class_='rating_num').get_text(strip=True)
        item_author = item.find('p').get_text(strip=True)

        item_quote_elem = item.find(class_='inq')
        item_quote = item_quote_elem.get_text(strip=True) if item_quote_elem else ''

        item_img_url = item.find('a').find('img')['src']
        img_response = requests.get(item_img_url)
        img_data = img_response.content
        img = Image.open(BytesIO(img_data))
        img.thumbnail((100, 100))
        item_img = ImageTk.PhotoImage(img)

        item_details = [
            item_index,
            item_name,
            item_score,
            item_link,
            item_img,
            item_author,
            item_quote
        ]

        data.append(item_details)

        treeview.insert("", "end", iid=f"I{item_index}", values=(item_index, item_name, item_score))

        treeview.image_references.append(item_img)

具体实现保存到本地的功能。

2.5 scrape_data模块

def scrape_data(start_index, end_index):
    data.clear()
    treeview.delete(*treeview.get_children())
    treeview.image_references = []
    messagebox.showinfo("抓取数据", "开始抓取数据,请等待...")

    for i in range(start_index, end_index):
        url = 'url'
        html = request_douban(url)
        soup = BeautifulSoup(html, 'lxml')
        save_to_excel(soup, i * 25 + 1)

    messagebox.showinfo("抓取完成", "抓取数据完成")

从豆瓣电影Top250网页中抓取数据的函数。它依赖于之前提到的request_douban()和save_to_excel()函数,以及data、treeview和messagebox等变量和库。

2.6 show模块

def show_filtered_data():
    range_input = filter_entry.get()
    if '-' in range_input:
        start_index, end_index = map(int, range_input.split('-'))
        if start_index >= 1 and end_index <= 250:
            filtered_data = [item for item in data if start_index <= item[0] <= end_index]
            if len(filtered_data) > 0:
                treeview.delete(*treeview.get_children())
                for item in filtered_data:
                    treeview.insert("", "end", iid=f"I{item[0]}", values=(item[0], item[1], item[2]))
                messagebox.showinfo("筛选完成", "筛选完成")
            else:
                messagebox.showwarning("筛选失败", "没有找到符合条件的数据")
        else:
            messagebox.showwarning("筛选失败", "请输入有效的序号范围(1-250)")
    else:
        messagebox.showwarning("筛选失败", "请输入正确的序号范围格式(x-y)")


def show_details():
    selected_item = treeview.focus()
    if selected_item:
        item = data[int(selected_item.lstrip('I')) - 1]
        details_window = tk.Toplevel(root)
        details_window.title("详细信息")
        details_window.geometry("400x400")

        item_frame = ttk.Frame(details_window)
        item_frame.pack(pady=10)

        item_label = ttk.Label(item_frame, text=f"序号:{item[0]}\n名称:{item[1]}\n评分:{item[2]}\n链接:{item[3]}")
        item_label.pack(side=tk.LEFT, padx=5)

        item_img_label = ttk.Label(item_frame, image=item[4])
        item_img_label.pack(side=tk.LEFT, padx=5)

        item_author_label = ttk.Label(details_window, text=f"作者:{item[5]}")
        item_author_label.pack()

        item_quote_label = ttk.Label(details_window, text=f"引用评价:{item[6]}")
        item_quote_label.pack()

        details_window.mainloop()
    else:
        messagebox.showwarning("查看详情", "请选择一项进行查看详细信息")


root = tk.Tk()
root.title("电影Top250")
root.geometry("900x600")  # 增加窗口大小

title_label = tk.Label(root, text="电影Top250数据获取", font=("楷书", 20, "bold"), fg="blue")
title_label.pack(pady=10)

input_frame = tk.Frame(root)
input_frame.pack(pady=10, side=tk.LEFT)

fetch_button = ttk.Button(input_frame, text="开始抓取数据", command=lambda: scrape_data(0, 10), width=15)
fetch_button.pack(pady=10)

filter_entry = ttk.Entry(input_frame, width=10, font=("Arial", 12), foreground="gray")
filter_entry.pack(pady=10)
filter_entry.insert(tk.END, "1-250")
filter_entry.bind("<FocusIn>", lambda event: filter_entry.config(foreground="black"))
filter_entry.bind("<FocusOut>", lambda event: filter_entry.config(foreground="gray"))

filter_button = ttk.Button(input_frame, text="筛选", command=show_filtered_data, width=10)
filter_button.pack(pady=10)

details_button = ttk.Button(input_frame, text="查看详细信息", command=show_details, width=15)
details_button.pack(pady=10)

save_button = ttk.Button(input_frame, text="保存数据到本地", command=save_data_to_local, width=15)
save_button.pack(pady=10)


treeview = ttk.Treeview(root)
treeview["columns"] = ("序号", "名称", "评分")
treeview.column("#0", width=0, stretch=tk.NO)
treeview.column("序号", anchor=tk.CENTER, width=75)
treeview.column("名称", anchor=tk.W, width=300)
treeview.column("评分", anchor=tk.CENTER, width=75)
treeview.heading("序号", text="序号")
treeview.heading("名称", text="名称")
treeview.heading("评分", text="评分")
treeview.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=10, pady=10)

简单的图形用户界面(GUI)程序,用于展示豆瓣电影Top250的数据,并提供数据抓取、筛选和查看详细信息的功能。

3、成果展示

一个可视化界面,布局还算可以,实现信息的爬取、筛选、详细展示、保存等功能

最后的结尾:
“感谢大家阅读本帖,并参与到我们关于爬虫技术的讨论中来!爬虫作为一项强大而又有趣的技术,可以帮助我们从互联网中收集、分析和利用海量的数据。在这个技术交流平台上,我们共同探讨了爬虫的基础知识、常见问题和实际应用案例。
通过这次交流,我们不仅学习到了如何编写爬虫代码、处理网页内容和保存数据,还了解了爬虫在信息获取、数据分析和业务开发等方面的重要性。同时,我们也分享了一些爬虫的最佳实践和注意事项,以确保我们的爬虫行为合法、高效和可持续。
欢迎大家在评论区继续交流、提问和分享自己的经验。无论是关于爬虫的新技巧、挑战还是创新应用,都可以在这里进行讨论。让我们共同探索爬虫技术的更多可能性,共同进步!
再次感谢大家的参与,希望这个技术交流平台能够成为我们共同学习和进步的乐园。祝愿大家在爬虫技术的路上越走越远,收获更多的知识和成就!”

需要源码可私信

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Token_w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值