CSDN热榜分析3:实现领域热榜的爬取

news2024/12/26 1:39:18

文章目录

    • 领域热榜爬取函数
    • 领域热榜按钮
    • 功能实现

热榜分析系列: CSDN热榜分析🔥 UI界面🔥 领域热榜

领域热榜爬取函数

CSDN热榜共有21个子领域,包括C++、云原生、人工智能、前沿技术、软件工程、后端、Java、JavaScript、PHP、Python、区块链、大数据、移动开发、嵌入式、开发工具、结构与算法、微软技术、测试、游戏、网络、运维等。

这些领域热榜的地址https://blog.csdn.net/rank/list/content?type=?,问好表示所在榜单名称,例如Python领域热榜的地址是https://blog.csdn.net/rank/list/content?type=python。

而且领域热榜和总榜的html结构是完全相同的,也就是说之前用于总榜的getHeatInfos可以继续使用。唯一不同是,领域热榜只排到第50名,而且有些可能不足50名,所以需要做一个标记来终止其运行,最终getHeatInfos修改如下

def getHeatInfos(callback, key=None):
    URL_ALL = 'https://blog.csdn.net/rank/list'
    URL_SUB = f'https://blog.csdn.net/rank/list/content?type={key}'
    nBlogs = 50 if key else 100

    driver = openEdge(URL_SUB if key else URL_ALL)

    titleClass = "floor-rank-item"
    ts, nTs, it = [], 0, 0
    # 获取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)
        
        it = it+1 if len(ts) == nTs else 0
        nTs = len(ts)
        if it > 5 : break

    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

领域热榜按钮

接下来添加一个领域热榜的按钮,考虑到这些领域实在太多,不太好每个领域给个热榜,故而用Menubutton来实现。又考虑到一个一个去爬太费劲,所以除了各领域之外,提供一个全部爬取的选项。

def setFrmHeat(self, frmHeat):
    # 省略。。。
    mb = ttk.Menubutton(frmHeat, width=10, text="领域内容榜")
    mb.pack(side=tk.LEFT)
    m = tk.Menu(mb, tearoff=False)
    m.add_command(label="全部领域", 
        command = lambda : self.mbSubHeatCrawler(None))
    for key in SUB_HEATS:
        m.add_command(label=key,
            command = lambda : self.mbSubHeatCrawler(key))    
    mb.config(menu=m)
    # 省略。。。

def mbSubHeatCrawler(self, key):
    pass

setFrmHeat函数在之前的博客中已经定义了,上面只给出需要添加的Menubutton的代码。其中SUB_HEATS被做成了一个全局变量,便于引用。

SUB_HEATS = ["C++", "云原生", "人工智能", "前沿技术", "软件工程", 
    "后端", "Java", "JavaScript", "PHP", "Python", "区块链", 
    "大数据", "移动开发", "嵌入式", "开发工具", "结构与算法", 
    "微软技术", "测试", "游戏", "网络", "运维"]

界面效果如下

在这里插入图片描述

功能实现

接下来要实现mbSubHeatCrawler函数,同时需要更新导出热榜按钮的功能,即既可以导出总榜,也可以导出领域热榜。

同时,为了能够一次性把所有领域热榜都爬取一遍,需要再实现一个函数,这个函数写在类外面,和getHeatInfos级别相同。

def getAllSubHeatInfos(callback):
    blogs = {}
    for key in SUB_HEATS:
        callback(blogs, f"正在读取{key}领域热榜")
        blogs[key] = getHeatInfos(callback, key)
        callback(blogs, f"{key}已经读取完成")
    callback(blogs, f"所有领域热榜都已读取完毕")

然后就是重头戏,领域热榜的爬取逻辑。由于每个领域都有自己的榜单,所以存储领域热榜的数据用字典最为合适,故而添加一个类成员self.subHeats。有关各领域热榜的实现逻辑如下。

def mbSubHeatCrawler(self, field):
    if not field:
        self.subHeats = {}
        Thread(target = getAllSubHeatInfos,
            args=(self.backAllSubHeat, ), daemon=True).start()
    else:
        func = lambda L, info : self.backOneSubHeat(L, info, field)
        Thread(target = getHeatInfos,
            args=(func, field), daemon=True).get()

