文章目录
- 步骤
- 打开谷歌浏览器
- 输入网址
- 按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: 在满足请求条件(如用户名、业务类型等)的情况下,总的记录数量。
- list: 这是一个数组,包含请求的业务列表。由于在请求中指定了
综上,这个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个元素,跟我的博文数量相符: