使用python3爬取知乎用戶信息并分析
參考了:囈語 ? 如何寫一個簡單的分布式知乎爬蟲?打算自己做一個python3的分布式爬蟲
想要抓取數(shù)據(jù)第献,首先分析用戶信息頁面的構(gòu)成望几,以輪子哥為例
紅框里的便我們要抓取的用戶關(guān)鍵信息(的一部分)缰趋。
最上面是我們的目標(biāo)URL:https://www.zhihu.com/people/excited-vczh/answers。
觀察一下這個URL的組成:
http://www.zhihu.com + /people + /excited-vczh + /answer
可以發(fā)現(xiàn)只有 excited-vczh 這部分是會變化的,它代表著知乎用戶的唯一ID按脚,在知乎的數(shù)據(jù)格式中泵督,它的鍵名叫做 urlToken。
所以我們可以用拼接字符串的形式哥倔,得到我們待抓取頁面的URL:
url='%s/people/%s/answers'%(host,urlToken)
頁面URL有了秸架,而且從上圖我們可以發(fā)現(xiàn) 不登錄 也可以訪問用戶主頁,這說明我們可以不用考慮模擬登陸的問題咆蒿,可以自由的獲取用戶主頁面源碼东抹。
那么我們?nèi)绾螐挠脩糁黜摰脑创a中獲取用戶的數(shù)據(jù)呢蚂子?一開始我以為需要挨個匹配頁面中對應(yīng)的部分,但我查看源碼的時候發(fā)現(xiàn)知乎把用戶數(shù)據(jù)集集中放到了源碼的一個地方缭黔,那就是 id="data" 的 div 的 data-state 屬性的值中食茎,看下圖:
從上圖我們可以發(fā)現(xiàn),date-state 的屬性值中藏有用戶的信息馏谨,比如我們可以依次找到用戶的教育經(jīng)歷(educations)别渔、簡介(headline)、參與的 Live 數(shù)量(participatedLiveCount)惧互、關(guān)注的收藏夾數(shù)量(followingFavlistsCount)哎媚、被收藏的次數(shù)(favoritedCount)、關(guān)注他的用戶數(shù)(followerCount)喊儡、關(guān)注的話題數(shù)量(followingTopicCount)抄伍、用戶描述(description)等信息。通過觀察我們也可以發(fā)現(xiàn)管宵,數(shù)據(jù)應(yīng)該是以 JSON 格式存儲截珍。
知道了用戶數(shù)據(jù)都藏在 date-state 中,我們 用 lxml
把該屬性的值取出來箩朴,然后作為 JSON 格式讀取岗喉,再把數(shù)據(jù)集中存儲用戶數(shù)據(jù)的部分提取出來即可,看代碼:
html = etree.HTML(request.text)
result = html.xpath("http://div[@id='data']/@data-state")
result = json.loads(result[0])
print(result['entities']['users'][urlToken])
選擇抓取用戶的關(guān)注者(follower)列表炸庞,我們可以根據(jù)知乎的api來抓取用戶的關(guān)注者列表
關(guān)注者列表api:? https://www.zhihu.com/api/v4/members/excited-vczh/followers?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset='+str(offset)+'&limit=20'
關(guān)注列表api:? https://www.zhihu.com/api/v4/members/excited-vczh/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset='+str(offset)+'&limit=20'
每頁默認(rèn)顯示20個用戶
代碼如下:
def getFollowers(self,offset):
getFolloweesUrl ='https://www.zhihu.com/api/v4/members/excited-vczh/followers?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset='+str(offset)+'&limit=20'
req =self.session.get(url=getFolloweesUrl,headers=headers)
hjson = json.loads(req.text)
flag = hjson['paging']['is_end']? #is_end為true結(jié)束
for i in range(0,20):
print(hjson['data'][i]['url_token']) #打印用戶url_token
offsetFlag= offsetFlag+20? #下一頁
注意:使用api獲取關(guān)注者或關(guān)注列表必須登陸钱床,不登陸會報錯誤代碼
關(guān)于登錄請查看我的GitHub