用tkinter+selenium做一个CSDN热榜爬虫

news2025/1/13 11:36:06

文章目录

    • UI设计
    • 函数封装
    • 功能实现

自从学会了分析热榜,就是CSDN热榜分析,每天都要爬下来分析一下热榜都在干什么。但脚本运行到底还是不方便,所以接下来就想办法将其做成一个带有界面的热榜爬虫

UI设计

做一个热榜爬虫的交互式界面,只需要两个按钮外加两个信息框就足够了,所以布局极其简单

class TestSTL:
    def __init__(self):
        self.root = tk.Tk()
        self.root.geometry("600x300+200+20")
        self.root.title("CSDN分析")
        self.initVars()
        self.initWidgits()
        self.root.mainloop()
    
    def initVars(self):
        self.heatBlogs = []
        self.subHeats = {}
        self.infoCSDN = tk.StringVar()

    def initWidgits(self):
        frmCtrl = ttk.LabelFrame(self.root, text="CSDN工具")
        frmCtrl.pack(side=tk.TOP, fill=tk.X)
        self.setFrmCtrl(frmCtrl)

        frmInfo = ttk.LabelFrame(self.root, text="反馈信息")
        frmInfo.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        ttk.Label(frmInfo, textvariable=self.infoCSDN).pack(side = tk.TOP, fill=tk.X)
        self.infoCSDN.set("无反馈")

        self.setFrmInfo(frmInfo)
    
    def setFrmCtrl(self, frm):
        frmPack = dict(side=tk.TOP, fill=tk.X)
        frmHeat = ttk.Frame(frm)
        frmHeat.pack(**frmPack)
        ttk.Label(frmHeat, width=10, text="热榜分析").pack(side=tk.LEFT)
        ttk.Button(frmHeat, width=10, text="爬取热榜",
            command=self.btnHeatCrawler).pack(side=tk.LEFT)

        ttk.Button(frmHeat, width=10, text="导出热榜",
            command=self.mbExportHeat).pack(side=tk.LEFT)
        
    def setFrmInfo(self, frm):
        scroll = ttk.Scrollbar(frm)
        scroll.pack(side=tk.RIGHT,fill=tk.Y)
        self.logTxt = tk.Text(frm)
        self.logTxt.pack(side=tk.TOP, fill=tk.BOTH, padx=5, pady=5, expand=True)
        self.logTxt.config(yscrollcommand=scroll.set)
        scroll.config(command=self.logTxt.yview)

    # 热榜
    def btnHeatCrawler(self):
        pass

    def mbExportHeat(self):
        pass

    def addLogs(self, text):
        self.logTxt.insert("end", f"{text}\n")
        self.logTxt.see("end")

在setFrmCtrl中,除了热榜分期的标签外,设置了两个按钮,分别是爬取热榜和导出热榜,二者分别绑定了两个函数btnHeatCrawler和mbExportHeat,这两个函数暂时还没实现。

在CSDN工具Frame下面,是信息界面,信息界面封装了两个组件,一个用于返回实时信息,是个Label,绑定了名为self.infoCSDN的Label;另一个是多行文本组件Text,并为其设置了addLogs函数,用于快速添加内容。布局结果如下

在这里插入图片描述

函数封装

尽管此前已经多少知道如何用selenium爬取热榜了,但所有代码都是以脚本的形式写出来的,并不适合调用。所以接下来就要把这些代码函数化,首先是打开Edge的函数

# 打开Edge
def openEdge(url):
    op = webdriver.EdgeOptions()
    op.add_argument('--headless')
    driver = webdriver.Edge(options=op)
    driver.get(url)
    return driver

这里用到了EdgeOptions,其参数headless表示不必打开Edge,而可以后台运行,不然Edge总会跳出来,影响其他工作。

然后就是用于热榜爬取的主要函数,封装如下,其中callback是一个回调函数,方便将运行信息传给用户界面,后面的key,则考虑到以后会爬取各领域热榜,于是预留一个接口。

# 输入回调函数
def getHeatInfos(callback, key=None):
    nBlogs = 100
    driver = openEdge('https://blog.csdn.net/rank/list')

    titleClass = "floor-rank-item"
    ts= []
    # 获取100篇热榜博客
    while len(ts) < nBlogs:
        script = "window.scrollTo(0,document.body.scrollHeight)"
        driver.execute_script(script)
        ts = driver.find_elements(By.CLASS_NAME, titleClass)
        time.sleep(0.5)
        info = f"已读取到{len(ts)}篇热榜博客"
        if callback: callback([], info)
        
    callback([], f"已读取到所有热榜博客,开始处理")
    blogs = []
    for t in ts:
        ws = t.text.split('\n')
        blogs.append([ws[i] for i in [0, 1, 10, 2, 4, 6, 8]])
        b = blogs[-1]
        callback(blogs, f"正在处理第{b[0]}篇博客,热度{b[-1]}")
    callback(blogs, f"全部热榜博客处理完毕")
    return blogs