def backOneSubHeat(self, L, info, field=None):
    self.subheats[field] = L
    self.infoCSDN.update(dct)
    if info.endswith("完毕"):
        n = len(self.subheats[field])
        self.addLogs(f"共读取了{key}领域{n}篇博客")

def backAllSubHeat(self, dct, info):
    if type(dct) == dict:
        self.subHeats.update(dct)
    self.infoCSDN.set(info)
    if info.endswith("完毕"):
        self.addLogs(f"共读取了{len(self.subHeats)}个领域")

同时,热榜导出函数也要更新

def mbExportHeat(self):
    heatHead = ["序号", "标题", "作者", "浏览", "评论", "收藏", "热度"]
    if len(self.heatBlogs) > 0:
        self.mbExport(self.heatBlogs, heatHead, "热榜博客")
    if len(self.subHeats) > 0:
        subs = []
        for k,v in self.subHeats.items():
            subs.extend([[k]+L for L in v])
        subHead = ["领域"] + heatHead
        self.mbExport(subs, subHead, "各领域热榜博客")

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

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

相关文章

NSSCTF

[SWPUCTF 2021 新生赛]gift_F12 在源代码界面找到了flag [SWPUCTF 2021 新生赛]jicao 源码 <?php highlight_file(index.php); include("flag.php"); $id$_POST[id]; $jsonjson_decode($_GET[json],true); if ($id"wllmNB"&&$json[x]"…

Learn Prompt- Midjourney 图片生成:常用参数

在上一页当中&#xff0c;我们在解说基本设置的同时&#xff0c;举例了不少以--开头的参数。 参数是添加到提示中的选项&#xff0c;可更改图像的生成方式&#xff0c;图像的纵横比&#xff0c;在 Midjourney模型版本之间切换&#xff0c;更改使用的 Upscaler 等等。使用参数的…

基于FPGA的图像直方图统计实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1、图像数据传输 4.2、直方图统计算法 4.3、时序控制和电路设计 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 timescal…

阻塞队列-生产者消费者模型

阻塞队列介绍标准库阻塞队列使用基于阻塞队列的简单生产者消费者模型。实现一个简单型阻塞队列 &#xff08;基于数组实现&#xff09; 阻塞队列介绍 不要和之前学多线程的就绪队列搞混&#xff1b; 阻塞队列&#xff1a;也是一个队列&#xff0c;先进先出。带有特殊的功能 &…

LeetCode_二叉树_中等_1372.二叉树中的最长交错路径

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一棵以 root 为根的二叉树&#xff0c;二叉树中的交错路径定义如下&#xff1a; 选择二叉树中 任意 节点和一个方向&#xff08;左或者右&#xff09;。如果前进方向为右&#xff0c;那么移动到当前节点…

基于Python + SnowNLP实现一个文本情感分析系统

当你浏览社交媒体、新闻或任何数字内容时&#xff0c;你有没有想过背后的技术是如何分析和理解这些文本的情感的&#xff1f;有没有想过在数百万条评论、帖子或文章中&#xff0c;如何快速地识别出其中的积极和消极情绪&#xff1f;在这篇文章中&#xff0c;我们将揭示其中的奥…

数据结构—堆(C语言实现)

目录 堆是什么&#xff1f; 一、大堆 一、小堆 如何实现堆&#xff1f; 代码实现 &#xff1f; 一、定义堆的结构体 二、初始化堆 三、构建堆 1.利用向下调整算法 2.开始构建 四、插入元素 1.利用向上调整算法 五、取出堆顶元素、销毁堆 六、堆排序 Extra&#…

SpringBoot中xml映射文件

1.规范 说明&#xff1a;XML映射文件的名称与Mapper接口名称一致&#xff0c;并且将XML映射文件和Mapper接口放置在相同包下&#xff08;同包同名&#xff09;。 xML映射文件的namespace属性为Mapper接口全类名一致。 XML映射文件中sql语句的id与Mapper接口中的方法名一致&…

Spring面试题4:面试官:说一说Spring由哪些模块组成?说一说JDBC和DAO之间的联系和区别?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring由哪些模块组成? Spring是一个开源的Java框架,由多个模块组成,每个模块都提供不同的功能和特性。下面是Spring框架的主要模块: S…

基于nodejs+vue办公OA公文发文件管理系统

论文的研究内容包括&#xff1a;公文分类、公文信息、待办提醒等方面进行了研究。系统以当前应用最为广泛的nodejs语言为基础&#xff0c;结合了目前应用最为广泛的嵌入式嵌入式平台&#xff0c;集成了B/S体系结构。数据库选择简便高效的MySQL&#xff0c;vue框架。在OA公文发文…

大语言模型之十 SentencePiece

Tokenizer 诸如GPT-3/4以及LlaMA/LlaMA2大语言模型都采用了token的作为模型的输入输出&#xff0c;其输入是文本&#xff0c;然后将文本转为token&#xff08;正整数&#xff09;&#xff0c;然后从一串token&#xff08;对应于文本&#xff09;预测下一个token。 进入OpenAI官…

【LeetCode75】第六十三题 不同路径

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们返回地图的长和宽。问我们从地图的左上走到右下有几种方法。我们只能往下走或是往右走。 这个算是简单的二维动态规划题了。 …

Docker安装 MySQL8.0.33

Docker 核心&#xff1a;容器 Container 和镜像 Images Docker 安装镜像 mysql:8.0.33 图形化安装界面可选择版本较少 推荐使用命令行安装(可以自定义安装的版本) 版本安装命令链接&#xff1a;mysql Tags | Docker Hub 终端执行命令 docker pull mysql:8.0.33创建容器 安装完…

多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测(SE注意力机制)

多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测&#xff08;SE注意力机制&#xff09; 目录 多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测&#xff08;SE注意力机制&#xff09;预测效果基本描述模型描述程序设计参考资料 预测效果 基本…

【Hello Linux】高级IO Select

本篇博客介绍&#xff1a;介绍Linux中的高级IO 高级IO IO五种IO模型非阻塞IO如何判断异常读取 IO多路转接之Selectselect的优缺点 网络通信的本质其实就是一种IO 而我们知道的是 IO的效率实际上是十分低下的 所以说我们需要一些机制或者方法来解决这个效率问题 IO IO实际上…

R and RStudio的安装教程【2023】

首先需要安装R&#xff0c;才能安装RStudio。 安装包文末获取或者去官网获取&#xff0c;一样的&#xff1a; R的安装&#xff1a;&#xff08;很简单&#xff0c;如果你想安装到C盘&#xff0c;全部选项无脑选下一步&#xff0c;不想安装到C盘&#xff0c;就改一下就ok.&…

软件测试同行评审到底是什么?

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程&#xff0c;刷完面试就稳了&#xff0c;你也可以当高薪软件测试工程师&#xff08;自动化测试&#xff09; “同行评审是一种通过作者的同行(开发、测试、QA等)来确认缺陷和需要变更区域的检查方法。”在软件测试中…

五、C#—字符串

&#x1f33b;&#x1f33b; 目录 一、字符串1.1 字符类型1.2 转义字符1.3 字符串的声明及赋值1.3.1 c# 中的字符串1.3.2 声明字符串1.3.3 使用字符串1.3.4 字符串的初始化1.3.4.1 引用字符串常量之初始化1.3.4.2 利用字符数组初始化1.3.4.3 提取数组中的一部分进行初始化 1.3.…

企业微信自建小程序应用踩坑实践

最近开发了一个小程序接入企业微信的需求&#xff0c;企业微信的权限限制诸多&#xff0c;网上的完整示例又少之又少&#xff0c;因此踩了比较多坑&#xff0c;与大家分享。 开发调试 在开发者工具中如果直接使用微信小程序模式&#xff0c;调用wx.qy接口会提示不存在&#x…

Qt5开发及实例V2.0-第二十一章-Qt.Quick Controls开发基础

Qt5开发及实例V2.0-第二十一章-Qt.Quick Controls开发基础 第21章 Qt Quick Controls开发基础21.1 Qt Quick Controls概述21.1.1 第一个Qt Quick Controls程序21.1.2 Qt Quick窗体应用程序的构成 21.2 Qt Quick控件21.2.1 概述21.2.2 基本控件21.2.3 高级控件21.2.4 样式定制 2…