爬取知乎中的推薦內容,輸出每條推薦文章的鏈接和標題
或許可以使用獲取html的方式來完成這個任務,不過這次主要想練一下json文件的爬取。
json數據格式簡單,不需要像html那樣需要構造選擇器來定位數據位置,只需要根據json數據的格式一步步找到目標字段即可。
先在打開瀏覽器終端的network,通過觀察找到推薦欄目對于的鏈接,為便于查找可勾選XHR選項進行過濾
json算不算爬蟲?再觀察鏈接的格式,上面圖片中的目標鏈接為https://www.zhihu.com/api/v3/feed/topstory/recommend?session_token=ce014c22353196104dcbc81d8a5593df&desktop=true&page_number=2&limit=6&action=down&after_id=5&ad_interval=-1
,可分解為兩個部分:https://www.zhihu.com/api/v3/feed/topstory/recommend?
和session_token=ce014c22353196104dcbc81d8a5593df&desktop=true&page_number=2&limit=6&action=down&after_id=5&ad_interval=-1
,后面這一部分為請求參數,接下來就可以構造鏈接并請求數據了。
import requests
import jsonbase_url = 'https://www.zhihu.com/api/v3/feed/topstory/recommend?'
headers = {'cookie':'...', # 你的cookie'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.3',
}
# page和after_id可根據需要進行調整
page = 0
after_id = 6
params = {'session_token':'7ff1929781f57d1262b18480fe3011c2','desktop':'true','page_number':page,'limit':'6','action':'down','after_id':after_id,'ad_interval':'1'
}
# 獲取對應頁面的json數據
def get_page(params, base_url, headers):# 附加參數extra_url = '&'.join(['{key}={val}'.format(key=key,val=params[key]) for key in params])# 合成urlurl = base_url + extra_url# 嘗試獲取json數據try:response = requests.get(url, headers = headers)if response.status_code == 200:return response.json()except requests.ConnectionError as e:print('Error',e.args)return []# 獲取json數據
data = get_page(params, headers)
上面這段代碼執行完后就獲取到了推薦頁面的json數據,這里需要的是每條推薦對應的鏈接。
先將獲取到的json數據保存到文件中方便觀察其數據格式
# 保存數據
with open('recommend.json', 'w', encoding='utf-8') as file:str = json.dumps(data, indent = 2, ensure_ascii = False)file.write(str)
觀察后發現里面的鏈接不能訪問后跳轉到的頁面都是一些json數據,也就是在數據中沒有顯式的給出每條推薦的鏈接,需要自己構造。
點開每條推薦,跳轉到的頁面如下:
爬蟲selenium。觀察地址欄的地址發現需要兩個數據,一是question后面的question_id,還有一個每個answer對應的答主id,這些數據都可以在爬取到的json數據中找到。(需要花點時間進行觀察才會發現)
通過觀察又發現推薦中的內容有的是文章,有的是視頻,兩者的json數據格式不完全一樣,如果是視頻內容則其對應的json數據中沒有question字段,為簡化處理,將視頻推薦內容直接舍去,只輸出推薦文章的標題和鏈接。(視頻標題和鏈接的提取大同小異)
然后就有了下面這段代碼
with open('recommend.json', 'r', encoding='utf-8') as file:str = file.read()data = json.loads(str)['data']num = len(data)# 接下來就是提取其中的信息,這需要觀察json數據的格式,了解你所需要的數據的位置,然后一步步定位# 由于json中沒有找到每條推薦對應的鏈接,所以需要自己根據json數據自己合成鏈接# 鏈接形如:https://www.zhihu.com/question/377886499/answer/1849697584for i in range(num):# 獲取target字段,里面包含主要的鏈接信息target = data[i].get('target')id = target.get('id')# 嘗試獲取question字段,如果失敗則該條推薦不是文章類型question = target.get('question', -1)if question != -1:question_id = question.get('id')# 合成推薦內容的鏈接url = 'https://www.zhihu.com/question/{q_id}/answer/{id}'.format(q_id = question_id, id = id)title = question.get('title')print('{title}\n{url}\n'.format(title=title, url=url))
打印效果如下:
最后提取出來的數據可以存放到數據庫中,這里偷個懶就不寫了。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态