这个函数的代码几乎都来自CSDN热榜分析。

最后,是导出CSV的函数

def saveAsCSV(path, infos, title=['id','name', 'date', '']):
    with open(path, 'w', newline='', encoding='utf8') as f:
        w = csv.writer(f)
        w.writerow(title)
        for i in infos: 
            try: w.writerow(i)
            except : continue

功能实现

最后,实现窗口程序对热榜爬取函数的调用逻辑。考虑到爬虫往往是个耗时的操作,所以必须使用多线程。

from threading import Thread

最终热榜爬取函数的内容如下,其实核心代码就只有一行,表示开启一个线程来执行getHeatInfo,并把self.backHeatCrawler作为参数输入了进去。

backHeatCrawler是用于反馈信息的回调函数,其功能如其参数一样,共有两个,一个是保存爬取到的博客信息,二则是展示爬虫进度。

# 热榜
def btnHeatCrawler(self):
    Thread(target = getHeatInfos,
        args=(self.backHeatCrawler,), daemon=True).start()

def backHeatCrawler(self, blogs, info):
    self.heatBlogs = blogs
    self.infoCSDN.set(info)
    if info.endswith("完毕"):
        self.addLogs(f"共读取了{len(self.heatBlogs)}热榜博客")

最后完成数据导出工作,其主要功能就是调用saveAsCSV函数,只不过其中加入了文件名对话框等交互方式。

def mbExportHeat(self):
    heatHead = ["序号", "标题", "作者", "浏览", "评论", "收藏", "热度"]
    self.mbExport(self.heatBlogs, heatHead, "热榜博客")
    
def mbExport(self, lst, title, info):
    self.infoCSDN.set(f"正在保存{info}")
    path = asksaveasfilename(filetypes=[("数据文件", "csv")], 
        defaultextension='.csv')
    if path=="":
        self.infoCSDN.set(f"未保存{info}")
        return
    saveAsCSV(path, lst, title=['id'])
    self.infoCSDN.set(f"{info}保存成功")
    self.addLogs(f"{info}保存成功")

最终演示效果如下

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1030033.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IOS版微信8.0.42正式版已推出:新增多语言“翻译”!

微信最近的更新的真的很快&#xff0c;包括Mac、iPhone、PC端以及安卓版本都进行了更新推送。 微信iOS 8.0.42正式版已经向公众开放&#xff0c;这个新版本在原有功能的基础上&#xff0c;对群管理界面、翻译功能、小程序等方面进行了优化和改进&#xff0c;让用户的使用体验更…

嵌入式Linux--进程间通信--共享内存

1. 回顾之前的通信内容&#xff1a; 进程间通信主要有5种通信方式 1、无名管道&#xff08;只能单向发送或接收&#xff09; 2、命名管道&#xff08;同上&#xff09; 3、消息队列&#xff08;可以发送&#xff0c;也能接收消息&#xff09; 4、共享内存&#xff08;有一块公…

呼叫中心系统角色功能的应用

呼叫中心系统拥有强大的功能&#xff0c;根据角色不同能够使用的功能也是不同的&#xff0c;按规则是角色权限越大&#xff0c;可以使用的功能也越多。如普通坐席最重要的工作就是接打电话&#xff0c;没必要使用全部功能&#xff0c;只需有几个话务相关功能就足够了&#xff0…

phpstudy RCE脚本编写(Python)

文章目录 编写过程脚本优化 编写过程 关于phpstudy 2016-2018 RCE漏洞的验证&#xff0c;请移步我的这篇博客 phpstudy2016 RCE漏洞验证。 将之前漏洞验证的数据包复制下来&#xff0c;编写脚本时需要使用&#xff1a; GET /phpinfo.php HTTP/1.1 Host: 10.9.75.164 Upgrade…

无涯教程-JavaScript - SERIESSUM函数

描述 SERIESSUM函数返回幂级数的总和。幂级数展开可近似许多功能。 语法 SERIESSUM (x, n, m, coefficients)争论 Argument描述Required/OptionalXThe input value to the power series.RequiredNThe initial power to which you want to raise x.RequiredMThe step by whi…

找不到名称 “$“。是否需要安装 jQuery 的类型定义? 请尝试使用 `npm i --save-dev @types/jquery`。

vitevue3环境 1、安装jQuery npm install --save jquery 2、在main.ts文件进行配置 declare const window: any; import jQuery from jquery; window.$ window.jQuery jQuery; 注意&#xff1a;需要声明window属性&#xff1b; 要不然会报错&#xff1a;类型“Window &am…

八、数据类型转换

数据类型转换 1.数据类型转换1.1.隐式类型转换1.2.显式类型转换1.3.训练11.4.训练2 —————————————————————————————————————————————————— 1.数据类型转换 类型转换是将一个值从一种类型更改为另一种类型的过程。例如&…

Navicat 武林小秘籍 | 如何在数据同步期间查看源和目标之间的数据差异

