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

文章目录

  • 步骤
    • 打开谷歌浏览器
    • 输入网址
    • 按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个元素,跟我的博文数量相符:

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

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

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

相关文章

「已解决」iframe 本地生效 但是在测试环境不生效问题

背景 我有一个表格中一列是个详情&#xff0c;这个详情可被点击&#xff0c;点击后弹出抽屉&#xff0c;抽屉里是后端传给我详情字段的值对应的 url 的 iframe 展示。 问题是&#xff0c;在本地 localhost 下运行&#xff0c;ifame 运行正常&#xff0c;但是部署到测试环境就看…

到江西赣州ibm维修服务器之旅-联想X3850 x6黄灯故障

2023年08月15日&#xff0c;一位江西赣州工厂客户通过朋友介绍与冠峰售前工程师取得联系&#xff0c;双方对产品故障前后原因沟通的大致情况如下&#xff1a; 服务器型号&#xff1a;Lenovo system x3850 x6 为用户公司erp仓库服务器 服务器故障&#xff1a;正常使用过程中业…

第三章 图论 No.12欧拉回路与欧拉路径

文章目录 定义欧拉路径的性质&#xff1a;1123. 铲雪车边编号输出欧拉路径&#xff1a;1184. 欧拉回路点编号字典序最小输出欧拉路径&#xff1a;1124. 骑马修栅栏并查集判断有向图是否存在欧拉路径&#xff1a;1185. 单词游戏 定义 小学一笔画问题&#xff0c;每条边只经过一次…

Neo4j的使用场景_以及Windows版安装_欺诈检测_推荐_知识图谱---Neo4j图数据库工作笔记0003

可以看到使用场景,比如欺诈检测, 要建立图谱,才能进行,欺诈人员检测 可以看到图谱的各种应用场景 然后推荐引擎也需要,可以看到 在金融,旅行,求职招聘,保健,服务,媒体娱乐,都可以进行推荐 然后还有知识图谱 身份访问管理,这里,可以进行安全管理,可以挖掘出潜在关系,分析, 某…

Chapter 2 Crystal Dynamics 2.1 晶格振动

2.1 Lattice Vibration 晶格振动 Born-Oppenheimer Approximation Electrons’ movement: Electron theory free electron theoryenergy band theory Atoms’ movement crystal dynamicslattice vibration 当研究电子运动时&#xff0c;忽略原子运动&#xff1b;当研究原子…

JavaScript如何执行语句

目录 语法/词法分析 预编译 解释执行 预编译什么时候发生 js运行三步曲 预编译前奏 预编译步骤 巩固基础练习 语法/词法分析 按语句块的粒度解析成抽象语法树 ,分析该js脚本代码块的语法是否正确&#xff0c;如果出现不正确&#xff0c;则向外抛出一个语法错误&#x…

NSI45030AT1G LED驱动器方案为汽车外部及内部照明恒流稳流器(CCR)方案

关于线性恒流调节器&#xff08;CCR&#xff09;&#xff1a;是一种用于控制电流的稳定输出。它通常由一个功率晶体管和一个参考电流源组成。CCR的工作原理是通过不断调节功率晶体管的导通时间来维持输出电流的恒定。当输出电流超过设定值时&#xff0c;CCR会减少功率晶体管的导…

探索未来:元宇宙与Web3的无限可能

随着科技的奇迹般发展&#xff0c;互联网已经成为了我们生活的不可分割的一部分。然而&#xff0c;尽管它的便利性和普及性带来了巨大的影响&#xff0c;但我们仍然面临着传统互联网体验的诸多限制。 购物需要不断在实体店与电商平台间切换&#xff0c;教育依然受制于时间与地…

数据库信息速递 -- MariaDB 裁员后,前景不确定 (翻译)

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请加 liuaustin3微信号 &#xff0c;在新加的朋友会分到3群&#xff…

【教程】零成本将小米净化器改造为无叶风扇

某宝某多上&#xff0c;就这么点破塑料&#xff0c;就要买79&#xff1f;&#xff01;&#xff01; 我这枚韭菜可不上当。咱自己做一个&#xff01; 真香~

