天天看點

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

Azure存儲隊列是個好東西,阿裡雲對象存儲和CDN也是個好東西,.NET更是個好東西,一起拿來做點東西玩玩

【初碼文章推薦】

程式員的自我修養

Azure系列文章

阿裡雲系列文章

爬蟲系列文章

【初碼産品推薦】

AlphaMS開發模式

閃送達城市中央廚房

今天帶來一個有意思的東西-分布式B站爬蟲任務系統

這個小玩意源于上周在研究Azure的時候,發現雲服務廠商都在推薦輕量級的存儲隊列服務,用來取代原有的比較重的消息隊列服務,具體來說,比如阿裡雲就推薦使用消息服務替代消息隊列,在Azure中,就有一個輕量級的存儲隊列(Storage Queue)可以替代服務總線(Service Bus),簡單試用了一下Azure的Storage Queue後,發現這玩意很好用,于是決定全面的深入研究一下,再将公司電商系統内的相關任務處理均重構成使用存儲隊列服務,而深入研究得找個案例呀,于是就想到了做個分布式爬蟲,此類應用會出現大量的任務場景,而正好前段時間下載下傳B站視訊時,找到一個網站,叫唧唧下載下傳(搞二次元的都是色情狂嗎?),但又不太好用,于是決定就做個比較全面的B站視訊爬蟲。一方面可以友善的下載下傳視訊,另一方面還可以當做公司開發人員的教學案例

老規矩,還是先看下最終的使用效果,應用入口:https://www.alphams.cn/LT,(為了防止濫用下載下傳以及記錄下載下傳,是以還麻煩注冊一下啦)

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

輸入視訊番号,點選下載下傳,就進入任務界面

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

任務界面可以看到視訊資訊,實時下載下傳資訊,和錯誤資訊

任務處理完成後,點選立即下載下傳,從一個CDN加速的位址得到了視訊

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

那麼下面就把本次的開發和實施流水賬記錄一下

1、首先是準備工作和可行性調研

想要對B站進行爬蟲,首先要準備好技術手段和相關工具,對B站的網站結構和資料流向進行一些分析,進行可行性的調研

首先打開B站任意一個視訊,可以看到位址都是這樣的格式

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

于是我們把AV後面的号碼叫做番号(此番号非老司機番号)

而有些視訊不止一段,如果是第二段視訊,則是這個位址:

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

而如果把Index後面的2換成1,也可以達到和第一個位址一樣的效果

然後用Fidder工具,分析一下網頁,可以看到有如下一些資源

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

剔除基本的JS檔案、CSS檔案、圖像檔案後,剩下來的就是一些有用的資訊了,而在有用的資訊中最終篩選出如下幾個資訊

1、AID是視訊的番号,也就是網址URL後面的那串唯一數字

2、CID是彈幕的番号,每個視訊AID會對應一個CID

3、彈幕的資訊存儲在了這樣的URL中:http://comment.bilibili.com/15075110.xml

4、視訊的資訊存儲在了這樣的URL中:https://interface.bilibili.com/playurl?cid=15075110&appkey=84956560bc028eb7&otype=json&type=&quality=3&sign=c070bfd93a84cab542e7c874add6839e

因為本次主要是下載下傳視訊,是以就着重看一下視訊存儲的資訊,打開上面的URL後發現了最終視訊的位址

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

太好了,一下子就給了視訊尺寸和視訊最終的下載下傳位址,那麼我們用浏覽器打開一下這個URL看一下,可以成功下載下傳!

注:以上相關分析實際上是經過了1-2個小時的反複嘗試和模拟得出的,有2個細節補充一下,1、B站的伺服器會根據HTTP頭資訊的不同傳回FLV格式或者MP4格式,2、B站的視訊可能用了不同廠商的CDN服務,有些視訊位址無法直接下載下傳,會判斷refer資訊和浏覽器資訊)

接下來繼續分析,注意看這個URL可以發現,尾部有一個sign,說明做了用戶端和服務端的簽名驗證,并不是很傻瓜的有直接通過AID或者CID關聯的下載下傳位址,分析進入到這一步後,我很快的就打了自己的臉,我曾在文章《關于.NET玩爬蟲這些事》中說過,一切網站行為都可以分析出HTTP+Javascript來,隻要分析得當,根本不需要用浏覽器來進行爬蟲模拟,但這尼瑪B站鬼的Web結構(忍不住想罵人,典型的垃圾Python、PHP向的開發人員做出來的鬼東西,代碼邏輯混亂、随便一看就是到處修補修改的痕迹,生成出來的HTML、JS的邏輯和層次毫無美感),看了2個小時,眼睛都看疼了,楞是沒分析出簽名方法,也許再看看會有結果,但是我等不及了,是以這時候祭出爬蟲神器-無頭浏覽器

