【2024-完整版】python爬虫 批量查询自己所有CSDN文章的质量分:附整个实现流程

news/2024/7/19 12:00:40 标签: python, pandas, excel, 爬虫, 经验分享, CSDN

【2024】批量查询CSDN文章质量分

  • 写在最前面
  • 一、分析获取步骤
  • 二、获取文章列表
    • 1. 前期准备
    • 2. 获取文章的接口
    • 3. 接口测试(更新重点)
  • 三、查询质量分
    • 1. 前期准备
    • 2. 获取文章的接口
    • 3. 接口测试
  • 四、python代码实现
    • 1. 分步实现
    • 2. 批量获取文章信息
    • 3. 从excel中读取文章url,查询质量分,再将质量分添加到excel
    • 4. 全部代码


请添加图片描述

🌈你好呀!我是 是Yu欸
🌌 2024每日百字篆刻时光,感谢你的陪伴与支持 ~
🚀 欢迎一起踏上探险之旅,挖掘无限可能,共同成长!

前些天发现了一个人工智能学习网站,内容深入浅出、易于理解。如果对人工智能感兴趣,不妨点击查看。

写在最前面

之前的代码一直报错521,不清楚什么原因
因此重新分析整个过程,并对代码进行更新

结果如图

在这里插入图片描述

参考:
批量获取CSDN文章对文章质量分进行检测,有助于优化文章质量
python】我用python写了一个可以批量查询文章质量分的小项目(纯python、flask+html、打包成exe文件)

一、分析获取步骤

  1. 获取博主的所有文章,并且拿到对应的url地址。(需要分析接口)
  2. 获取到url地址,我们需要使用官方查询质量分网页的接口进行请求。(需要分析接口)
  3. 接口分析完成后,我们就可以按照我们的需求进行代码编写了。

二、获取文章列表

1. 前期准备

浏览器访问需要获取文章的博主首页地址,并且打开开发者工具快捷键F12

然后点击网络选项,我们在刷新页面可以看到发送的请求地址。

然后我们选择XHR过滤掉我们不需要看到请求,但是这里面也没有我们需要的请求,但是没关系,我们只要想一下什么情况下会发送请求获取文章呢?答案就是下滑底部后,会重新发送请求获取新的文章并且渲染到页面。

点击删除请求这样我们下拉就可以清晰看到请求的接口数据

发现就是该接口发送的请求获取文章数据

在这里插入图片描述

2. 获取文章的接口

我们主要还是研究获取文章的接口
看请求的 url,是一个 GET 请求。

在这里插入图片描述

请求URL:
https://blog.csdn.net/community/home-api/v1/get-business-list

https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=20&businessType=blog&orderby=&noMore=false&year=&month=&username=wtyuong

这个接口也比较简单只需要携带4个参数:

  • 页码:page 第几页
  • 页数:size 页码展示的条数
  • 用户名称:username 需要查询的博主名(csdn id)
  • 业务类型:businessType 默认使用 blog 这个类型对应

分析响应体:可以返回每篇文章的地址、阅读量、评论量等数据。

python">['title', 'url', 'postTime', 'viewCount', 'collectCount', 'diggCount', 'commentCount']
['文章标题', 'URL', '发布时间', '阅读量', '收藏量', '点赞量', '评论量']

在这里插入图片描述

3. 接口测试(更新重点)

用ApiPost这个软件来进行接口测试

发现实际上,如果只发送url是会报错的,提示:请进行安全验证

在这里插入图片描述

服务器要求进行“安全验证”以继续访问。这通常是网站的防爬机制之一,用于识别和阻止自动化的访问尝试。面对这种情况,有几个可能的解决方案:

  1. 用户代理(User-Agent):确保你的请求头中包含了一个合理的用户代理(User-Agent)字符串。有些网站会检查这个字段来判断请求是否来自真实的浏览器用户。尝试使用常见浏览器的用户代理字符串。

  2. Cookies:某些网站要求请求携带有效的cookies来通过安全验证。你可以先手动访问该网站,通过浏览器获取到有效的cookies,并在你的爬虫请求中携带这些cookies。

  3. 处理JavaScript挑战:如果网站使用JavaScript生成动态内容或执行安全验证,你可能需要使用Selenium或Puppeteer这类工具,它们可以模拟真实的浏览器环境,执行JavaScript代码,并处理复杂的交互。

  4. 验证码识别:如果需要验证码验证,你可能需要集成验证码识别服务(如Google reCAPTCHA解决方案)或使用OCR(光学字符识别)技术尝试自动识别和填写验证码,虽然这可能面临法律和道德问题。

  5. 频率限制:确保你的请求频率不要太高,高频率的请求更容易触发网站的安全防护机制。尝试降低请求频率,或者在连续的请求之间增加延时。

