持续创造,加快生长!这是我参与「掘金日新方案 4 月更文挑战」的第24天,点击查看活动概况
前语
大家好,咱们今日来爬取c站的高校名单,把其高校名单,成员和内容数获取下来,不过,咱们发现这个网站比咱们平常多了一个验证,下面看看我是怎样解决的。
功用完成
话不多说,咱们和平常一样,发送咱们的恳求,按照平常,咱们看看代码怎样写。
url = 'https://bizapi.csdn.net/community-cloud/v1/homepage/community/by/tag?deviceType=PC&tagId=37'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'}
response = requests.get(url=url,headers=headers)
咱们在这儿运用requests
库发送 GET 恳求,并将 URL 和恳求头作为参数传递给get
办法。恳求的 URL 是https://bizapi.csdn.net/community-cloud/v1/homepage/community/by/tag?deviceType=PC&tagId=37
,表明查询社区根据标签分类的数据。恳求头包含了User-Agent
和Accept
字段,分别表明客户端的 User-Agent 和 Accept 协议类型。
不过咱们会发现,咱们得不到数据,就说明咱们被反爬了,我测验了很多次,咱们发现它做了一个验证。
headers = {
'accept': 'application/json, text/plain, */*',
'origin': 'https://bbs.csdn.net',
'referer': 'https://bbs.csdn.net/college?utm_source=csdn_bbs_toolbar&spm=1035.2022.3001.8850&category=37',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
'x-ca-key': '203899271',
'x-ca-nonce': '13b10c23-6a9b-423e-92a7-b114bc2c7f48',
'x-ca-signature': 'Hhnf/RUARDM2jddNAkl2tJ6hpXfweWbY1U4/yh6FCZM=',
'x-ca-signature-headers': 'x-ca-key,x-ca-nonce',
}
咱们这儿科普一下,x-ca-signature 是对恳求内容的签名,用于验证恳求的完整性和可信性。 签名通常是经过运用私钥和一种哈希算法(如 SHA256)对恳求内容进行核算得到的。 假如恳求头中出现这三个参数,定心,是为了反爬用的,当然也可以用于约束恳求频率,避免歹意攻击。
在解决该反爬问题时,第一步便是要找到他们的加密点。寻找 x-ca-key、x-ca-nonce、x-ca-signature 加密位置这一步主要看你对开发者工具的运用熟练程度了,寻找任意一个携带该恳求头参数的恳求,然后增加相应断点。经过恳求地址中的部分关键字,即可增加 XHR 断点。再次改写页面,可进入断点中,一般会停留在send()函数位置。 下面的过程便是比较枯燥的了,需求一点点的解密,例如在本函数头部找到headers,发现其参数 x-ca-key、x-ca-nonce、x-ca-signature 现已被赋值。
这儿咱们没有做多页爬虫,就没有去解密了,感兴趣的朋友自己去测验。
内容获取
咱们拿到了数据,接下来就可以提取内容了,咱们看看代码怎样写,这儿就很简单了。
data =responses.json()['data']
for list in data:
tagName = list['tagName']
list_url= list['url']
res = requests.get(list_url)
num = re.findall('<div title="(\d+)"',res.text)
print(tagName,list_url,num)
咱们这儿运用responses.json()['data']
读取 API 响应 JSON 数据,并在一个数组中提取数据。然后,它运用一个 for 循环遍历数组中的每个元素,提取tagName
和url
两个字段,并运用requests.get()
发送 GET 恳求获取数据。最终,它运用正则表达式从响应文本中提取num
数据,并将其打印到控制台上。
总结
咱们这样就获取到了内容,本文仅供学习。