网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
近期突发奇想想要做一个短视频账号,发一下历史上的今天这类题材。因为做视频就要有文案,但是这种文案需要权威的资料,所以就上网查了查。发现数据来源还真不少,眼花缭乱,为了权威,选择了百度百科的数据。
传送门:历史上的今天
实操开始,新建 InPrivate选项卡,打开开发者工具,打开网络界面,然后再进行访问。
PS:这里先不做过多降解,关于这一部分内容,我会单独写一篇文章讲解,然后从这里设置一个传送门直接过去,如果没有链接,那就是我还没写。
根据个人习惯的,是先找XHR
,如果数据直接是接口返回,那是最令人开心的事。如果没有,那就只能苦哈哈的从页面请求的Response
里做数据清洗。

非常庆幸在众多百度系产品中,还能找到XHR
,可以直接返回参数。接下来需要做的就是分析请求方式跟负载参数了。


现在已知接口链接如下:
https://baike.baidu.com/cms/home/eventsOnHistory/09.json?_=1725521601879
?
后面只跟了一个请求参数,而且目测是个时间戳转化来字符串格式,这样我们省去了逆向的过程。但是请求头中包含cookie,我们未知模拟请求cookie是否为必须验证项。如果是,那我们就需要花费大量时间去进行逆向。
而09.json
这个文件名称也不确定是否固定,根据作者现在所处时间节点,我们不妨大胆猜测这是个月份。不可以绝对的说是什么,但正确的判断会给我们省下大量的时间。
接下来就是对接口进行模拟请求,很多初学者还在自己拿到url,然后打开编辑器,创建py文件,import requests
,然后手写header等信息。
今天给大家介绍一个方法跟工具,省去自己构造请求头的时间。

首先我们在网络面板中右键XHR链接,找到复制。注意,这里要复制为cURL(bash)
。
然后打开我在导航里面推荐的工具:CURL命令转换 – 字节次元 (bytesp.com) 转化工具。

在工具中选中python选项卡(一般默认是python),上面输入框粘贴复制好的cURL,下面输出框则会自动转化成python格式,复制到编辑器即可。
import requests
cookies = {
'BAIDUID': '87A68CEBC456601139A8005894C79D6E:FG=1',
'BAIDUID_BFESS': '87A68CEBC45660117066EE1FF8D83DBD:FG=1',
'baikeVisitId': 'd4914873-2b33-45e9-8c95-61f00c9a2b18',
}
headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
# 'Cookie': 'BAIDUID=87A68CEBC456601139A8005894C79D6E:FG=1; BAIDUID_BFESS=87A68CEBC45660117066EE1FF8D83DBD:FG=1; baikeVisitId=d4914873-2b33-45e9-8c95-61f00c9a2b18',
'Pragma': 'no-cache',
'Referer': 'https://baike.baidu.com/calendar/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0',
'X-Requested-With': 'XMLHttpRequest',
'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Microsoft Edge";v="128"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
params = {
'_': '1725521601879',
}
response = requests.get(
'https://baike.baidu.com/cms/home/eventsOnHistory/09.json',
params=params,
cookies=cookies,
headers=headers,
)
首先我们要删除cookies信息和请求中的cookies,做第一次请求验证,看不含cookies是否返回信息。因为cURL转化工具中输出的没有打印信息,而接口返回数据又为json,所以我们需要添加下方代码来打印查看信息。
data = response.json()
print(data)
运行之后发现可以正常返回数据,验证了cookies不是必要验证参数。
接下来是参数的构造,之前我们猜想是时间戳,现在先用python获取时间戳,与接口那个时间戳做一个对比。
import time
timestamp = time.time()
print(timestamp)
输出结果为1725523650.829632
,与1725521601879
趋于接近,只是位数不同,那我们确定了这就是时间戳的转化形式。目标参数比当前时间戳多三位,那我们只需要获取当前时间戳后乘以1000,然后使用int去掉小数点之后的数字即可。
timestamp = int(timestamp * 1000)
print(timestamp)
修改之后输出结果为1725523923289
。然后我们修改之前的params,使其变为:
params = {
'_': f"{int(time.time()*1000):.0f}",
}
当然,获取timetamp要在params之前。然后我们做一次整体请求,发现成功返回了完整数据,接下来就是关于json文件名的构造了。

我们通过原网页切换月份来观察,发现文件名就是月份,那我们可以用python来获取当前月份,代码如下:
from datetime import datetime
now = datetime.now()
month = now.strftime('%m')
print(month)
修改后如下:
response = requests.get(
f'https://baike.baidu.com/cms/home/eventsOnHistory/{month}.json',
params=params,
cookies=cookies,
headers=headers,
)
修改后我们实际请求一下,发现成功返回了当前月份的全部数据。
接下来则需要对返回的数据进行处理,只输出文案内容。

通过观察我们发现数据是在月份09下,每天的又会在月日下,每天的数据又是列表,所以我们要先获取到列表,然后循环取出数据。详细的数据则是固定的year
、title
、type
。
现在月我们已经获取到了,月日还需要我们获取一下。
mouth_day = now.strftime('%m%d')
下面是获取请求当天的数据并做格式化输出,因为title是带html格式的,所以需要使用bs4
库的BeautifulSoup
进一步处理:
results = data[month][month_day]
for i in results:
year = i['year']
type = i['type']
title = BeautifulSoup(i['title'],'html.parser').get_text()
text = f"{year}年,{title}"
print(text)
运行后输出结果如下:
917年,刘龚称帝,建立南汉
1567年,日本战国时代大名伊达政宗出生
1885年,晚清政治家左宗棠逝世
1906年,热力学奠基人路德维希·玻尔兹曼逝世
1914年,马恩河会战开始
1926年,英军炮舰炮击万县,史称“万县惨案”
1937年,最大一次纳粹集会在纽伦堡举行
1967年,日本漫画家久米田康治出生
1971年,中国画家潘天寿逝世
1972年,慕尼黑奥运会发生慕尼黑惨案
1997年,诺贝尔和平奖获得者特蕾莎修女逝世
至此完成了整个接口数据的爬取。之后我会写一个接口格式代码上传到此文章。