经过测试,请求头只需要包括Cookies、Referer参数即可。

在这里插入图片描述

nice!

关于如何获取cookie:

在这里插入图片描述

三、查询质量分

流程和上述一样

1. 前期准备

先去质量查询地址:https://www.csdn.net/qc

在这里插入图片描述

2. 获取文章的接口

输入任意一篇文章地址进行查询,同时检查页面,在Network选项下即可看到调用的API的请求地址、请求方法、请求头、请求体等内容:

看请求的 url,是一个 POST 请求。

https://bizapi.csdn.net/trends/api/v1/get-article-score

在这里插入图片描述

POST 请求携带参数是 url。

在这里插入图片描述

我们得到的响应数据:文章id、分数、消息、发布时间。

在这里插入图片描述

3. 接口测试

请求头里面很多参数是不需要的,我们用ApiPost这个软件来测试哪些是必要参数。

需要注意的是请求体的类型是form-data类型

在这里插入图片描述

经过测试,请求头只需要下面这几个参数即可。

请求头分析
X-Ca-Key:使用自己浏览器的
X-Ca-Nonce:使用自己浏览器的
X-Ca-Signature:使用自己浏览器的
X-Ca-Signature-Headers:x-ca-key,x-ca-nonce
X-Ca-Signed-Content-Type:multipart/form-data
Accept :application/json, text/plain, /

在这里插入图片描述

响应体分析:

  • score:文章的分数
  • message:给出的建议

在这里插入图片描述

python_160">四、python代码实现

1. 分步实现

为了便于理解,把程序分为2个部分:

  • 批量获取文章信息,保存为excel文件;
  • excel中读取文章url,查询质量分,再将质量分添加到excel

2. 批量获取文章信息

python"># 批量获取文章信息并保存到excel
class CSDNArticleExporter:
    def __init__(self, username, cookies, Referer, page, size, filename):
        self.username = username
        self.cookies = cookies
        self.Referer = Referer
        self.size = size
        self.filename = filename
        self.page = page

    def get_articles(self):
        url = "https://blog.csdn.net/community/home-api/v1/get-business-list"
        params = {
            "page": {self.page},
            "size": {self.size},
            "businessType": "blog",
            "username": {self.username}
        }
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
            'Cookie': self.cookies,  # Setting the cookies string directly in headers
            'Referer': self.Referer
        }

        try:
            response = requests.get(url, params=params, headers=headers)
            response.raise_for_status()  # Raises an HTTPError if the response status code is 4XX or 5XX
            data = response.json()
            return data.get('data', {}).get('list', [])
        except requests.exceptions.HTTPError as e:
            print(f"HTTP错误: {e.response.status_code} {e.response.reason}")
        except requests.exceptions.RequestException as e:
            print(f"请求异常: {e}")
        except json.JSONDecodeError:
            print("解析JSON失败")
        return []
    
    def export_to_excel(self):
        df = pd.DataFrame(self.get_articles())
        df = df[['title', 'url', 'postTime', 'viewCount', 'collectCount', 'diggCount', 'commentCount']]
        df.columns = ['文章标题', 'URL', '发布时间', '阅读量', '收藏量', '点赞量', '评论量']
        # df.to_excel(self.filename)
        # 下面的代码会让excel每列都是合适的列宽,如达到最佳阅读效果
        # 你只用上面的保存也是可以的
        # Create a new workbook and select the active sheet
        wb = Workbook()
        sheet = wb.active
        # Write DataFrame to sheet
        for r in dataframe_to_rows(df, index=False, header=True):
            sheet.append(r)
        # Iterate over the columns and set column width to the max length in each column
        for column in sheet.columns:
            max_length = 0
            column = [cell for cell in column]
            for cell in column:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(cell.value)
                except:
                    pass
            adjusted_width = (max_length + 5)
            sheet.column_dimensions[column[0].column_letter].width = adjusted_width
        # Save the workbook
        wb.save(self.filename)

在这里插入图片描述

excelurlexcel_239">3. 从excel中读取文章url,查询质量分,再将质量分添加到excel

