Python,Tkinter里运行爬虫程序实例
前言
爬取今日热榜里某个模块的数据
截图如下:
一、话不多说,直接上代码
代码如下(示例):
from tkinter import *
from tkinter.scrolledtext import ScrolledText
import re
import requests
from bs4 import BeautifulSoup
import time
"""
放在tkinter里运行的爬虫程序如何终止?
在Tkinter应用中终止一个爬虫程序,你可以使用一个全局变量作为标志位,然后在爬虫的循环中检查这个标志位。如果标志位指示停止爬虫,你可以抛出一个异常来终止循环。
"""
# 全局标志位(用于终止爬虫)
running = True
start_time = time.time() # 记录开始时间
# 实时更新提示框数据
def set_value(data):
tip.delete(0, END) # 清空现有的文本
tip.insert(0, data) # 插入新的文本
tip.update() # 立即更新(如果不更新的话是会等程序执行完再一次性更新的)
def getData():
global running
try:
set_value("-------------------开始获取数据------------------------")
# 获取数据前清空现有文本
clearBox()
url = "https://tophub.today/"
head = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
resp = requests.get(url, headers=head)
resp.encoding = "utf-8"
"""
1.把页面源代码交给BeautifulSoup进行处理,生成bs对象
2.从bs对象中查找数据
find(标签,属性=值)
find_all(标签,属性=值)
class是关键字,用class_
"""
page = BeautifulSoup(resp.text, "html.parser") #
# 查找包含特定文本的div
# search_text = "懂球帝"
search_text = ent.get()
print(search_text)
div_containing_text = page.find("span", string=search_text).parent.parent.parent.parent.next_sibling.next_sibling
all_a = div_containing_text.find_all("a") # 找到所有a标签
# 循环a标签
zidian = {}
for item in all_a:
href = item.get("href")
title = item.find("span", class_="t").text
zidian = {"title": title, "url": href}
# 执行数据插入
tit = str(zidian) + '\n'
txt.insert(END, tit) # 插入最后一行
txt.see(END) # 跳转到最后一行
set_value(tit)
time.sleep(1)
# 终止爬虫
if not running:
break # 当标志位为False时,终止爬虫
end_time = time.time() # 记录结束时间
execution_time = end_time - start_time # 计算执行时间
print(f"函数执行时间: {execution_time}秒")
set_value(f"---------全部爬取完成--------------用时:{execution_time}秒")
except Exception as e:
set_value(f"An error occurred: {e}")
# 处理所有异常的代码
print(f"An error occurred: {e}")
def clearBox():
txt.delete("1.0", "end") # 清空内容
def func2(event):
"""当鼠标点击ent时,清除掉默认值"""
if ent.get() == '请输入话题':
ent.delete('0', 'end') # 做这个判断,是为了避免清除用户自己输入的数据
# 终止程序
def stopGet():
global running
running = False
root = Tk()
root.title('测试')
root.geometry('780x530+400+200')
# root.resizable(0,0) # 禁止改变窗体大小
# 创建一个frame
frame_head = Frame(root)
frame_head.grid(row=0, column=0)
# 左边标签
label = Label(frame_head, text="请输入:", font=("华文行楷", 17), width=8)
label.grid(row=0, column=0)
# 中间输入框
# 创建一个StringVar对象,用于存储文本框的内容
text_var = StringVar()
text_var.set("请输入话题")
ent = Entry(frame_head, width=47, font=("隶书", 17), textvariable=text_var, foreground='blue', relief='groove')
ent.grid(row=0, column=1, columnspan=2, sticky=N + S, pady=10, ipady=4)
ent.bind('<Button-1>', func2)
# 右边按钮
btn_get = Button(frame_head, text='爬取', font=("隶书", 15), width=8, command=getData)
btn_get.grid(row=0, column=3, padx=10)
# 这里插入一个提示框
tip = Entry(frame_head, width=102, background='lightgray')
tip.grid(row=1, column=0, columnspan=4, pady=5, ipady=10)
set_value("-------------------准备就绪------------------------")
# 中间
txt = ScrolledText(frame_head, height=28, width=100)
txt.grid(row=2, columnspan=4)
# 底部按钮
btn_clear = Button(frame_head, text='清空', font=("隶书", 15), command=clearBox)
btn_clear.grid(row=3, column=0, columnspan=2, pady=10, ipadx=10)
btn_quit = Button(frame_head, text='终止', bg='gray', font=("隶书", 15), command=stopGet)
btn_quit.grid(row=3, column=2, pady=10, ipadx=10)
root.mainloop()