Python爬蟲實(shí)戰(zhàn):抓取知乎問題下所有回答
好久不見,工作有點(diǎn)忙...雖然每天都是在寫爬蟲,也解鎖了很多爬蟲實(shí)戰(zhàn)新技能,但由于工作里是用 NodeJS,已經(jīng)好久沒動手寫 Python 了。
對于解決需求問題來說,無論 Python 還是 NodeJS 也只不過是語法和模塊不同,分析思路和解決方案是基本一致的。
最近寫了個簡單的知乎回答的爬蟲,感興趣的話一起來看看吧。

需求

抓取知乎問題下所有回答,包括其作者、作者粉絲數(shù)、回答內(nèi)容、時間、回答的評論數(shù)、回答贊同數(shù)以及該回答的鏈接。




分析

以上圖中問題為例,想要拿到回答的相關(guān)數(shù)據(jù),一般我們可以在 Chrome 瀏覽器下按 F12 來分析請求;但借助Charles抓包工具可以更直觀地獲取相關(guān)字段:



注意我標(biāo)注的 Query String 參數(shù)中 limit 5 表示每次請求返回 5 條回答,經(jīng)測試最多可以改成 20;offset 表示從第幾個回答開始;
而返回的結(jié)果是 Json 格式的,每一條回答包含的信息足夠多,我們只要篩選想要抓取的字段記錄保存即可。
需要注意的是 content 字段中返回的是回答內(nèi)容,但它格式是帶了網(wǎng)頁標(biāo)簽的,經(jīng)過搜索我選用了 HTMLParser 來解析,就免得自己再手動處理了。

代碼

import requests,jsonimport datetimeimport pandas as pdfrom selectolax.parser import HTMLParserurl = 'https://www.zhihu.com/api/v4/questions/486212129/answers'headers = {'Host':'www.zhihu.com','user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36','referer':'https://www.zhihu.com/question/486212129'}df = pd.DataFrame(columns=('author','fans_count','content','created_time','updated_time','comment_count','voteup_count','url'))def crawler(start):print(start)global dfdata= {'include':'data[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,attachment,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,is_labeled,paid_info,paid_info_content,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,is_recognized;data[*].mark_infos[*].url;data[*].author.follower_count,vip_info,badge[*].topics;data[*].settings.table_of_content.enabled','offset':start,'limit':20,'sort_by':'default','platform':'desktop'}#將攜帶的參數(shù)傳給paramsr = requests.get(url, params=data,headers=headers)res = json.loads(r.text)if res['data']:for answer in res['data']:author = answer['author']['name']fans = answer['author']['follower_count']content = HTMLParser(answer['content']).text()#content = answer['content']created_time = datetime.datetime.fromtimestamp(answer['created_time'])updated_time = datetime.datetime.fromtimestamp(answer['updated_time'])comment = answer['comment_count']voteup = answer['voteup_count']link = answer['url']row = {'author':[author],'fans_count':[fans],'content':[content],'created_time':[created_time],'updated_time':[updated_time],'comment_count':[comment],'voteup_count':[voteup],'url':[link]}df = df.append(pd.DataFrame(row),ignore_index=True)if len(res['data'])==20:crawler(start+20)else:print(res)crawler(0)df.to_csv(f'result_{datetime.datetime.now().strftime("%Y-%m-%d")}.csv',index=False)print("done~")

結(jié)果

最終抓取結(jié)果大致如下:



可以看到有的回答是空的,去問題下檢查發(fā)現(xiàn)是視頻回答,沒有文本內(nèi)容,這個就先忽略了,當(dāng)然可以自己再取下視頻鏈接加到結(jié)果中。
目前(2021.09)看這個問題接口沒有特別大限制,包括我在代碼里的請求也沒有帶 cookie 直接來抓取的,而且通過修改 limit 參數(shù)到 20 來減少請求次數(shù)。

爬蟲意義

爬蟲只是獲取數(shù)據(jù)的一種途徑,如何解讀才是數(shù)據(jù)的更大價值所在。
我是TED,一個天天寫爬蟲、但好久沒寫Python的數(shù)據(jù)工程師,后續(xù)會繼續(xù)更新一系列自己琢磨的 Python 爬蟲項(xiàng)目,歡迎持續(xù)關(guān)注~