可应用操作系统&#xff1a;Windows、macOS、Linux 可应用 Navicat 产品&#xff1a;Navicat for MySQL、Navicat for PostgreSQL、Navicat for Oracle、Navicat for SQL Server、Navicat for MariaDB、Navicat for SQLite、Navicat for MongoDB、Navicat Premium 可应用 Nav…

【记录】Python 之于 C/C++ 区别

记录本人在 Python 上经常写错的一些地方&#xff08;C/C 写多了&#xff0c;再写 Python 有点切换不过来&#xff09; 逻辑判断符号用 and、or、!可以直接 10 < num < 30 比较大小分支语句&#xff1a;if、elif、else使用 、-&#xff0c;Python 中不支持 、- - 这两个…

LVS 负载均衡集群的DR模式配置

集群 集群的概述 集群技术是一种用于提高系统性能、可用性、容错性和可扩展性的关键方法。它涉及将多个计算资源或节点组合在一起&#xff0c;以协同工作以处理任务、服务请求或数据处理。 集群类型 无论是哪种集群&#xff0c;都至少包括两台节点服务器&#xff0c;而对外…

AB实验总结

互联网有线上系统&#xff0c;可做严格的AB实验。传统行业很多是不能做AB实验的。 匹配侧是采用严格的AB实验来进行模型迭代&#xff0c;而精细化定价是不能通过AB实验来评估模型好坏&#xff0c;经历过合成控制法、双重差分法&#xff0c;目前采用双重差分法来进行效果评估。…

无涯教程-JavaScript - MROUND函数

描述 MROUND函数返回一个舍入为所需倍数的数字。 MROUND函数是Excel中的15个舍入函数之一。 语法 MROUND (number, multiple)争论 Argument描述Required/OptionalNumberThe value to round.RequiredMultipleThe multiple to which you want to round number.Required Note…

如何使用chorme版本对应的ChromeDriver(不用更改Chrome版本)

为什么要这样 我们发现在 官网 下载ChromeDriver的地方&#xff0c;没有对于高版本的下载包&#xff0c;可是我们的浏览器版本是 117.0.5938.88&#xff0c;我又不想降低本地的Chrome版本&#xff0c;因为这样也太蠢了&#xff0c;每次更新后可能老版本就不适用了。 使用方法 …

9.2.3.1 【MySQL】XDES Entry链表

当段中数据较少的时候&#xff0c;首先会查看表空间中是否有状态为 FREE_FRAG 的区&#xff0c;也就是找还有空闲空间的碎片区&#xff0c;如果找到了&#xff0c;那么从该区中取一些零碎的页把数据插进去&#xff1b;否则到表空间下申请一个状态为 FREE 的区&#xff0c;也就是…

链表的分割——哨兵位

现有一链表的头指针 ListNode* pHead&#xff0c;给一定值x&#xff0c;编写一段代码将所有小于x的结点排在其余结点之前&#xff0c;且不能改变原来的数据顺序&#xff0c;返回重新排列后的链表的头指针。 思路&#xff0c;把链表分成两个新链表&#xff0c;然后连接起来 代码…

vue3 @click那些事

vue3element-plus vue3 click那些事 1.动态决定click能否点击 1.动态决定click能否点击 只需要在点击事件前加一个判断条件

MTK联发科MT6762/MT8788安卓核心板性能参数对比

MT6762核心板是联发科的八核处理器&#xff0c;采用12nm制程工艺。MT6762具有集成的蓝牙、fm、WLAN和gps模块&#xff0c;是一个高度集成的基带平台&#xff0c;包括调制解调器和应用处理子系统启用LTE/LTE-A和C2K智能手机应用程序。MT6762芯片集成了ARM Cortex-A53&#xff0c…

乒乓球廉价底板和套胶对比分析

手机最近没办法写微博&#xff0c;在火车上没事&#xff0c;折腾了下&#xff0c;升级后可以了&#xff0c;我近期又打了很多套胶&#xff0c;我还录了段粘拍的视频一会分享。 这次我还是说几款底板和套胶的感受&#xff0c;最近买了dj200不带A底板&#xff0c;palio cc 和银河…

Git小乌龟不弹add push commit的方法

1.关于使用Git小乌龟无法弹出Add菜单的问题 第一次使用小乌龟软件&#xff0c;发现可以正常将程序从Gitee仓库中克隆到本地&#xff0c;但是在将本地的程序上传到Gitee仓库中时&#xff0c;TortoiseGit无法弹出Add那一系列菜单&#xff0c;如下图所示&#xff1a; 2.解决方法 …

大数据-hadoop

1.hadoop介绍 1.1 起源 1.2 版本 1.3生产环境版本选择 Hadoop三大发行版本:Apache、Cloudera、Hortonworks Apache版本最原始的版本 Cloudera在大型互联网企业中用的较多 Hortonworks文档较好 1.4架构 hadoop由三个模块组成 分布式存储HDFS 分布式计算MapReduce 资源调度引擎Y…