node.js實現爬蟲功能介紹

admin發表於2017-04-12

本文介紹一下使用node.js實現基於WTFPL協議爬蟲功能,感謝去的朋友可以做一下參考。

一.環境配置:

1)搞一臺伺服器,什麼linux都行,我用的是CentOS 6.5。

2)裝個mysql資料庫,5.5或5.6均可,圖省事可以直接用lnmp或lamp來裝,回頭還能直接在瀏覽器看日誌。

3)先安個node.js環境,我用的是0.12.7,更靠後的版本沒試過。

4)執行npm -g install forever,安裝forever好讓爬蟲在後臺跑。

5)把所有程式碼整到本地(整=git clone)。

6)在專案目錄下執行npm install安裝依賴庫。

7)在專案目錄下建立json和avatar兩個空資料夾。

8)建立一個空mysql資料庫和一個有完整許可權的使用者,先後執行程式碼裡的setup.sql和startusers.sql,建立資料庫結構並匯入初始種子使用者。

9)編輯config.js,標明(必須)的配置項必須填寫或修改,其餘項可以暫時不改:

[JavaScript] 純文字檢視 複製程式碼
exports.jsonPath = "./json/";//生成json檔案的路徑
exports.avatarPath = "./avatar/";//儲存頭像檔案的路徑
exports.dbconfig = {
  host: 'localhost',//資料庫伺服器(必須)
  user: 'dbuser',//資料庫使用者名稱(必須)
  password: 'dbpassword',//資料庫密碼(必須)
  database: 'dbname',//資料庫名(必須)
  port: 3306,//資料庫伺服器埠
  poolSize: 20,
  acquireTimeout: 30000
};
    
exports.urlpre = "http://www.softwhy.com/";//網址
exports.urlzhuanlanpre = "http://www.softwhy.com/js_23.html/";//網址
    
exports.WPurl = "www.xxx.com";//要釋出文章的wordpress網站地址
exports.WPusername = "publishuser";//釋出文章的使用者名稱
exports.WPpassword = "publishpassword";//釋出文章使用者的密碼
exports.WPurlavatarpre = "http://www.xxx.com/avatar/";//釋出文章中替代原始頭像的url地址
    
exports.mailservice = "QQ";//郵件通知服務型別,也可以用Gmail,前提是你訪問得了Gmail(必須)
exports.mailuser = "12345@qq.com";//郵箱使用者名稱(必須)
exports.mailpass = "qqpassword";//郵箱密碼(必須)
exports.mailfrom = "12345@qq.com";//傳送郵件地址(必須,一般與使用者名稱所屬郵箱一致)
exports.mailto = "12345@qq.com";//接收通知郵件地址(必須)

儲存,然後進入下一步。

二.爬蟲使用者:

爬蟲的原理其實就是模擬一個真正的知乎使用者在網站上點來點去並收集資料,所以我們需要有一個真正的知乎使用者。 為了測試可以用你自己的賬號,但從長遠著想,還是專門註冊個小號吧,一個就夠,目前的爬蟲也只支援一個。 我們的模擬過程不必像真的使用者那樣從首頁登入,而是直接借用cookie值:

註冊啟用登入之後,進入自己的主頁,使用任何有開發者模式或檢視cookie外掛的瀏覽器,開啟知乎中自己的cookie。 可能有很複雜的一大串,但我們只需要其中一部分,即「z_c0」。 複製你自己cookie中的z_c0部分,連等號、引號、分號都不要落下,最後格式大致是這樣的:

[JavaScript] 純文字檢視 複製程式碼
z_c0="LA8kJIJFdDSOA883wkUGJIRE8jVNKSOQfB9430=|1420113988|a6ea18bc1b23ea469e3b5fb2e33c2828439cb";

在mysql資料庫的cookies表中插入一行記錄,其中各欄位值分別為: 

email:爬蟲使用者的登入郵箱

password:爬蟲使用者的密碼

name:爬蟲使用者名稱

hash:爬蟲使用者的hash(每個使用者不可修改的唯一標識,其實這裡用不到,可以暫時留空)

cookie:剛才你複製的cookie

然後就可以正式開始執行了。如果cookie失效或使用者被封,直接修改這行記錄的cookie欄位即可。

三 .執行:

推薦用forever來執行,這樣不僅方便後臺執行和記錄日誌,還能在崩潰後自動重啟。 示例: 

[JavaScript] 純文字檢視 複製程式碼
forever -l /var/www/log.txt index.js