這裡我選擇了PhantomJS這個無頭浏覽器,具體的使用過程就不詳述了,有興趣可以到官網了解一下,寫了如下分析代碼

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

通過代碼我們可以很清楚的看到,主要是兩個目的,輸出包含interface.bilibili.com的URL以及本次視訊的标題

測試一下,确實可以得到URL和标題,這裡有個要注意的是,B站預設是GB2312編碼,是以PhantomJS要加一個參數,就是輸出編碼改為GB2312

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

到此為止,可以說完成了整個爬蟲部分的調研,至少是有完整的可行性了。

2、然後進行業務功能的設計

有了可行性後,就可以天馬行空的進行業務功能的設計了,既然上面說到那個雞雞網站特别不好用,那麼我們就來重新設計一下這個爬蟲的功能

一、使用者端功能

1、使用者可以輸入視訊番号和序号送出視訊下載下傳(注:幹淨清爽的送出界面)

最終界面如下:

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

2、使用者可以在送出視訊下載下傳後,可以看到實時的處理進度,并且能夠看到自己以前送出的任務(注:需要設計任務機制,做好狀态控制,這裡采用Azure的存儲隊列)

最終界面如下

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

3、使用者最終的下載下傳速度特别快(注:使用CDN和網絡存儲技術,這裡采用阿裡雲的CDN和OSS)

最終效果如下:

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

4、下載下傳進度能夠通過郵件進行視訊資訊的推送(注:使用郵件模闆技術,詳見:《使用阿裡雲郵件推送服務架設自己郵件驗證與推送體系》,這裡采用SendCloud雲服務)

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

二、服務端功能

1、考慮到B站CDN可能會限制IP位址使用,需要使用分布式的爬蟲設計(注:這裡使用Windows Console Application程式)

2、增加下載下傳效率,使用多線程技術(注:因為使用.NET做爬蟲,多線程控制還算比較穩定和齊全)

3、對無頭浏覽器進行精準的控制(注:這裡是Windows環境,考慮使用.NET裡面的Process類進行控制)

有了業務功能做指導,下面就可以進行完整的系統設計了

3、系統設計與技術細節

老規矩,先放出整體設計圖

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

其中具體的技術細節和代碼如下:

一、分布式架構的核心

1、分布式Win32控制台程式需要有賬号體系,這樣可以進行節點的實施狀态管理和記錄

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施
【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

2、任務的新增、擷取、核銷等,需要精準的控制,不能出現并發沖突,是以這裡使用了消息隊列,也就是上面所說的Azure存儲隊列服務

任務的新增和配置設定主要代碼如下:

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施
【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

3、豐富的日志和錯誤處理機制

因為會一直執行,分布式節點的穩定性非常重要,Windows Console Application程式本身是非常穩定,是以在具體的代碼裡面,記憶體控制與對象釋放、死循環的避免、多線程優化、異常的捕捉和處理等都非常重要,這裡不一一洗漱,都是開發的基本功,做類似的應用的話,大家也需要多注意。另外因為無頭浏覽器的執行,是放在分布式的用戶端裡面進行的,是以也需要對無頭浏覽器進行精準控制,下面會詳細說到

二、爬蟲任務的資料結構

本案例中由于隻對單一URL進行分析和爬蟲,業務邏輯并不複雜,考慮到需要支援進度查詢、狀态控制等,資料結構設計如下,就2個表

1、爬蟲任務表(記錄爬蟲任務,控制狀态、記錄過程參數等)

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

2、視訊存儲表

任務完成後,就把CDN加速好的視訊資訊存儲下來,一方面進行備援查詢,另一方面也用于其他使用者下載下傳可以秒下

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

三、無頭浏覽器的精準控制

1、.NET裡面的Process類

上面提到了,無頭浏覽器畢竟有一個浏覽器核心的執行,而在任務處理的高峰,可能會不斷的調用、銷毀這個浏覽器,而Web行為又是非常不穩定的,是以想要分布式的穩定,就一定要進行無頭浏覽器的精準控制。這裡用到了.NET裡面Process來控制無頭浏覽器的執行,主要的技術點有:

不顯示指令視窗,重定向輸入輸出

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

監聽資料接收

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

這裡可以看到,我們之前在PhantomJS裡面寫的JS代碼,主要就輸出了兩點,一個是包含下載下傳位址JSON資料的URL位址,另一個是視訊的标題,這裡都做了記錄