python">class ArticleScores:
    def __init__(self, filepath):
        self.filepath = filepath

    @staticmethod
    def get_article_score(article_url):
        url = "https://bizapi.csdn.net/trends/api/v1/get-article-score"
        # TODO: Replace with your actual headers
        headers = {
            "Accept": "application/json, text/plain, */*",
            "X-Ca-Key": "203930474",
            "X-Ca-Nonce": "b35e1821-05c2-458d-adae-3b720bb15fdf",
            "X-Ca-Signature": "gjeSiKTRCh8aDv0UwThIVRITc/JtGJkgkZoLVeA6sWo=",
            "X-Ca-Signature-Headers": "x-ca-key,x-ca-nonce",
            "X-Ca-Signed-Content-Type": "multipart/form-data",
        }
        data = {"url": article_url}
        try:
            response = requests.post(url, headers=headers, data=data)
            response.raise_for_status()  # This will raise an error for bad responses
            return response.json().get('data', {}).get('score', 'Score not found')
        except requests.RequestException as e:
            print(f"Request failed: {e}")
            return "Error fetching score"

    def get_scores_from_excel(self):
        df = pd.read_excel(self.filepath)
        urls = df['URL'].tolist()
        scores = [self.get_article_score(url) for url in urls]
        return scores

    def write_scores_to_excel(self):
        df = pd.read_excel(self.filepath)
        df['质量分'] = self.get_scores_from_excel()
        df.to_excel(self.filepath, index=False)

4. 全部代码

python">import json
import pandas as pd
from openpyxl import Workbook, load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows
import math
import requests

# 批量获取文章信息并保存到excel
class CSDNArticleExporter:
    def __init__(self, username, cookies, Referer, page, size, filename):
        self.username = username
        self.cookies = cookies
        self.Referer = Referer
        self.size = size
        self.filename = filename
        self.page = page

    def get_articles(self):
        url = "https://blog.csdn.net/community/home-api/v1/get-business-list"
        params = {
            "page": {self.page},
            "size": {self.size},
            "businessType": "blog",
            "username": {self.username}
        }
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
            'Cookie': self.cookies,  # Setting the cookies string directly in headers
            'Referer': self.Referer
        }

        try:
            response = requests.get(url, params=params, headers=headers)
            response.raise_for_status()  # Raises an HTTPError if the response status code is 4XX or 5XX
            data = response.json()
            return data.get('data', {}).get('list', [])
        except requests.exceptions.HTTPError as e:
            print(f"HTTP错误: {e.response.status_code} {e.response.reason}")
        except requests.exceptions.RequestException as e:
            print(f"请求异常: {e}")
        except json.JSONDecodeError:
            print("解析JSON失败")
        return []
    
    def export_to_excel(self):
        df = pd.DataFrame(self.get_articles())
        df = df[['title', 'url', 'postTime', 'viewCount', 'collectCount', 'diggCount', 'commentCount']]
        df.columns = ['文章标题', 'URL', '发布时间', '阅读量', '收藏量', '点赞量', '评论量']
        # df.to_excel(self.filename)
        # 下面的代码会让excel每列都是合适的列宽,如达到最佳阅读效果
        # 你只用上面的保存也是可以的
        # Create a new workbook and select the active sheet
        wb = Workbook()
        sheet = wb.active
        # Write DataFrame to sheet
        for r in dataframe_to_rows(df, index=False, header=True):
            sheet.append(r)
        # Iterate over the columns and set column width to the max length in each column
        for column in sheet.columns:
            max_length = 0
            column = [cell for cell in column]
            for cell in column:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(cell.value)
                except:
                    pass
            adjusted_width = (max_length + 5)
            sheet.column_dimensions[column[0].column_letter].width = adjusted_width
        # Save the workbook
        wb.save(self.filename)

class ArticleScores:
    def __init__(self, filepath):
        self.filepath = filepath

    @staticmethod
    def get_article_score(article_url):
        url = "https://bizapi.csdn.net/trends/api/v1/get-article-score"
        # TODO: Replace with your actual headers
        headers = {
            "Accept": "application/json, text/plain, */*",
            "X-Ca-Key": "203930474",
            "X-Ca-Nonce": "b35e1821-05c2-458d-adae-3b720bb15fdf",
            "X-Ca-Signature": "gjeSiKTRCh8aDv0UwThIVRITc/JtGJkgkZoLVeA6sWo=",
            "X-Ca-Signature-Headers": "x-ca-key,x-ca-nonce",
            "X-Ca-Signed-Content-Type": "multipart/form-data",
        }
        data = {"url": article_url}
        try:
            response = requests.post(url, headers=headers, data=data)
            response.raise_for_status()  # This will raise an error for bad responses
            return response.json().get('data', {}).get('score', 'Score not found')
        except requests.RequestException as e:
            print(f"Request failed: {e}")
            return "Error fetching score"

    def get_scores_from_excel(self):
        df = pd.read_excel(self.filepath)
        urls = df['URL'].tolist()
        scores = [self.get_article_score(url) for url in urls]
        return scores

    def write_scores_to_excel(self):
        df = pd.read_excel(self.filepath)
        df['质量分'] = self.get_scores_from_excel()
        df.to_excel(self.filepath, index=False)