其中-l後的地址就是記錄日誌的地方,如果放在web伺服器目錄下,就能在瀏覽器裡通過http://www.xxx.com/log.txt 來直接檢視日誌了。在index.js後面加引數(用空格分隔)可以執行不同的爬蟲指令: 

1、-i 立即執行,如果不加此引數則預設在下一個指定時間執行,如每天凌晨0:05分;

2、-ng 跳過抓取新使用者階段,即getnewuser;

3、-ns 跳過快照階段,即usersnapshot;

4、-nf 跳過生成資料檔案階段,即saveviewfile;

5、-db 顯示除錯日誌。

各階段的功能在下一節介紹。為了方便執行,可以將這行命令寫成sh指令碼,例如: 

[JavaScript] 純文字檢視 複製程式碼
#!/bin/bash
cd /usr/zhihuspider
rm -f /var/www/log.txt
forever -l /var/www/log.txt start index.js $*

具體路徑請替換成自己的。這樣就能通過./zhihuspider.sh 加引數來開啟爬蟲了: 比如./zhihuspider.sh -i -ng -nf就是立即開始任務、跳過新使用者和儲存檔案階段。停止爬蟲的方法是forever stopall(或stop序號)。

四.原理概述:

看知乎爬蟲的入口檔案是index.js。它通過迴圈方式在每天指定時間執行爬蟲任務。每天順序執行的任務有三個,分別是:

1)getnewuser.js:通過當前庫內使用者關注者列表的對比,抓取新使用者資訊,依靠此機制可以自動將知乎值得關注的新人納入庫中;

2)usersnapshot.js:迴圈抓取當前庫內使用者資料和答案列表,並以每日快照形式儲存下來。

3)saveviewfile.js:根據最近一次快照內容,生成使用者分析列表,並篩選出昨日、近日和歷史精華答案發布到「看知乎」網站。


在以上三個任務執行完畢後,主執行緒會每隔幾分鐘重新整理一次知乎首頁,驗證當前cookie是否仍然有效,如果失效(跳到未登入頁),則會給指定郵箱傳送通知郵件,提醒及時更換cookie。 更換cookie的方法和初始化時一致,只需手工登入一次然後取出cookie值就行了。如果對具體程式碼實現感興趣可以仔細看裡面的註釋,調整一些配置,甚至嘗試自己重構整個爬蟲。

Tips

1)getnewuser的原理是通過對比前後兩天快照中使用者的關注數量進行指定抓取,所以必須有了至少兩次快照之後才能開始,之前就算執行也會自動跳過。

2)快照抓到一半是可以恢復的。如果程式出錯崩潰,用forever stop停止它,然後加上引數-i -ng,立即執行並跳過新使用者階段就能從剛才抓到一半的快照繼續下去了。

3)不要輕易增加快照抓取時的(偽)執行緒數,即usersnapshots中的maxthreadcount屬性。執行緒太多會導致429錯誤,同時抓取回來的大量資料可能會來不及寫入資料庫造成記憶體溢位。所以,除非你的資料庫搭在SSD上,執行緒不要超過10個。

4)saveviewfile生成分析結果的工作需要至少近7天的快照才能進行,如果快照內容少於7天會報錯並跳過。此前的分析工作可以手動查詢資料庫進行。

5)考慮到大多數人並不需要複製一個「看知乎」,已經將自動釋出wordpress文章函式入口註釋掉了。如果你搭建好了wordpress,記得開啟xmlrpc,然後設定一個專門用於釋出文章的使用者,在config.js中配置相應引數並將saveviewfile中的相關程式碼解除註釋。

6)由於知乎對頭像做了防盜鏈處理,我們在抓取使用者資訊時一併也將頭像獲取了下來,儲存在本地,釋出文章時使用的是本地頭像地址。需要在http伺服器中將url路徑指向儲存頭像的資料夾,或者將儲存頭像的資料夾直接放到網站目錄下。

7)程式碼可能不太容易讀懂。除了node.js的回撥結構本身就較混亂之外,還有一部分原因是最初寫程式時我剛剛開始接觸node.js,有很多不熟悉的地方導致結構混亂沒有來得及改正;另一部分是在多次縫縫補補中累加了許多醜陋的判斷條件和重試規則,如果全部去掉,程式碼量可能會下降三分之二。但這是沒有辦法的事,為了保障一個系統的穩定執行,必須加入這些。

8)本爬蟲原始碼基於WTFPL協議,不對修改和釋出做任何限制。


相關文章