天天看點

Python爬蟲爬取知乎小結

最近學習了一點網絡爬蟲,并實作了使用python來爬取知乎的一些功能,這裡做一個小的總結。網絡爬蟲是指通過一定的規則自動的從網上抓取一些資訊的程式或腳本。我們知道機器學習和資料挖掘等都是從大量的資料出發,找到一些有價值有規律的東西,而爬蟲則可以幫助我們解決擷取資料難的問題,是以網絡爬蟲是我們應該掌握的一個技巧。

python有很多開源工具包供我們使用,我這裡使用了requests、beautifulsoup4、json等包。requests子產品幫助我們實作http請求,bs4子產品和json子產品幫助我們從擷取到的資料中提取一些想要的資訊,幾個子產品的具體功能這裡不具體展開。下面我分功能來介紹如何爬取知乎。

模拟登入

要想實作對知乎的爬取,首先我們要實作模拟登入,因為不登入的話好多資訊我們都無法通路。下面是登入函數,這裡我直接使用了知乎使用者fireling的登入函數,具體如下。其中你要在函數中的data裡填上你的登入賬号和密碼,然後在爬蟲之前先執行這個函數,不出意外的話你就登入成功了,這時你就可以繼續抓取想要

的資料。注意,在首次使用該函數時,程式會要求你手動輸入captcha碼,輸入之後目前檔案夾會多出cookiefile檔案和zhihucaptcha.gif,前者保留了cookie資訊,後者則儲存了驗證碼,之後再去模拟登入時,程式會自動幫我們填上驗證碼。

Python爬蟲爬取知乎小結

需要注意的是,在login函數中有一個全局變量s=reequests.session(),我們用這個全局變量來通路知乎,整個爬取過程中,該對象都會保持我們的持續模拟登入。

擷取使用者基本資訊

知乎上每個使用者都有一個唯一id,例如我的id是marcovaldong,那麼我們就可以通過通路位址

https://www.zhihu.com/people/marcovaldong

來通路我的首頁。個人首頁中包含了居住地、所在行業、性别、教育情況、獲得的贊數、感謝數、關注了哪些人、被哪些人關注等資訊。是以,我首先介紹如何通過爬蟲來擷取某一個知乎使用者的一些資訊。下面的函數get_userinfo(userid)實作了爬取一個知乎使用者的個人資訊,我們傳遞給該使用者一個使用者id,該函數就會傳回一個

list,其中包含昵稱、id、居住地、所在行業、性别、所在公司、職位、畢業學校、專業、贊同數、感謝數、提問數、回答數、文章數、收藏數、公共編輯數量、關注的人數、被關注的人數、首頁被多少個人浏覽過等19個資料。

Python爬蟲爬取知乎小結

下圖是我的首頁的部分截圖,從上面可以看到這19個資料,下面第二張圖是終端上顯示的我的這19個資料,我們可以作個對照,看看是否全部抓取到了。這個函數我用了很長時間來調試,因為不同人的首頁的資訊完整程度是不同的,如果你在使用過程中發現了錯誤,歡迎告訴我。

Python爬蟲爬取知乎小結
Python爬蟲爬取知乎小結

擷取某個答案的所有點贊者名單

知乎上有一個問題是如何寫個爬蟲程式扒下知乎某個回答所有點贊使用者名單?,我參考了段小草的這個答案如何入門python爬蟲,然後有了下面的這個函數。

這裡先來大概的分析一下整個流程。我們要知道,知乎上的每一個問題都有一個唯一id,這個可以從位址中看出來,例如問題2015

年有哪些書你讀過以後覺得名不符實?的位址為 https://www.zhihu.com/question/38808048

,其中38808048就是其id。而每一個問題下的每一個答案也有一個唯一id,例如該問題下的最高票答案2015

年有哪些書你讀過以後覺得名不符實? - 餘悅的回答 -

知乎的位址連結為https://www.zhihu.com/question/38808048/answer/81388411

,末尾的81388411就是該答案在該問題下的唯一id。不過我們這裡用到的不是這兩個id,而是我們在抓取點贊者名單時的唯一id,此id的獲得方法是這樣:例如我們打算抓取如何評價《人間正道是滄桑》這部電視劇?

