天天看點

【2022知乎爬蟲】我用Python爬蟲爬了2300多條知乎評論!

【2022知乎爬蟲】我用Python爬蟲爬了2300多條知乎評論!

馬哥原創爬蟲:用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、頁碼、評論作者、作者性别、作者首頁、作者頭像、評論時間、評論内容、評論級别。

部分資料截圖:

【2022知乎爬蟲】我用Python爬蟲爬了2300多條知乎評論!

三、爬蟲代碼講解

3.1 分析知乎頁面

任意打開一個知乎回答,點開評論界面:

【2022知乎爬蟲】我用Python爬蟲爬了2300多條知乎評論!

同時打開chrome浏覽器的開發者模式,評論往下翻頁,就會找到目标連結:

【2022知乎爬蟲】我用Python爬蟲爬了2300多條知乎評論!

作為爬蟲開發者,看到這種0-19的json資料,一定要敏感,這大機率就是評論資料了。猜測一下,每頁有20條評論,逐級打開json資料:

【2022知乎爬蟲】我用Python爬蟲爬了2300多條知乎評論!

基于此資料結構,開發爬蟲代碼。

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,直接複制下來,然後替換:

【2022知乎爬蟲】我用Python爬蟲爬了2300多條知乎評論!

先提取出一共多少評論,用于計算後面的翻頁次數:

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說, 感謝您的閱讀。

繼續閱讀