差錯處理以及任務的關閉和結束

【初碼幹貨】記一次分布式B站爬蟲任務系統的完整設計和實施

2、重試的機制

實測中發現,無頭浏覽器的失敗率和出錯率還是挺高的,是以在資料結構設計的時候,就預留了重試機制,當分布式用戶端處理視訊失敗時,服務端重新送出消息隊列,超過一定的次數再宣告任務失敗

三、CDN的加速處理

1、之前在這篇文章《使用阿裡雲對Web開發中的資源檔案進行CDN加速的深入研究和實踐》中,提出了一種非常好的資源管理和加速方式,核心思路包括三點

檔案資源的資訊管理和目錄結構在本地資料表中,GUID化

檔案的資料存儲在阿裡雲OSS中,無目錄結構的扁平化記錄

對OSS綁定域名,對CDN服務也綁定域名

回報給用戶端的檔案資訊,直接使用CDN位址,進而回源到OSS中或者直接命中緩存

2、同樣的,在本次案例中,也使用了這樣的處理方式,最終給使用者的下載下傳位址是CDN下載下傳位址,具體的處理流程可以看上面的設計圖,應該能一目了然

3、關于對上傳到OSS的處理

在最初的設計方案中,分布式用戶端完全下載下傳到視訊檔案的内容後,是上傳到服務端,由服務端統一進行上傳,後來評估這樣的方式,對服務端的壓力和帶寬占用都明顯提升了,既然是分布式系統,應當充分利用分布式用戶端的資源,是以改為分布式用戶端直接上傳檔案到阿裡雲OSS中,這樣做唯一的弊端是分布式用戶端會擷取明文的阿裡雲管理密鑰,于是又加入了阿裡雲RAM權限管理,加入了OSS子權限的控制,問題就迎刃而解了。

四、郵件推送的處理

在上面的功能設計中,加入了郵件推送的功能,詳細的設計思路參見這篇文章《使用阿裡雲郵件推送服務架設自己郵件驗證與推送體系》,郵件模闆就是HTML代碼,這裡就不多說了,但有一個小插曲,就是阿裡雲的郵件推送服務,實在是太爛了,特别是QQ郵箱的到達率奇差無比,是以最終的實施部分換成了搜狐的SendCloud解決方案。

好啦,整個實施到這裡基本上就差不多了,老規矩,還是要總結和思考一下:

1、技術改進。因為整個程式就做了2天不到,很多技術細節點并未很到位,還有大量可以改進的地方: 比如對于PhantomJS更多細節參數的研究,是不是可以提升效率,是不是可以減少出錯率 又比如任務表的設計,耦合的地方還是很多,應該還可以優化設計 又比如在使用者界面上,沒有做太多H5的美工,應該還可以加強一下 又比如分布式用戶端Windows Console Application是不是可以強化為Windows Service,并且加入監控和守護程序 又比如經過研究發現,B站用了大廠商(藍汛)的CDN服務,非常智能,在快速的加載30%以後就進行限速,那麼對于這樣的瓶頸的處理是不是還可以更細緻一些 這些工作在後續我會慢慢完善 2、功能改進。今天隻是為了測試存儲隊列的這個服務,是以簡單的進行了B站視訊的爬蟲,事實上還有很多後續功能可以拓展 比如加入微信掃碼就可以在微信上下載下傳視訊、觀看視訊 比如可以綁定微信公衆号,在微信公衆号上也可以視訊番号發起下載下傳,并通過微信模闆消息推送處理結果 比如可以加入對彈幕的處理 比如可以加入一些經營性的功能,例如廣告、收費高速下載下傳、加入存儲廣告站的下載下傳位址等等 3、其他思考 還是老生常談的話題,堅決的反對前端向開發人員進行大型系統的架構,做出來除了垃圾就是垃圾 目前個人資訊的保護是非常嚴格的,如果下載下傳并存儲電影和綜藝節目,一定是非法的甚至觸犯刑法,而這種個人釋出的視訊的爬蟲下載下傳,不知道上傳時有沒有和B站簽署版權協定或者電子協定,如果是直接下載下傳位址給到使用者還好,但在本案例中,加入了中轉存儲,那麼這樣的行為,是不是涉嫌違法呢?我認為暫時法律風險不大,但從長遠看,不太合适!

作者:張柔,釋出于  部落格園  與  張柔的部落格

轉載請注明出處,歡迎郵件交流:[email protected],或者加QQ群:11444444

繼續閱讀