【python】我用python写了一个可以批量查询文章质量分的小项目(纯python、flask+html、打包成exe文件)

web 效果预览:
在这里插入图片描述

文章目录

  • 一、API 分析
    • 1.1 质量分查询
    • 1.2 文章url获取
  • 二、代码实现
    • 2.1 Python
      • 2.11 分步实现
      • 2.12 一步完成
      • 2.13 完整代码
    • 2.2 python + html
      • 2.21 在本地运行
      • 2.22 打打包成exe文件
      • 2.23 部署到服务器

一、API 分析

1.1 质量分查询

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

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

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

经过测试,请求头只需要下面这几个参数即可。
在这里插入图片描述

请求体是:

url:文章地址

测试结果:
在这里插入图片描述


文章质量分查询的问题已经解决了。下面来批量获取文章的URL。

1.2 文章url获取

点击个人主页,开启检查,然后点击主页的文章选项。

在这个选项下即可看到返回的文章列表:
在这里插入图片描述

方法是:GET

请求URL:

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

参数说明:

  • page:请求的页面数
  • size:每页数量
  • username:你的csdn id

测试结果:可以返回每篇文章的地址、阅读量、评论量等数据。
在这里插入图片描述

二、代码实现

2.1 Python

2.11 分步实现

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

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

批量获取文章信息:

效果(获取20篇):

在这里插入图片描述

代码:

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

    def get_articles(self):
        url = f"https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size={self.size}&businessType=blog&orderby=&noMore=false&year=&month=&username={self.username}"
        with urllib.request.urlopen(url) as response:
            data = json.loads(response.read().decode())
        return data['data']['list']

    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"
        headers = {
            "Accept": "...",
            "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",
        }
        data = urllib.parse.urlencode({"url": article_url}).encode()
        req = urllib.request.Request(url, data=data, headers=headers)
        with urllib.request.urlopen(req) as response:
            return json.loads(response.read().decode())['data']['score']

    def get_scores_from_excel(self):
        # Read the Excel file
        df = pd.read_excel(self.filepath)
        # Get the 'URL' column
        urls = df['URL']
        # Get the score for each URL
        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)

2.12 一步完成

前面的代码还是有点臃肿的,可以在获取文章信息后,就查询出质量分,然后再把所有数据写入到excel。

这部分代码你自己实现吧。

2.13 完整代码

import urllib.request
import json
import pandas as pd
from openpyxl import Workbook, load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows


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

    def get_articles(self):
        url = f"https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size={self.size}&businessType=blog&orderby=&noMore=false&year=&month=&username={self.username}"
        with urllib.request.urlopen(url) as response:
            data = json.loads(response.read().decode())
        return data['data']['list']

    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"
        headers = {
            "Accept": "...",
            "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",
        }
        data = urllib.parse.urlencode({"url": article_url}).encode()
        req = urllib.request.Request(url, data=data, headers=headers)
        with urllib.request.urlopen(req) as response:
            return json.loads(response.read().decode())['data']['score']

    def get_scores_from_excel(self):
        # Read the Excel file
        df = pd.read_excel(self.filepath)
        # Get the 'URL' column
        urls = df['URL']
        # Get the score for each URL
        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__':
    # 获取文章信息
    exporter = CSDNArticleExporter(你的csdn id, 要查询的文章数量, 'score.xlsx')  # Replace with your username
    exporter.export_to_excel()
    # 批量获取质量分
    score = ArticleScores('score.xlsx')
    score.write_scores_to_excel()

2.2 python + html

思路:

  1. 用户输入:首先,我们需要获取用户的输入。在这个项目中,用户需要输入他们的CSDN用户名和他们想要获取的文章数量。我们使用HTML的<input>元素来创建输入框,让用户输入这些信息。

  2. 获取文章信息:当用户点击"Submit"按钮时,我们使用jQuery的$.getJSON()函数来发送一个GET请求到CSDN的API。这个API返回一个包含用户文章信息的JSON对象。我们从这个对象中提取出我们需要的信息,包括文章的标题、URL和分数。

  3. 获取文章分数:为了获取每篇文章的分数,我们需要发送一个POST请求到我们自己的服务器。我们的服务器会接收到这个请求,然后发送一个POST请求到CSDN的另一个API来获取文章的分数。这个API返回一个包含文章分数的JSON对象。我们的服务器将这个分数返回给前端。

  4. 显示结果:最后,我们在网页上显示获取到的文章信息。我们创建一个HTML表格,每行显示一篇文章的信息。我们使用jQuery的$.when.apply()函数来确保所有的POST请求都完成后再显示结果。这是因为POST请求是异步的,如果我们不等待所有的请求都完成,我们可能会在某些文章的分数还没有获取到时就显示结果。

