注:先解釋義,網路爬蟲指的是按照一定的規則,自動抓取全球資訊網資訊的程式或者指令碼。
要抓取微信公眾號文章,第一件事就是去找介面,之前都是在 Web 站點上去找。Chrome 的除錯工具,能夠很清晰地看到所有的網路請求,簡單的分析,就能找到對應的 API ,但是在移動端,這件事情顯然就變得複雜了很多。
Android 抓包
對於許多從事移動開發的朋友們來說,抓包是一個常用需求,在這裡,筆者簡要介紹一下基本步驟:
在你的個人電腦上安裝抓包軟體,推薦 Charles 和 Fiddler ,使用 Mac 的朋友建議使用 Charles ,使用 Windows 的朋友建議使用 Fiddler;將手機與電腦連線在同一個區域網中;在手機的 Wi-Fi 設定裡面,手動設定代理,使用你的個人電腦代理手機的網路請求;代理請求,抓取 HTTPS。眾所周知,HTTP 是進行明文傳輸的,可以很方便地看到上行與下行的資料。但是 HTTPS 使用的是加密傳輸,要看到上行與下行的資料,我們得事先知道通訊的密碼,才能解密看到真實內容。
為了解決這個問題,抓包工具會作為一箇中間代理人,手機端與抓包工具進行通訊,抓包工具再與服務端進行通訊。手機端與抓包工具建立 HTTPS 請求使用的公鑰是抓包工具下發給他的。所以,為了能正常通訊,需要安裝抓包工具生成的根證書。
現在,我們很輕鬆地就把 CSDN 好幾年的文章爬了下來。但是要想拿到文章的閱讀、點贊數,還需要去分析獲取這兩個資料的請求。經過仔細的分析,單從介面上來說,是可以獲取到閱讀、點贊數,但是獲取這兩項資料的請求,是微信客戶端發的,上行引數中進行了簽名和文章唯一 ID 的生成,找不到對應的生成演算法。所以,此路不通。
為了能拿到這兩項資料,網路上有一種方式的實現,使用的是 AnyProxy + MonkeyRunner ,筆者也是採用與之類似的方式:
AnyProxy + ADB Shell
AnyProxy 是一個基於 Node.js 的,可供外掛配置的 HTTP/HTTPS 代理伺服器。和上面提到的 Charles 、 Fiddler 類似,但更加適合開發者使用。
筆者使用 ADB Shell 中的命令,來模擬點選,以自動化的形式開啟微信公眾號中的文章。然後在啟動 AnyProxy ,使用它提供的外掛配置的功能,拿到評論的資料,並寫入資料庫中。
varurl = require( "url")
module.exports = {
*beforeSendResponse(requestDetail, responseDetail)
{
try{
varpathName = url.parse(requestDetail.url).pathname
if(pathName == "/mp/getappmsgext") {
saveReadCount(requestDetail, responseDetail)
}
} catch(err) {
console.log( "err")
}
}
};
資料清洗與整理
在前面拿到的文章列表與點贊和評論資料中,儲存的都是網路請求的詳細資料,我們需要將所需的資料從原始資料中清洗出來,並將點贊數與請論數與文章關聯起來。
讀取文章列表原始資料,並解析資料。邏輯很簡單,程式碼如下:
definsertInto(cursor, msg):
list = json.loads(msg)[ "list"]
forlistItem inlist:
ifnotlistItem.has_key( "app_msg_ext_info"):
continue
commMsgInfo = listItem[ "comm_msg_info"]
appMsg = listItem[ "app_msg_ext_info"]
addAppMsg(cursor, commMsgInfo, appMsg)
ifappMsg.has_key( "multi_app_msg_item_list"):
subAppMsg = appMsg[ "multi_app_msg_item_list"]
forsubAppItem insubAppMsg:
addAppMsg(cursor, commMsgInfo, subAppItem)
defgetCount(articId):
conn = sqlite3.connect( "wechat_read_cont.db")
conn.text_factory = str
cursor = conn.cursor()
articId = articId.replace( "=", "%3D")
selectSql = "select responseBody from read_cont where url = ""+ articId + """
cursor.execute(selectSql)
values = cursor.fetchall()
iflen(values) <= 0:
return"-1", "-1"
data = values[ 0]
appmsgstat = json.loads(data[ 0])[ "appmsgstat"]
conn.close()
returnappmsgstat[ "read_num"], appmsgstat[ "like_num"]
資料分析
經過前面一系列的處理,我們需要的資料已經存入了資料庫表中去了。經過艱難的爬取,資料終於到手,先來膜拜一下 10W+文章:
因為是在控制檯直接列印為了更好的格式化展示資料,使用了prettytable , 資料處理的程式碼如下:
defgetArticInfos(min, max):
conn = sqlite3.connect( 'wechat.db')
conn.text_factory = str
cursor = conn.cursor()
cursor.execute( "select title, author, datetime, readCount from messages")
values = cursor.fetchall()
table = PrettyTable([ "Title", "Author", "Time", "Read Count"])
table.align[ "Title"] = "l"
table.align[ "Author"] = "l"
table.padding_width = 1
totalCount = 0
foritem invalues:
readCount = int(item[ 3], 10)
ifreadCount >= min andreadCount < max:
table.add_row([str(item[ 0]), str(item[ 1]), str(item[ 2]), str(item[ 3])])
totalCount += 1
printtable
print"Total Count:"+ str(totalCount)
conn.close()
if__name__ == '__main__':
getArticInfos( 100001, 100002)
聽小道訊息說,CSDN 是 2017 年下半年才著重開始運營公眾號,恰巧,爬取的資料有 CSDN 全量文章資料,總計 6000 篇,所以我們可以對比看看 CSDN 公眾號產出的文章數量:
歷年文章數量
從上圖可以看出,2018 年 CSDN 公眾號差不多產出 2000 篇文章,平均每天產出至少 6 篇文章。不得不說,一個專業的技術媒體,他的實力是不容小看的。當然,CSDN 的編輯大大們,也辛苦了。感謝你們為我們貢獻了如此多的知識內容。
回過頭來,再來看一下從 2017 年到 2018 年,資料的增長趨勢是什麼樣子的。如下圖:
每月發表文章數
從上圖可以看到從 2017 年 9 月份開始,文章總數開始增加,甚至出現直接翻倍的情況,說明 CSDN 開始投入人力資源運營公眾號,2018 年春節,文章數量略有減少,年後文章數量開始增多,最多的時候,一個月產出了 236 篇文章,真是佩服得五體投地。
2018 年都已經結束,CSDN 都發表了 2000 篇左右的文章。這些文章都有些什麼內容?拿到標題,使用“Jieba”分詞,製作詞雲圖,如下圖所示:
詞雲
我們可以明確地看到,隨著 AlphaGo 橫空出世,機器學習、人工智慧在技術領域崛起,未來已來深入人心。機器學習讓 Python 這門程式語言在更多的開發者面前展現出來,從圖中也可以看到,Python 在 CSDN 的文章中出現頻率也非常高,CSDN 深度為千萬開發者解析,想開發者所想,手動為他們點贊。
不僅如此,不管是正面的科技大佬 "馬雲"、“馬化騰”,還是負面的科技大佬“賈躍亭”等都頻繁地出現在我們的視野中,CSDN 的小姐姐們也在第一時間為我們提供科技界的新聞趣事。
2019 年剛剛開始。準備好迎接新的一年了嗎?沒準備好也沒關係,反正 2019 年都會來的。
最後為所有小夥伴們送上一句至理名言:
我 2019 年的目標就是搞定 2018 年那些原定於 2017 年完成的安排,不為別的,只為兌現我 2016 年時要完成的 2015 年年度計劃的諾言。
One more thing..
《瘋狂Python》
從零開始,Python 程式設計從入門到實踐一網打盡。網路爬蟲、大資料分析與展現、併發程式設計等一個不漏。
《Redis 深度歷險:核心原理與應用實踐》
本書作者老錢在使用 Redis 上積累了豐富的實戰經驗,可以幫助更多後端開發者更快、更深入地掌握 Redis 技能,還能幫助讀者更輕鬆地通過技術面試,進入心儀企業。
《Netty進階之路:跟著案例學Netty》
Netty 將Java NIO 介面封裝,提供了全非同步程式設計方式,是各大 Java 專案的網路應用開發必備神器。
本書作者是國內 Netty 技術的先行者和佈道者,本書是他繼《Netty木又威指南》之後的又一力作。
《你也能看得懂的Python演算法書》
本書面向演算法初學者,首先介紹當下流行的程式語言 Python,詳細講解 Python 語言中的變數和循序、分支、迴圈三大結構,以及列表和函式的使用,為之後學習演算法打好基礎。
然後以通俗易懂的語言講解雙指標、雜湊、深度優先、廣度優先、回溯、貪心、動態規劃和至短路徑等經典演算法。
《智慧問答與深度學習》
本書由淺入深地介紹了人工智慧在文字任務中的應用。不但介紹了自然語言處理、深度學習和機器閱讀理解等基礎知識,還簡述了資訊理論、人工智慧等的發展過程。