if __name__ == '__main__':
    total = 10     #已发文章总数量
    # TODO:调整为你自己的cookies,Referer,CSDNid, headers
    cookies = 'uuid_tt_dd=10'  # Simplified for brevity
    Referer = 'https://blog.csdn.net/WTYuong?type=blog'
    CSDNid = 'WTYuong'
    t_index = math.ceil(total/100)+1 #向上取整,半闭半开区间,开区间+1。
    # 获取文章信息
    # CSDNArticleExporter("待查询用户名", 2(分页数量,按总文章数量/100所得的分页数),总文章数量仅为设置为全部可见的文章总数。
    # 100(最大单次查询文章数量不大于100), 'score1.xlsx'(待保存数据的文件,需要和下面的一致))
    for index in range(1,t_index): #文章总数
        filename = "score"+str(index)+".xlsx"
        exporter = CSDNArticleExporter(CSDNid, cookies, Referer, index, 100, filename)  # Replace with your username
        exporter.export_to_excel()
        # 批量获取质量分
        score = ArticleScores(filename)
        score.write_scores_to_excel()

http://www.niftyadmin.cn/n/5427899.html

相关文章

【日志分析】Android 运营商名称显示优先级(AlphaTag/SPN)

规则说明 MTK平台的设计,优先级:(MD)CIEV > Eons > Nitz > xml 功能代码说明 【笔记】Android Telephony 漫游SPN显示定制(Roaming Alpha Tag)-CSDN博客 日志分析 关键字:lookupOpe…

Python 井字棋游戏

井字棋是一种在3 * 3格子上进行的连珠游戏,又称井字游戏。井字棋的游戏有两名玩家,其中一个玩家画圈,另一个玩家画叉,轮流在3 * 3格子上画上自己的符号,最先在横向、纵向、或斜线方向连成一条线的人为胜利方。如图1所示…

游戏发行新方式——游戏海外发行代理

随着全球游戏市场的蓬勃发展,许多游戏开发者纷纷迈向海外市场,寻找更广阔的发展空间。在这个过程中,游戏海外发行代理逐渐成为行业中备受关注的服务模式。本文将深入探讨什么是游戏海外发行代理,为何需要海外发行代理以及这一模式…

web 服务搭建

实验拓扑图: 实验环境搭建 Centos7-5作为Client(12.0.0.12/24);Centos7-1作为网关服务器(配置两块网卡ens33 192.168.246.7/24,ens36 12.0.0.1/24);Centos7-2作为Web1(19…

OpenAI GPT-4.5 Turbo 泄露,六月或将发布

网络媒体THE DECODER透露,OpenAI即将推出的模型GPT-4.5 Turbo的信息在官方公告之前就已在线泄露。这次泄露似乎源自OpenAI的网络团队,导致Bing和DuckDuck Go等搜索引擎提前索引了GPT-4.5 Turbo的产品页面。尽管信息提前曝光,但实际的产品页面…

springcloud第3季 consul服务发现注册,配置中心2

一 consul的作用 1.1 为何使用注册中心 为何要用注册中心? 1.A服务调用B服务,使用ip和端口,如果B服务的ip或者端口发生变化,服务A需要进行改动; 2.如果在分布式集群中,部署多个服务B,多个服…

【论文笔记合集】Transformers in Time Series A Survey综述总结

本文作者: slience_me 文章目录 Transformers in Time Series A Survey综述总结1 Introduction2 Transformer的组成Preliminaries of the Transformer2.1 Vanilla Transformer2.2 输入编码和位置编码 Input Encoding and Positional Encoding绝对位置编码 Absolute …

【零基础学习05】嵌入式linux驱动中platform与设备树基本实现

大家好,为了进一步提升大家对实验的认识程度,每个控制实验将加入详细控制思路与流程,欢迎交流学习。 今天主要学习一下,基于总线、设备和驱动进行匹配的平台驱动模型,这次将采用设备树的platform设备与驱动的编写方法,目前绝大多数的Linux内核已经支持设备树,这次主要来…