
馬哥原創爬蟲:用python爬了2300條知乎評論!
您好,我是 @馬哥python說,一枚10年程式猿。
一、爬取目标
前些天我分享過一篇微網誌的爬蟲:
https://www.cnblogs.com/mashukui/p/16414027.html
但是知乎平台和微網誌平台的不同之處在于,微網誌平台的資料用于分析社會輿論熱點事件是極好的,畢竟是個偏娛樂化的社交平台。但知乎平台的評論更加客觀、讨論内容更加有深度,更加有專業性,基于此想法,我開發出了這個知乎評論的爬蟲。
二、展示爬取結果
我在知乎上搜尋了5個關于”考研“的知乎回答,爬取了回答下方的評論資料,共計2300+條資料。
https://www.zhihu.com/question/291278869/answer/930193847
https://www.zhihu.com/question/291278869/answer/802226501
https://www.zhihu.com/question/291278869/answer/857896805
https://www.zhihu.com/question/291278869/answer/910489150
https://www.zhihu.com/question/291278869/answer/935352960
爬取字段,含:
回答url、頁碼、評論作者、作者性别、作者首頁、作者頭像、評論時間、評論内容、評論級别。
部分資料截圖:
三、爬蟲代碼講解
3.1 分析知乎頁面
任意打開一個知乎回答,點開評論界面:
同時打開chrome浏覽器的開發者模式,評論往下翻頁,就會找到目标連結:
作為爬蟲開發者,看到這種0-19的json資料,一定要敏感,這大機率就是評論資料了。猜測一下,每頁有20條評論,逐級打開json資料:
基于此資料結構,開發爬蟲代碼。
3.2 爬蟲代碼
首先,導入用到的庫:
import requests
import time
import pandas as pd
import os
從上面的截圖可以看到,評論時間created_time是個10位時間戳,是以,定義一個轉換時間的函數:
def trans_date(v_timestamp):
"""10位時間戳轉換為時間字元串"""
timeArray = time.localtime(v_timestamp)
otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
return otherStyleTime
作者的性别gender是0、1,是以也定義一個轉換函數:
def tran_gender(gender_tag):
"""轉換性别"""
if gender_tag == 1:
return '男'
elif gender_tag == 0:
return '女'
else: # -1
return '未知'
準備工作做好了,下面開始寫爬蟲。
請求位址url,從哪裡得到呢?
打開Headers,找到Request URL,直接複制下來,然後替換:
先提取出一共多少評論,用于計算後面的翻頁次數:
url0 = 'https://www.zhihu.com/api/v4/answers/{}/root_comments?order=normal&limit=20&offset=0&status=open'.format(answer_id)
r0 = requests.get(url0, headers=headers) # 發送請求
total = r0.json()['common_counts'] # 一共多少條評論
print('一共{}條評論'.format(total))
計算翻頁次數,直接用評論總數除以20就好了:
# 判斷一共多少頁(每頁20條評論)
max_page = int(total / 20)
print('max_page:', max_page)
下面,再次發送請求,擷取評論資料:
url = 'https://www.zhihu.com/api/v4/answers/{}/root_comments?order=normal&limit=20&offset={}&status=open'.format(answer_id,str(offset))
r = requests.get(url, headers=headers)
print('正在爬取第{}頁'.format(i + 1))
j_data = r.json()
comments = j_data['data']
現在,所有資料都在comments裡面了,開始for循環周遊處理:
字段過多,這裡以評論作者、評論性别為例,其他字段同理:
for c in comments: # 一級評論
# 評論作者
author = c['author']['member']['name']
authors.append(author)
print('作者:', author)
# 作者性别
gender_tag = c['author']['member']['gender']
genders.append(tran_gender(gender_tag))
其他字段不再贅述。
需要注意的是,知乎評論分為一級評論和二級評論(二級評論就是一級評論的回複評論),是以,為了同時爬取到二級評論,開發以下邏輯:(同樣以評論作者、評論性别為例,其他字段同理)
if c['child_comments']: # 如果二級評論存在
for child in c['child_comments']: # 二級評論
# 評論作者
print('子評論作者:', child['author']['member']['name'])
authors.append(child['author']['member']['name'])
# 作者性别
genders.append(tran_gender(child['author']['member']['gender']))
待所有字段處理好之後,把所有字段的清單資料拼裝到DataFrame,to_csv儲存到csv檔案裡,完畢!
df = pd.DataFrame(
{
'回答url': answer_urls,
'頁碼': [i + 1] * len(answer_urls),
'評論作者': authors,
'作者性别': genders,
'作者首頁': author_homepages,
'作者頭像': author_pics,
'評論時間': create_times,
'評論内容': contents,
'評論級别': child_tag,
}
)
# 儲存到csv檔案
df.to_csv(v_result_file, mode='a+', index=False, header=header, encoding='utf_8_sig')
完整代碼中還涉及到避免資料重複、字段值拼接、判斷翻頁終止等細節邏輯,詳細了解請見文末。
四、同步視訊
示範視訊:
https://www.zhihu.com/zvideo/1545723927430979584
我是 @馬哥python說, 感謝您的閱讀。