• 批量获取CSDN文章对文章质量分进行检测,有助于优化文章质量


    ⚙️简介

          有时候我们写文章是为了记录当下遇到的bug进行简单记录,这样CSDN会对文章进行算法评估文章的质量,这样就会导致我们写的文章字数较少,被系统误判,当然字数只是算法的一方面,算法会多多个角度进行评估,但是我觉得字数占比巨大,如果文章的字数啥的较少,对于我们人来说可能是比较好的,我可以清晰明了知道这篇文章大致讲了什么,我当前遇到的问题是不是可以在这里面得到我需要的。这一类文章不出意外系统评级的分数应该不会特别高,文字少了排版,配图,段落结构、正文长度都会受到影响。
          所以我想看看我之前写的文章质量分到底怎么样,看看是不是有一些简单明了几行代码,几句话就可以说的清楚的事情需要我长篇大论的写才能得到高分?但是官网的查质量分需要一篇一篇的查询效率极低,好歹这些年大大小小的文章也写了百来篇,用手那岂不是点出火星子都出来。

    在这里插入图片描述

    ✨分析获取步骤

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

    ⛳获取文章列表

    ☘️前期准备

          浏览器访问需要获取文章的博主首页地址,并且打开开发者工具快捷键F12,点击网络选项,我们在刷新页面可以看到发送的请求地址。

    在这里插入图片描述

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

    在这里插入图片描述

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

    在这里插入图片描述

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

    在这里插入图片描述

    在这里插入图片描述

    ✨ 接口解析

          使用工具请求接口按照浏览器发送的参数进行模拟,看看能拿到啥数据。可以看出这个接口返回的total是null他没给我们总的博客数量,但是没关系我们有的是办法拿到所有文章总数。前面说的主页面刷新有个接口可以得到博客的总条数,我在这简单给你们看一下这个接口。反正没有中条数也不影响我们爬取数据。

    该接口可以得到博客总数
    https://blog.csdn.net/community/home-api/v1/get-tab-total?username=qq_45502336

    在这里插入图片描述

    ⚡️ 获取文章的接口

    我们主要还是研究获取文章的接口
    https://blog.csdn.net/community/home-api/v1/get-business-list

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

    • 页码:page 第几页
    • 页数:size 页码展示的条数
    • 用户名称:username 需要查询的博主名
    • 业务类型:businessType 默认使用 blog 这个类型对应
      在这里插入图片描述

    模拟请求获取数据

    在这里插入图片描述

    前面由于选项卡是在最近所以导致返回的条数是null,这一次我们把选项卡选择到文章该接口就又返回了条数。

    在这里插入图片描述

    分析响应体:

    在这里插入图片描述
    响应体分析:

    • 文章标题:title
    • 文章查看地址:url
    • 文章描述:description
    • 查看文章的数量:viewCount
    • 收藏数:collectCount
    • 编辑地址:editUrl
    • 等数据

    我们本次目的已经达到,这些数据都可以通过这个接口获取到,我们就可以分析查询质量分的接口了。

    ☄️文章质量分接口

    ###*‍❄前期准备

    浏览器访问官方质量分页面https://www.csdn.net/qc

    在这里插入图片描述
    步骤后上面一致,主要的是找到对应的接口就行,这里就不过多解释了。

    在这里插入图片描述

    ⭐接口分析

    质量分接口
    https://bizapi.csdn.net/trends/api/v1/get-article-score
    该请求是POST请求

    在这里插入图片描述
    请求参数分析:

    • 文章地址:url

    需要注意的是请求体的类型是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:给出的建议

    在这里插入图片描述

    ⌛代码实现:

    ⚓核心代码:

    @Service
    public class CsdnScoreServiceImpl implements CsdnScoreService {
        private final String getArticleUrl = "https://blog.csdn.net/community/home-api/v1/get-business-list";
        private final String getArticlesScoreUrl = "https://bizapi.csdn.net/trends/api/v1/get-article-score";
    
        @Override
        public List<ArticleDetails> getAllTheArticles(String username, String businessType) {
            List<ArticleDetails> articleDetails = new ArrayList<>();
            Map<String, Object> param = new HashMap<>(4);
            param.put("size", 20);
            param.put("businessType", businessType);
            param.put("username", username);
            int index = 0;
            while (true) {
                index++;
                param.put("page", index);
                String msg = HttpUtil.get(getArticleUrl, param);
                if (ObjectUtil.isEmpty(msg)) {
                    break;
                }
                JSONObject data = JSONUtil.parseObj(msg);
                ArticleResponse articleResponse = JSONUtil.toBean(data, ArticleResponse.class);
                if (ObjectUtil.isNotEmpty(articleResponse)
                        && ObjectUtil.isNotEmpty(articleResponse.getData())
                        && ObjectUtil.isNotEmpty(articleResponse.getData().getList())
                ) {
                    articleDetails.addAll(articleResponse.getData().getList());
                } else {
                    break;
                }
            }
            return articleDetails;
        }
    
        @Override
        public Score getArticlesScore(String url) {
            Map<String, String> headers = new HashMap<>(6);
            headers.put("X-Ca-Key", "203930474");
            headers.put("X-Ca-Signature", "+fkC/Z91B8FRai2qZutPI0OyQCX7IsfVFcS7rPZk+YM=");
            headers.put("X-Ca-Nonce", "86970a2f-f385-4427-a40b-c90cb17c00b9");
            headers.put("X-Ca-Signature-Headers", "x-ca-key,x-ca-nonce");
            headers.put("X-Ca-Signed-Content-Type", "multipart/form-data");
            headers.put("Accept", "application/json, text/plain, */*");
    
            String body = HttpUtil.createPost(getArticlesScoreUrl).headerMap(headers, true)
                    .body("url=" + url).execute().body();
            if (ObjectUtil.isNotEmpty(body)){
                ScoreResponse scoreResponse = JSONUtil.toBean(body, ScoreResponse.class);
                if (ObjectUtil.isNotEmpty(scoreResponse)){
                    return scoreResponse.getData();
                }
            }
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • getAllTheArticles:返回总文章数据
    • getArticlesScore : 返回文章的分数

    在这里插入图片描述

    ⛵测试用例:

    @SpringBootTest
    class CsdnScoreApplicationTests {
        @Resource
        private CsdnScoreService scoreService;
    
        @Test
        void articleDetailsScore() {
            List<ArticleDetails> allTheArticles = scoreService.getAllTheArticles("自己的名称", "blog");
            ArticleDetails articleDetails = allTheArticles.get(0);
            Score articlesScore = scoreService.getArticlesScore(articleDetails.getUrl());
            System.out.println("-------文章质量分------");
            System.out.println("文章名称:"+articleDetails.getTitle());
            System.out.println("文章分数:"+articlesScore.getScore());
            System.out.println("文章建议:"+articlesScore.getMessage());
            System.out.println("-------   结束  ------");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    ⛴ 运行效果:

    在这里插入图片描述

    ☘️增加Excel导出

    在这里插入图片描述
    在这里插入图片描述

    不看不知道,一看吓一跳,179篇只有72篇是良好,剩下的都有改进空间,裂开呀.

    在这里插入图片描述

    ✍️结束

    后续代码会发布到gitee上,有兴趣的可以去下载研究地址

  • 相关阅读:
    集合的总结
    django和celery的项目,nginx和uwsgi协议,在通过api端口进行deeplearning任务的训练和排队
    【JavaScript】用类的操作对CSDN社区管理菜单栏优化
    浏览器中环境判断和系统判断-js封装
    一个基于RedisTemplate静态工具类
    c语言练习58:⾃定义类型:结构体
    通过代理模式 + 责任链模式实现对目标执行方法拦截和增强功能
    MySQL驱动扯后腿?Spring Boot用虚拟线程可能比用物理线程还差
    使用FRP进行内网穿透的最佳实践
    编程之美4 Nim游戏
  • 原文地址:https://blog.csdn.net/qq_45502336/article/details/132941467