2.21 在本地运行

先看效果: 这是兔老大的博客质量分

在这里插入图片描述


创建一个Flask应用,并定义一个路由’/',它对GET和POST请求做出响应。对于GET请求,它返回一个HTML表单。对于POST请求,它获取表单中的username和size,然后获取相应的文章,并将它们显示在屏幕上。

app.py:请求头的参数依旧是自己去获取

from flask import Flask, request, jsonify
from flask_cors import CORS
import urllib.request
import json

app = Flask(__name__)
CORS(app)

@app.route('/get_score', methods=['POST'])
def get_score():
    article_url = request.json['url']
    url = "https://bizapi.csdn.net/trends/api/v1/get-article-score"
    headers = {
        "Accept": "application/json, text/plain, */*",
        "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",
    }
    data = urllib.parse.urlencode({"url": article_url}).encode()
    req = urllib.request.Request(url, data=data, headers=headers)
    with urllib.request.urlopen(req) as response:
        score = json.loads(response.read().decode())['data']['score']
    return jsonify(score=score)

if __name__ == '__main__':
    app.run(debug=True)

html 可视化:

<!DOCTYPE html>
<html>
<head>
    <title>CSDN Article Info</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        form {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-top: 20px;
        }
        input, button {
            width: 100%;
            padding: 10px;
            margin-top: 5px;
            font-size: 18px;
        }
        button {
            background-color: #4CAF50;
            color: white;
            border: none;
            cursor: pointer;
        }
        button:hover {
            background-color: #45a049;
        }
        table {
            width: 100%;
            border-collapse: collapse;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        tr:nth-child(even) {
            background-color: #f2f2f2;
        }
        th {
            background-color: #4CAF50;
            color: white;
        }
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
        $(document).ready(function(){
            $("#submit").click(function(event){
                event.preventDefault();
                var username = $("#username").val();
                var size = $("#size").val();
                var url = "https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=" + size + "&businessType=blog&orderby=&noMore=false&year=&month=&username=" + username;
                $.getJSON(url, function(data) {
                    var articles = data.data.list;
                    var promises = [];
                    for (var i = 0; i < articles.length; i++) {
                        (function(article) {
                            var promise = $.ajax({
                                url: "http://localhost:5000/get_score",
                                type: "POST",
                                data: JSON.stringify({url: article.url}),
                                contentType: "application/json; charset=utf-8",
                                dataType: "json"
                            }).then(function(data){
                                return "<tr><td>" + article.title + "</td>" +
                                       "<td><a href='" + article.url + "'>Link</a></td>" +
                                       "<td>" + data.score + "</td></tr>";
                            });
                            promises.push(promise);
                        })(articles[i]);
                    }
                    $.when.apply($, promises).then(function() {
                        var html = "<table><tr><th>Title</th><th>URL</th><th>Score</th></tr>";
                        for (var i = 0; i < arguments.length; i++) {
                            html += arguments[i];
                        }
                        html += "</table>";
                        $("#result").html(html);
                    });
                });
            });
        });
    </script>
</head>
<body>
    <form>
        <label for="username">CSDN ID:</label>
        <input type="text" id="username" name="username">
        <label for="size">Article number to query:</label>
        <input type="text" id="size" name="size">
        <button id="submit">Submit</button>
    </form>
    <div id="result"></div>
</body>
</html>


使用方法:

先运行app.py,再打开html即可。
在这里插入图片描述

也可以在命令行运行,先进入app.py所在的目录,地址栏输入cmd(powershell这些也可以),回车即可,我这个代码用的是conda虚拟环境,所以先进入虚拟环境:

conda activate first_env

然后运行app.py即可:

python app.py

在这里插入图片描述

最后打开html进行查询。

2.22 打打包成exe文件

我用的是conda的虚拟环境。

进入虚拟环境:

conda activate first_env

先在你目前的虚拟环境安装: pyinstaller

(只要进入这个虚拟环境,使用conda、pip都可以)

继续在命令行打包:

pyinstaller --onefile --paths=E:\anaconda3\envs\first_env\Lib\site-packages app.py

注意:

  • 前面的路径是我的python程序运行的虚拟环境(first_env),我在里面已经安装了相关的模块,比如flask;
  • 这个命令是在app.py所在目录下运行,并且是进入虚拟环境了。

打包完成后:在dist目录下即可找到这个exe文件。

打开如果显示缺失什么模块,那你就需要自己解决一下。

如果可以运行,那么就可以把这个exe移动到任意位置运行,比如我把他复制到桌面,然后双击打开即可运行。

然后浏览器打开Html就可以查询了。
在这里插入图片描述

2.23 部署到服务器

你也可以把它部署到服务器,以后直接用url即可打开查询页面。

感兴趣的自己部署吧。
在这里插入图片描述



~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp app端 echarts 设置tooltip的formatter不生效问题以及解决办法

需求一&#xff1a; y轴数据处理不同数据增加不同单位 需求二&#xff1a; 自定义图表悬浮显示的内容 需求一&#xff1a;实现方式 在yAxis里面添加formatter yAxis: [{//y轴显示value的设置axisLabel: {show: true,formatter (value, index) > {var valueif (value > 1…

Jmeter用于接口测试中,关联如何实现

Jmeter用于接口测试时&#xff0c;后一个接口经常需要用到前一次接口返回的结果&#xff0c;应该如何获取前一次请求的结果值&#xff0c;应用于后一个接口呢&#xff0c;拿一个登录的例子来说明如何获取。 1、打开jmeter, 使用的3.3的版本&#xff0c;新建一个测试计划&#x…

抄写Linux源码(Day6:读闪客文章第一回 “最开始的两行代码”)

按照 Day1 完成了 Linux0.11 的运行之后&#xff0c;可以在 ~/oslab/linux-0.11 找到 linux0.11 的源码 根据闪客的文章第一回&#xff1a;https://mp.weixin.qq.com/s/LIsqRX51W7d_yw-HN-s2DA Linux0.11 的启动代码程序入点在 bootsect.s 里&#xff0c;总共 512 个字节 这…

烘焙小程序蛋糕店烘焙店源码点心店小程序源码

本系统开发使用JAVA技术栈开发 使用uniapp技术栈 支持微信小程序 &#xff0c;对接打印机&#xff0c;对接第三方同城跑腿平台 用户端使用&#xff1a;uniapp 管理端使用&#xff1a;vueelementui 后台服务使用&#xff1a;springbootjpa

Web课堂笔记

Web课堂笔记 文章目录 Web课堂笔记第一周html部分CSS部分php部分 第二周B/S工作原理http协议**块标记** 第三周标准盒状模型标签优先级**伪类选择器**伪元素派生选择器 第四周Flex布局多媒体查询下拉菜单作业 第五周创建一个NodeLocalStorage 和 SessionStorge 异同JQuery作业 …

filebeat kibana elasticsearch 日志监控

解压三个压缩包 一、filebeat的安装部署 1、打开filebeat的配置文件 2、Filebeat inputs 处打开日志输入开关&#xff0c;设置要监控的路径 3、Outputs 输出中设置Elasticsearch output的输出地址 4、配置kibana 的地址 5、执行 ./filebeat setup -e 二、Elasticsearch 安装…

github Recv failure: Connection reset by peer

Recv failure: Connection reset by peer 背景处理ping一下github网页访问一下github项目git配置git ssh配置再次尝试拉取 疑惑点待研究参考 背景 晚上敲着代码准备提交&#xff0c;执行git pull&#xff0c;报错Recv failure: Connection reset by peer。看着这报错我陷入了沉…

SpringBoot百货超市商城系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBoot框架开发的百货超市系统。首先&#xff0c;这是一个很适合SpringBoot初学者学习的项目&#xff0c;代…

微服务架构的模式介绍

1.微服务架构模式方案 用Scale Cube方法设计应用架构&#xff0c;将应用服务按功能拆分成一组相互协作的服务。每个服务负责一组特定、相关的功能。每个服务可以有自己独立的数据库&#xff0c;从而保证与其他服务解耦。 1.1 聚合器微服务设计模式 聚合器调用多个服务实现应用程…

k8s安装Jenkins

目录 ​编辑 一、环境准备 1.1 环境说明 二、安装nfs 2.1 安装NFS 2.2 创建NFS共享文件夹 2.3 配置共享文件夹 2.4 使配置生效 2.5 查看所有共享目录 2.6 启动nfs 2.7 其他节点安装nfs-utils 三、创建PVC卷 3.1 创建namespace 3.2 创建nfs 客户端sa授权 3.3 创建…

SQL Server数据库 -- 索引与视图

文章目录 一、索引 聚集索引非聚集索引二、视图三、自定义函数 标量函数表值函数四、游标五、总结 前言 在学习完创建库表、查询等知识点后&#xff0c;为了更加方便优化数据库的存储和内容&#xff0c;我们需要学习一系列的方法例如索引与视图等等&#xff0c;从而使我们更加…

SpringBoot项目中使用Lombok插件中Slf4j日志框架

前言&#xff1a;idea需要安装lombok插件&#xff0c;因为该插件中添加了Slf4j注解&#xff0c;可以将Slf4j翻译成 private static final org.slf4j.Logger logger LoggerFactory.getLogger(this.XXX.class); springboot本身就内置了slf4j日志框架&#xff0c;所以不需要单独…

Unity-缓存池

一、.基础缓存池实现 继承的Singleton脚本为 public class Singleton<T> where T : new() {private static T _instance;public static T GetIstance(){if (_instance null)_instance new T();return _instance;} } 1.PoolManager using System.Collections; using S…

中国工商银行长春分行 聚焦融合互促 让机关党建更有活力

党的十八大以来&#xff0c;中国工商银行长春分行党委认真落实中央部署&#xff0c;立足金融工作政治性、人民性的基本原则&#xff0c;深刻把握机关党建的要点、着力破解难点、大力打造亮点&#xff0c;围绕“党建”模式&#xff0c;将党建融入经营管理各个方面&#xff0c;使…

创建邮件服务器(小微企业)

这里写自定义目录标题 目的硬件选型&#xff1a;软件选型&#xff1a;coremail &#xff08;商业版本&#xff09;postfixumail免费开源版本新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适…

docker minio安装

1.介绍 Minio是一款开源的对象存储服务&#xff0c;它可以在任何硬件或云平台上提供高性能、高可用性和高安全性的存储解决方案。Minio最新版是2021年11月发布的RELEASE.2021-11-24T23-19-33Z&#xff0c;它带来了以下几个方面的改进和新特性&#xff1a; - 支持S3 Select AP…

c语言(函数)

目录 何为函数 库函数 自定义函数 二分查找数组下标 链式访问 函数的声明 函数定义 递归 正向打印数字 打印字符个数 使用临时变量 递归(不使用临时变量) n的阶乘 一般形式 递归 斐波那契数 递归 正常做法 何为函数 在计算机科学中&#xff0c;子程序是一个…

Leetcode(一):数组、链表部分经典题目详解(JavaScript版)

数组、链表部分算法题 一、数组1. 二分查找2. 移除数组元素3. 有序数组的平方4. 长度最小的子数组5. 螺旋矩阵 二、链表1. 删除链表元素2. 设计链表3.反转链表4.两两交换链表中的节点5.删除链表倒数第n个节点6.环形链表 提前声明&#xff1a;本博客内容均为笔者为了方便个人理解…

DbVisualizer Pro Crack

DbVisualizer Pro Crack DbVisualizer是适用于开发人员、DBA和分析师的通用数据库工具。它是最终的解决方案&#xff0c;因为相同的工具可以在访问各种数据库的所有主要操作系统上使用。支持的数据库Amazon Redshift、DB2 LUW、Exasol、H2、Informix、JavaDB/Derby、Microsoft …

深度解剖动态内存管理

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 望小伙伴们点赞&#x1f44d;收藏✨加关注哟&#x1f495;&#x1…