3. 爬取自己CSDN博客列表(分页查询)(网站反爬虫策略,需要在代码中添加合适的请求头User-Agent,否则response返回空)

news2024/12/25 1:46:27

文章目录

  • 步骤
    • 打开谷歌浏览器
    • 输入网址
    • 按F12进入调试界面
    • 点击网络,清除历史消息
    • 按F5刷新页面
    • 找到接口(community/home-api/v1/get-business-list)
      • 接口解读
    • 撰写代码获取博客列表
      • 先明确返回信息格式
        • json字段解读
      • Apipost测试接口
      • 编写python代码(注意有反爬虫策略,需要设置请求头)(成功)

步骤

打开谷歌浏览器

输入网址

https://dontla.blog.csdn.net/?type=blog

按F12进入调试界面

点击网络,清除历史消息

在这里插入图片描述

按F5刷新页面

找到接口(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=Dontla

在这里插入图片描述

接口解读

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

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

这是一个HTTP GET请求的接口,用于获取CSDN博客网站上的业务列表信息。具体来说,它是用于获取某个用户的博客文章列表。让我们逐个分析URL中的参数:

  • page=1:这个参数表示请求的页面编号,设为1意味着请求第一页的数据。

  • size=20:这个参数表示每页显示的记录数。这里,每页显示20条记录。

  • businessType=blog:这个参数指定了业务类型,此处为"blog",所以它应该是用来获取博客文章的。

  • orderby=:这个参数应该是用来指定排序方式的,但在这个请求中并没有具体值,可能默认为某种排序方式,如按发布时间降序等。

  • noMore=false:这个参数可能是用来判断是否还有更多的记录可以获取。如果设置为false,表示可能还有更多的记录。

  • year= & month=:这两个参数可能是用来筛选特定年份和月份的博客文章,但在这个请求中并没有具体值,因此可能会返回所有时间段的文章。

  • username=Dontla:这个参数指定了用户名,意味着这个请求可能用来获取名为"Dontla"的用户的博客文章列表。

撰写代码获取博客列表

先明确返回信息格式

我们将https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=1&businessType=blog&orderby=&noMore=false&year=&month=&username=Dontla拷贝到浏览器url栏打开:

在这里插入图片描述

全选拷贝,将文字粘贴到编辑器并格式化:

在这里插入图片描述

{“code”:200,“message”:“success”,“traceId”:“47d3f9ad-bfc0-4604-b386-48b0e0b40c8d”,“data”:{“list”:[{“articleId”:132295415,“title”:“shellcheck警告:Declare and assign separately to avoid masking return values.shellcheck(SC2155)”,“description”:“ShellCheck的SC2155警告是关于在shell脚本中正确处理命令返回值的一个重要提示。通过将声明和赋值分开进行,我们可以确保命令的返回值不会被误导,并且在命令执行失败时,脚本能够正确地捕获并处理错误。”,“url”:“https://dontla.blog.csdn.net/article/details/132295415”,“type”:1,“top”:false,“forcePlan”:false,“viewCount”:8,“commentCount”:0,“editUrl”:“https://editor.csdn.net/md?articleId=132295415”,“postTime”:“2023-08-15 13:16:23”,“diggCount”:0,“formatTime”:“8 小时前”,“picList”:[“https://img-blog.csdnimg.cn/a0eb894421994488a27fd20a767d00de.png”],“collectCount”:0}],“total”:2557}}

在这里插入图片描述

{
    "code": 200,
    "message": "success",
    "traceId": "47d3f9ad-bfc0-4604-b386-48b0e0b40c8d",
    "data": {
        "list": [
            {
                "articleId": 132295415,
                "title": "shellcheck警告:Declare and assign separately to avoid masking return values.shellcheck(SC2155)",
                "description": "ShellCheck的SC2155警告是关于在shell脚本中正确处理命令返回值的一个重要提示。通过将声明和赋值分开进行,我们可以确保命令的返回值不会被误导,并且在命令执行失败时,脚本能够正确地捕获并处理错误。",
                "url": "https://dontla.blog.csdn.net/article/details/132295415",
                "type": 1,
                "top": false,
                "forcePlan": false,
                "viewCount": 8,
                "commentCount": 0,
                "editUrl": "https://editor.csdn.net/md?articleId=132295415",
                "postTime": "2023-08-15 13:16:23",
                "diggCount": 0,
                "formatTime": "8 小时前",
                "picList": [
                    "https://img-blog.csdnimg.cn/a0eb894421994488a27fd20a767d00de.png"
                ],
                "collectCount": 0
            }
        ],
        "total": 2557
    }
}

目前已知的是:原创对应type值为1,转载对应为2。

json字段解读

这是一个JSON格式的HTTP响应,用于传输具体的数据信息。以下是对每个字段的解读:

  • code: 这是HTTP响应状态码,200通常表示请求成功。

  • message: 这是响应的描述信息,"success"表示请求处理成功。

  • traceId: 这可能是此次请求的唯一标识符,用于追踪和调试。

  • data: 这是实际返回的数据对象,包含以下字段:

    • list: 这是一个数组,包含请求的业务列表。由于在请求中指定了size=1,所以此处只有一个对象。该对象包含以下属性:
      • articleId: 文章的唯一标识符。
      • title: 文章的标题。
      • description: 文章的描述。
      • url: 文章的网址链接。
      • type: 文章的类型,具体代表什么需要参考API文档或者询问API提供者。
      • top: 是否置顶,false表示未置顶。
      • forcePlan: 不清楚这个字段的具体含义,可能需要参考API文档或者询问API提供者。
      • viewCount: 文章的浏览次数。
      • commentCount: 文章的评论数量。
      • editUrl: 编辑文章的链接。
      • postTime: 文章的发布时间。
      • diggCount: 文章的点赞数。
      • formatTime: 格式化后的发布时间。
      • picList: 文章中的图片列表。
      • collectCount: 文章的收藏数量。
    • total: 在满足请求条件(如用户名、业务类型等)的情况下,总的记录数量。

综上,这个JSON响应表示成功获取了用户"Dontla"的博客文章列表(因为设置了size=1,所以只返回了一个结果)。该用户共有2557篇博客文章,最新的一篇文章的标题、描述、链接、类型、浏览次数、评论数量、编辑链接、发布时间、点赞数、图片列表和收藏数量都在响应中给出。

点赞为什么是digg?
digg"这个词在网络社区中经常被用来表示“点赞”或者“投票”。这个词的来源是一家名为Digg的美国新闻网站,用户可以对他们喜欢的文章进行“digg”,也就是投票,最受欢迎的文章会被推送到首页。因此,"digg"在很多网站和应用中都被用作代表用户点赞或者投票的动作。

Apipost测试接口

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

在这里插入图片描述

(Apipost接口元数据)

{
    "parent_id": "0",
    "project_id": "-1",
    "target_id": "fdb84824-e558-48f1-9456-219ea5e9950e",
    "target_type": "api",
    "name": "新建接口",
    "sort": 1,
    "version": 0,
    "mark": "developing",
    "create_dtime": 1692028800,
    "update_dtime": 1692109242,
    "update_day": 1692028800000,
    "status": 1,
    "modifier_id": "-1",
    "method": "GET",
    "mock": "{}",
    "mock_url": "/community/home-api/v1/get-business-list",
    "url": "https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=20&businessType=blog&orderby=&noMore=false&year=&month=&username=Dontla",
    "request": {
        "url": "https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=20&businessType=blog&orderby=&noMore=false&year=&month=&username=Dontla",
        "description": "",
        "auth": {
            "type": "noauth",
            "kv": {
                "key": "",
                "value": ""
            },
            "bearer": {
                "key": ""
            },
            "basic": {
                "username": "",
                "password": ""
            },
            "digest": {
                "username": "",
                "password": "",
                "realm": "",
                "nonce": "",
                "algorithm": "",
                "qop": "",
                "nc": "",
                "cnonce": "",
                "opaque": ""
            },
            "hawk": {
                "authId": "",
                "authKey": "",
                "algorithm": "",
                "user": "",
                "nonce": "",
                "extraData": "",
                "app": "",
                "delegation": "",
                "timestamp": "",
                "includePayloadHash": -1
            },
            "awsv4": {
                "accessKey": "",
                "secretKey": "",
                "region": "",
                "service": "",
                "sessionToken": "",
                "addAuthDataToQuery": -1
            },
            "ntlm": {
                "username": "",
                "password": "",
                "domain": "",
                "workstation": "",
                "disableRetryRequest": 1
            },
            "edgegrid": {
                "accessToken": "",
                "clientToken": "",
                "clientSecret": "",
                "nonce": "",
                "timestamp": "",
                "baseURi": "",
                "headersToSign": ""
            },
            "oauth1": {
                "consumerKey": "",
                "consumerSecret": "",
                "signatureMethod": "",
                "addEmptyParamsToSign": -1,
                "includeBodyHash": -1,
                "addParamsToHeader": -1,
                "realm": "",
                "version": "1.0",
                "nonce": "",
                "timestamp": "",
                "verifier": "",
                "callback": "",
                "tokenSecret": "",
                "token": ""
            }
        },
        "body": {
            "mode": "none",
            "parameter": [],
            "raw": "",
            "raw_para": [],
            "raw_schema": {
                "type": "object"
            }
        },
        "event": {
            "pre_script": "",
            "test": ""
        },
        "header": {
            "parameter": []
        },
        "query": {
            "parameter": [
                {
                    "description": "",
                    "is_checked": 1,
                    "key": "page",
                    "type": "Text",
                    "not_null": 1,
                    "field_type": "String",
                    "value": "1"
                },
                {
                    "description": "",
                    "is_checked": 1,
                    "key": "size",
                    "type": "Text",
                    "not_null": 1,
                    "field_type": "String",
                    "value": "20"
                },
                {
                    "description": "",
                    "is_checked": 1,
                    "key": "businessType",
                    "type": "Text",
                    "not_null": 1,
                    "field_type": "String",
                    "value": "blog"
                },
                {
                    "description": "",
                    "is_checked": 1,
                    "key": "orderby",
                    "type": "Text",
                    "not_null": 1,
                    "field_type": "String",
                    "value": ""
                },
                {
                    "description": "",
                    "is_checked": 1,
                    "key": "noMore",
                    "type": "Text",
                    "not_null": 1,
                    "field_type": "String",
                    "value": "false"
                },
                {
                    "description": "",
                    "is_checked": 1,
                    "key": "year",
                    "type": "Text",
                    "not_null": 1,
                    "field_type": "String",
                    "value": ""
                },
                {
                    "description": "",
                    "is_checked": 1,
                    "key": "month",
                    "type": "Text",
                    "not_null": 1,
                    "field_type": "String",
                    "value": ""
                },
                {
                    "description": "",
                    "is_checked": 1,
                    "key": "username",
                    "type": "Text",
                    "not_null": 1,
                    "field_type": "String",
                    "value": "Dontla"
                }
            ]
        },
        "cookie": {
            "parameter": []
        },
        "resful": {
            "parameter": []
        }
    },
    "response": {
        "success": {
            "raw": "",
            "parameter": [],
            "expect": {
                "name": "成功",
                "isDefault": 1,
                "code": 200,
                "contentType": "json",
                "verifyType": "schema",
                "mock": "",
                "schema": {}
            }
        },
        "error": {
            "raw": "",
            "parameter": [],
            "expect": {
                "name": "失败",
                "isDefault": -1,
                "code": 404,
                "contentType": "json",
                "verifyType": "schema",
                "mock": "",
                "schema": {}
            }
        }
    },
    "is_first_match": 1,
    "ai_expect": {
        "list": [],
        "none_math_expect_id": "error"
    },
    "enable_ai_expect": -1,
    "enable_server_mock": -1,
    "is_example": -1,
    "is_locked": -1,
    "is_check_result": 1,
    "check_result_expectId": "",
    "is_changed": -1,
    "is_saved": -1
}

编写python代码(注意有反爬虫策略,需要设置请求头)(成功)

网站反爬虫策略:一些网站会通过识别请求头(User-Agent)来判断是否为机器人行为。解决方法是添加合适的请求头:

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36"
}
response = requests.get(url, headers=headers)

完整代码:

import requests
import json

# 定义变量存储所有文章信息
articles = []

# 设置初始分页
page = 1

# 设置每页查询数量
page_size = 50

while True:
    # 构建请求url
    url = f"https://blog.csdn.net/community/home-api/v1/get-business-list?page={page}&size={page_size}&businessType=blog&orderby=&noMore=false&year=&month=&username=Dontla"

    # 发送GET请求
    # response = requests.get(url)
    # 防止反爬虫策略
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36"
    }
    response = requests.get(url, headers=headers)

    # 如果请求成功
    if response.status_code == 200:
        
        # print(f'response.content: {response.content}')
        # print(f'response.text: {response.text}')
        
        
        # 检查响应是否为空
        if response.text:
            # 解析JSON响应
            try:
                data = response.json()
            except json.JSONDecodeError:
                print(f"Error parsing JSON: {response.text}")
                break

            # 遍历每个文章
            for article in data['data']['list']:
                print(f"page: {page}, {article['url']}")
                # 获取并保存需要的信息
                articles.append({
                    'title': article['title'],
                    'url': article['url'],
                    'type': article['type'],
                    'postTime': article['postTime']
                })

            # 判断是否还有更多文章,如果没有则结束循环
            if len(data['data']['list']) < page_size:
                break

            # 增加分页数以获取下一页的文章
            page += 1
        else:
            print("Response is empty")
            break
    else:
        print(f"Error: {response.status_code}")
        break

# 将结果保存为json文件
with open('articles.json', 'w') as f:
    json.dump(articles, f, ensure_ascii = False, indent = 4)

注意,最大单次查询上限为100,我一开始把每页查询数量page_size设置成200,发现不行,后来设置成100以下就ok了,为了保证速度,我就设置成100:

这是代码运行结果:

在这里插入图片描述

这是生成的j’son文件:

在这里插入图片描述

总共2557个元素,跟我的博文数量相符:

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

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

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

相关文章

每天一道leetcode:646. 最长数对链(动态规划中等)

今日份题目&#xff1a; 给你一个由 n 个数对组成的数对数组 pairs &#xff0c;其中 pairs[i] [lefti, righti] 且 lefti < righti 。 现在&#xff0c;我们定义一种 跟随 关系&#xff0c;当且仅当 b < c 时&#xff0c;数对 p2 [c, d] 才可以跟在 p1 [a, b] 后面…

JMeter 特殊组件-逻辑控制器与BeanShell PreProcessor 使用示例

文章目录 前言JMeter 特殊组件-逻辑控制器与BeanShell PreProcessor 使用示例1. 逻辑控制器使用1.1. While Controller 使用示例1.2. 如果&#xff08;If&#xff09;控制器 使用示例 2. BeanShell PreProcessor 使用示例 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞…

视频云存储平台EasyCVR视频汇聚接入AI算法接口,如何在检测中对视频流画框?

视频集中存储EasyCVR安防监控视频汇聚平台基于云边端智能协同架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台可支持多协议接入&#xff0c;包括市场主流标准协议与厂家私有协议及SDK&#xff0c;如&#xff1a;国标GB28181、RTMP、RTSP/Onvif、海康Ehome…

Matlab中图例的位置(图例放在图的上方、下方、左方、右方、图外面)等

一、图例默认位置 默认的位置在NorthEast r 10; a 0; b 0; t0:0.1:2.1*pi; xar*cos(t); ybr*sin(t); A1plot(x,y,r,linewidth,4);%圆 hold on axis equal A2plot([0 0],[1 10],b,linewidth,4);%直线 legend([A1,A2],圆形,line)二、通过Location对legend的位置进行改变 变…

国标GB28181视频平台EasyGBS国标视频平台接入大量通道,创建角色未响应的问题解决方案

国标GB28181协议视频平台EasyGBS是基于国标GB28181协议的视频云服务平台&#xff0c;支持多路设备同时接入&#xff0c;并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。平台可提供视频监控直播、云端录像、云存储、检索回放、智能告警、语音对讲、平台级…

生成IOS app专用密码教程

转载&#xff1a;生成IOS app专用密码教程 APP专用密码app-specific password是专门用于上传ipa文件的一种密码&#xff0c;是一种苹果的安全机制&#xff01; 现在苹果开发者账号开启了双重认证&#xff0c;提交ipa文件时候都需要这个密码&#xff01; 一.注册AppID账号 1…

Linux 路由三大件

对于 Linux 网络&#xff0c;好奇心强的同学一定思考过两个问题&#xff1a; 当我们发出一个包的时候&#xff0c;Linux 是如何决策该从哪个网卡&#xff08;假设有多个网卡&#xff09;、哪个下一跳发出这个包&#xff0c;用什么 IP 作为 source......当 Linux 收到一个包时&a…

云服务 Ubuntu 20.04 版本 使用 Nginx 部署静态网页

所需操作&#xff1a; 1.安装Nginx 2.修改配置文件 3.测试、重启 Nginx 4.内部修改防火墙 5.配置解析 6.测试是否部署成功 1.安装Nginx // 未使用 root 账号 apt-get update // 更新apt-get install nginx // 安装 nginx 1.1.测试是否安装没问题 在网页上输入云服务的公网…

链表之第一回

欢迎来到我的&#xff1a;世界 收录专栏&#xff1a;链表 希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 目录 前言第一题&#xff1a;删除链表的倒数第n个节点第二题&#xff1a;链表的中间结点第三题&#xff1a;合并两个排序…

Apache Dubbo 云原生可观测性的探索与实践

作者&#xff1a;宋小生 - 平安壹钱包中间件资深工程师 Dubbo3 可观测能力速览 Apache Dubbo3 在云原生可观测性方面完成重磅升级&#xff0c;使用 Dubbo3 最新版本&#xff0c;你只需要引入 dubbo-spring-boot-observability-starter 依赖&#xff0c;微服务集群即原生具备以…

Gradio部署应用到服务器不能正常访问

用Gradio部署一个基于ChatGLM-6B的应用&#xff0c;发布到团队的服务器上&#xff08;局域网&#xff0c;公网不能访问&#xff09;&#xff0c;我将gradio应用发布到服务器的9001端口 import gradio as gr with gr.Blocks() as demo:......demo.queue().launch(server_port90…

视频集中存储安防监控平台EasyCVR优化AI硬件接入时的通道显示异常问题

安防视频监控平台视频集中存储EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 安防监控视频云存储平台EasyCVR既具…

NPCon2023 AI模型技术与应用峰会:参后感

8月12日&#xff0c;参加了在北京皇家格兰云天大酒店召开的“全链路搭建人工智能研发基础”会议。此次会议汇集了众多人工智能领域的顶尖技术专家&#xff0c;他们就人工智能基础设施、计算能力资源以及模型训练等核心议题展开了深入的研讨。 1.主题以及收获 主题1.由千芯科技…

网络编程555

上传代码 #include <stdio.h>//客户端 #include <string.h> #include <stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<head.h> #define PORT 69 #define IP "192.168.124.57"…

Arduino之TFT_eSPI驱动彩色LCD屏

一、TFT_eSPI库简介 1.1 安装TFT_eSPI库 在User_Setup.h中进行个人屏幕参数的配置&#xff1a; User_Setup.hTFT驱动板备注TFT_MISO无 TFT_MOSISDA TFT_SCLKCLK TFT_CSCS液晶屏片选信号&#xff0c;低电平使能TFT_DCRS液晶屏寄存器/数据选择信号TFT_RSTRST液晶屏复位信号TF…

通达信一目均衡表指标选股公式,又称云图指标

一目均衡表&#xff08;Ichimoku Kinko Hyo&#xff0c;又称一目均衡图、云图指标&#xff09;是由日本记者兼股市专家一目山人发明的&#xff0c;被广泛用于股票、外汇、期货等金融市场的趋势分析和支撑阻力位的判断。一目均衡表提供了一种综合性的视角&#xff0c;结合了多个…

LC-相交链表(解法1)

LC-相交链表&#xff08;解法1&#xff09; 链接&#xff1a;https://leetcode.cn/problems/intersection-of-two-linked-lists/description/ 描述&#xff1a;给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在…

Linux交叉编译opencv并移植ARM端

Linux交叉编译opencv并移植ARM端 - 知乎 一、安装交叉编译器 目标平台为arm7l&#xff0c;此为32位ARM架构&#xff0c;要安装合适的编译器 sudo apt install arm-linux-gnueabihf-gcc sudo apt install arm-linux-gnueabihf-g注意&#xff1a;64位ARM架构的编译器与32位ARM架…

微服务与Nacos概述-6

RBAC 模型 RBAC 基于角色的访问控制是实施面向企业安全策略的一种有效的访问控制方式。 基本思想是&#xff0c;对系统操作的各种权限不是直接授予具体的用户&#xff0c;而是在用户集合与权限集合之间建立一个角色集合。每一种角色对应一组相应的权限。一旦用户被分配了适当…

使用 BERT 进行文本分类 (02/3)

​ 一、说明 在使用BERT&#xff08;1&#xff09;进行文本分类中&#xff0c;我向您展示了一个BERT如何标记文本的示例。在下面的文章中&#xff0c;让我们更深入地研究是否可以使用 BERT 来预测文本是使用 PyTorch 传达积极还是消极的情绪。首先&#xff0c;我们需要准备数据…