網(wǎng)頁(yè)抓取數據百度百科( 大數據之美獲取百度指數相關(guān)的數據困難及解決辦法 )
優(yōu)采云 發(fā)布時(shí)間: 2022-02-12 11:26網(wǎng)頁(yè)抓取數據百度百科(
大數據之美獲取百度指數相關(guān)的數據困難及解決辦法
)
作者 | 葉廷云
來(lái)源|艾婷云君
一、簡(jiǎn)介
在實(shí)際業(yè)務(wù)中,我們可能會(huì )使用爬蟲(chóng)根據關(guān)鍵詞獲取百度搜索索引的歷史數據,然后進(jìn)行相應的數據分析。
百度指數,體驗大數據之美。但是,要獲取百度指數相關(guān)的數據,困難在于:
本文以獲取關(guān)鍵詞(北京冬奧會(huì ),冬奧會(huì )開(kāi)幕式):近期百度搜索索引數據為例,講解使用爬蟲(chóng)獲取百度搜索索引歷史數據的過(guò)程根據關(guān)鍵詞(以冬奧會(huì )為例),然后制作近90天冬奧會(huì )搜索索引可視化和采集報道的素材的詞云圖媒體。
二、網(wǎng)頁(yè)分析
如果沒(méi)有百度賬號,需要先注冊,然后進(jìn)入百度指數官網(wǎng):
百度指數
搜索冬奧會(huì ),選擇過(guò)去90天,可以看到最近90天冬奧會(huì )搜索指數的折線(xiàn)圖:
最后要做的是獲取這些搜索索引數據并將其保存到本地 Excel。
首先,登錄后需要獲取cookie(必須要有,否則無(wú)法獲取數據)。具體cookie獲取如下:
分析可以找到j(luò )son數據的接口,如下:
Request URL中word參數后面跟著(zhù)搜索到的關(guān)鍵詞(只編碼漢字),days=90,表示過(guò)去90天的數據,從前一天往前推一個(gè)月當前日期,并可根據需要修改天數以獲取更多數據或更少數據。將Request URL粘貼到瀏覽器中查看(查看JSON數據網(wǎng)頁(yè),有JSON Handle之類(lèi)的插件會(huì )很方便)
https://index.baidu.com/api/SearchApi/index?area=0&word[[%7B%22name%22:%22%E5%86%AC%E5%A5%A5%E4%BC%9A%22,%22wordType%22:1%7D]]&days=90
可以看到以下數據:
將all、pc、wise對應的數據解密后,與搜索索引的折線(xiàn)圖顯示的數據進(jìn)行對比,發(fā)現all部分的數據就是搜索索引的數據。這個(gè)請求返回的數據都在這里了,也可以看到uniqid,而且每次刷新加密數據時(shí),加密數據和uniqid都會(huì )發(fā)生變化。
經(jīng)過(guò)多次分析,發(fā)現請求數據的url下的uniqid出現在這個(gè)url中,如上圖。
因此需要從請求數據對應的url中獲取數據,解析出搜索索引對應的加密數據和uniqid,然后將url拼接得到key,最后調用解密方法解密得到搜索索引的數據。
https://index.baidu.com/Interface/ptbk?uniqid=b92927de43cc02fcae9fbc0cee99e3a9
找到對應的url后,爬蟲(chóng)的基本思路還是一樣的:發(fā)送請求,得到響應,解析數據,然后解密保存數據。
三、數據采集
Python代碼:
<p>#?-*-?coding:?UTF-8?-*-
"""
@Author ??:葉庭云
@公眾號????:AI庭云君
@CSDN ????:https://yetingyun.blog.csdn.net/
"""
import?execjs
import?requests
import?datetime
import?pandas?as?pd
from?colorama?import?Fore,?init
init()
#?搜索指數數據解密的Python代碼
def?decryption(keys,?data):
????dec_dict?=?{}
????for?j?in?range(len(keys)?//?2):
????????dec_dict[keys[j]]?=?keys[len(keys)?//?2?+?j]
????dec_data?=?''
????for?k?in?range(len(data)):
????????dec_data?+=?dec_dict[data[k]]
????return?dec_data
if?__name__?==?"__main__":
?#?北京冬奧會(huì )??冬奧會(huì )開(kāi)幕式
????keyword?=?'北京冬奧會(huì )'?????#?百度搜索收錄的關(guān)鍵詞
????period?=?90???????????#?時(shí)間??近90天
????start_str?=?'https://index.baidu.com/api/SearchApi/index?area=0&word=[[%7B%22name%22:%22'
????end_str?=?'%22,%22wordType%22:1%7D]]&days={}'.format(period)
????dataUrl?=?start_str?+?keyword?+?end_str
????keyUrl?=?'https://index.baidu.com/Interface/ptbk?uniqid='
????#?請求頭
????header?=?{
????????'Accept':?'application/json,?text/plain,?*/*',
????????'Accept-Encoding':?'gzip,?deflate,?br',
????????'Accept-Language':?'zh-CN,zh;q=0.9',
????????'Connection':?'keep-alive',
????????'Cookie':?'注意:換成你的Cookie',
????????'Host':?'index.baidu.com',
????????'Referer':?'https://index.baidu.com/v2/main/index.html',
????????'sec-ch-ua':?'"?Not;A?Brand";v="99",?"Google?Chrome";v="91",?"Chromium";v="91"',
????????'sec-ch-ua-mobile':?'?0',
????????'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/91.0.4472.77?Safari/537.36'
????}
????#?設置請求超時(shí)時(shí)間為16秒
????resData?=?requests.get(dataUrl,
???????????????????????????timeout=16,?headers=header)
????uniqid?=?resData.json()['data']['uniqid']
????print(Fore.RED?+?"uniqid:{}".format(uniqid))
????keyData?=?requests.get(keyUrl?+?uniqid,
???????????????????????????timeout=16,?headers=header)
????keyData.raise_for_status()
????keyData.encoding?=?resData.apparent_encoding
????#?解析json數據
????startDate?=?resData.json()['data']['userIndexes'][0]['all']['startDate']
????print(Fore.RED?+?"startDate:{}".format(startDate))
????endDate?=?resData.json()['data']['userIndexes'][0]['all']['endDate']
????print(Fore.RED?+?"endDate:{}".format(endDate))
????source?=?(resData.json()['data']['userIndexes'][0]['all']['data'])??#?原加密數據
????print(Fore.RED?+?"原加密數據:{}".format(source))
????key?=?keyData.json()['data']??#?密鑰
????print(Fore.RED?+?"密鑰:{}".format(key))
????res?=?decryption(key,?source)
????#?print(type(res))
????resArr?=?res.split(",")
????#?生成datetime
????dateStart?=?datetime.datetime.strptime(startDate,?'%Y-%m-%d')
????dateEnd?=?datetime.datetime.strptime(endDate,?'%Y-%m-%d')
????dataLs?=?[]
????#?起始日期到結束日期每一天
????while?dateStart?