- 老編輯的回答 - 知乎的點贊者名單,首先打開firebug,點選“5321 人贊同”時,firebug會抓取到一個“get

voters_profile”的一個包,把光标放在上面,會看到一個連結

https://www.zhihu.com/answer/5430533/voters_profile

,其中的5430533才是我們在抓取點贊者名單時用到的一個唯一id。注意此id隻有在答案被贊過後才有。(在這安利一下《人間正道是滄桑》這部電視劇,該劇以楊立青三兄妹的恩怨情仇為線索,從大革命時期到解放戰争,比較全面客觀的展現了國共兩黨之間的主義之争,每一次看都會新的認識和體會。)

在拿到唯一id後,我們用requests子產品去get到知乎傳回的資訊,其中有一個json語句,該json語句中包含點贊者的資訊。另外,我們在網頁上浏覽點贊者名單時,一次隻能看到20條,每次下拉到名單底部時又加載出20條資訊,再加載20條資訊時所用的請求位址也包含在前面的json語句中。是以我們需要從json語句中提取出點攢着資訊和下一個請求位址。在網頁上浏覽點贊者名單時,我們可以看到點贊者的昵稱、頭像、獲得了多少贊同和感謝,以及提問和回答的問題數量,這裡我提取了每個點贊者的昵稱、首頁位址(也就是使用者id)、贊同數、感謝數、提問數和回答數。關于頭像的提取,我會在下面的函數中實作。

在提取到點贊者名單後,我将者資訊儲存了以唯一id命名的txt檔案中。下面是函數的具體實作。

Python爬蟲爬取知乎小結

注意,點贊者名單中會有匿名使用者,或者有使用者被登出,這時我們抓取不到此使用者的資訊,我這裡在txt檔案中添加了一句“有點贊者的資訊缺失”。

使用同樣的方法,我們就可以抓取到一個使用者的關注者名單和被關注者名單,下面列出了這兩個函數。但是關注者名單抓取函數有一個問題,每次使用其抓取大v的關注者名單時,當抓取到第10020個follower的時候程式就會報錯,好像知乎有通路限制一般。這個問題,我還沒有找到解決辦法,希望有solution的告知一下。因為沒有看到有使用者關注10020+個人,是以抓取被關注者名單函數暫時未發現報錯。 

Python爬蟲爬取知乎小結

提取使用者頭像

再往下就是抓取使用者頭像了,給出某個唯一id,下面的函數自動解析其首頁,從中解析出該使用者頭像位址,抓取到圖檔并儲存到本地檔案,檔案以使用者唯一id命名。 

Python爬蟲爬取知乎小結

結合其他函數,我們就可以抓取到某個答案下所有點贊者的頭像,某個大v所有followers的頭像等。

抓取某個問題的所有答案

給出某個唯一id,下面的函數幫助爬取到該問題下的所有答案。注意,答案内容隻抓取文字部分,圖檔省略,答案儲存在txt檔案中,txt檔案以答主id命名。

Python爬蟲爬取知乎小結

資料庫存取資料

在完成了上面的這些功能後,下一步要做的是将使用者資訊儲存在資料庫中,友善資料的讀取使用。我剛剛接觸了一下sqlite3,僅僅實作了将使用者資訊存儲在表格中。

Python爬蟲爬取知乎小結

等熟悉了sqlite3的使用,我的下一步工作是抓取大量使用者資訊和使用者之間的follow資訊,嘗試着将大v間的follow關系進行可視化。再下面的工作應該就是學習python的爬蟲架構scrapy和爬取微網誌了。

另外,在寫這篇部落格的時候我又重新測試了一下上面的這些函數,然後我再在火狐上通路知乎時,系統提示“因為該賬戶過度頻繁通路”而要求輸入驗證碼,看來知乎已經開始限制爬蟲了,這樣以來我們就需要使用一些反反爬蟲技巧了,比如控制通路頻率等等,這個等以後有了系統的了解之後再作補充吧。

作者:晴明

來源:51cto