UNIX网络编程——TCP协议API 基础demo服务器代码

目录 一.TCP客户端API 1.创建套接字 2.connect连接服务器​编辑 3.send发送信息 4.recv接受信息 5.close 二.TCP服务器API 1.socket创建tcp套接字(监听套接字) 2.bind给服务器套接字绑定port,ip地址信息 3.listen监听并创建连接队列 4.accept提取客户端的连接 5.send,r…

Linux设备树详解

Linux 设备树详解 Linux 操作系统早期是针对个人电脑设备而开发的操作系统&#xff0c;而个人电脑处理器产商较为单一&#xff08;例如只有 Intel&#xff0c;AMD&#xff09;同时个人电脑产商均使用 Intel 或 AMD 制造的处理器&#xff0c;业界形成了统一的总线/硬件接口标准…

SQLSERVER 查询语句加with (NOLOCK) 报ORDER BY 报错 除非另外还指定了 TOP、OFFSET 或 FOR XML

最近有一个项目在客户使用时发现死锁问题&#xff0c;用的数据库是SQLSERVER &#xff0c;死锁的原因是有的客户经常去点报表&#xff0c;报表查询时间又慢&#xff0c;然后又有人在做单导致了死锁&#xff0c;然后主管要我们用SQLSERVER查询时要加with (NOLOCK),但是我在加完 …

Excel设置某列或者某行不某行不可以编辑,只读属性

设置单元格只读的三种方式: 1、通过单元格只读按钮&#xff0c;设置为只为 设置行或者列的只读属性&#xff0c;可以设置整行或者整列只读 2、设置单元格编辑控件为标签控件(标签控件不可编辑) 3、通过锁定行&#xff0c;锁定行的修改。锁定的行与只读行的区别在于锁定的行不…

【已解决】mac端 sourceTree 解决remote: HTTP Basic: Access denied报错

又是在一次使用sourcetree拉取或者提交代码时候&#xff0c;遇到了sourcetree报错&#xff1b; 排查了一会&#xff0c;比如查看了SSH keys是否有问题、是否与sourcetree账户状态有问题等等&#xff0c;最终才发现并解决问题 原因&#xff1a; 因为之前公司要求企业gitlab中…

智安网络|网络安全:危机下的创新与合作

随着信息技术的迅猛发展和互联网的普及&#xff0c;我们进入了一个高度网络化的社会。网络在提供便利和连接的同时&#xff0c;也带来了许多安全隐患和挑战。 一、网络安全的危险 **1.数据泄露和隐私侵犯&#xff1a;**网络上的个人和机构数据存在遭受泄露和盗取的风险&#…

什么是Node js?什么是React?有什么区别

JavaScript是当今最流行的编程语言之一&#xff0c;它用于开发多种技术&#xff0c;两种这样的技术是Node.js和React。许多学生很难理解Nodejs和React之间的区别。 React和Nodejs之间的主要区别在于它们的使用位置。Nodejs 用于开发应用程序的服务器端&#xff0c;而Reactjs用于…

docker 学习--03 环境安装(本人使用的win10 Linux也是在win10下模拟)

docker 学习–03 环境安装&#xff08;本人使用的win10 Linux也是在win10下模拟&#xff09; 文章目录 docker 学习--03 环境安装&#xff08;本人使用的win10 Linux也是在win10下模拟&#xff09;[TOC](文章目录) 1. windows10 安装docker1.1 访问官网 点击下载1.2.点击下载的…

HTTP和HTTPS协议

目录 一、HTTP和HTTPS区别&#x1f33b; 二、有了https还有使用http场景吗&#x1f34a; 三、https协议的工作原理&#x1f4a5; 四、https协议的优点和缺点&#x1f35e; 一、HTTP和HTTPS区别&#x1f33b; HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTT…

Freemarker+thymeleaf应用实现打印银行小票

背景&#xff1a;最近项目里有个需求&#xff0c;需要动态配置一个模板&#xff0c;来打印各种不同银行或者其他行业的小票&#xff0c;下面小小记录一下实现过程。 关键词&#xff1a;Springboot, thymeleaf, Freemarker,html2image 一&#xff0c;引入依赖 <dependency…