標籤:資料 問題 re c linux 時間
最近一段時間主要重心在Amazon電商資料分析上,這是一個偏資料分析和可視化的項目。具體來說就是先擷取Amazon的商品資料,資料清洗和持久化儲存後作為我們自己的資料來源。分析模組和可視化模組基於資料進行一系列的操作。
顯然,整個項目中最基本,也是最重要的就是前期資料的擷取,本篇文章就是針對資料擷取和清洗過程進行一個簡單的介紹和總結。
整個項目我們採用了Python作為開發語言,其中可視化模組基於Django搭建,當然在資料擷取,即爬蟲模組,我們也是採用了Python作為我們的開發語言。
對於爬蟲模組,因為需求是確定的,並且爬取網站也是固定的——Amazon.com,因此在爬蟲模組主要需要考慮的是調度問題、頁面解析問題以及流程自動化的問題。
首先說明一下爬蟲的整體架構,一開始我們是採用單機器爬取,啟動方式也很簡單——命令列啟動,但這樣帶來的問題是顯著的,不穩定,需要手動啟動任務。之後我們將爬虫部署成服務,對於進入的任務,可能是使用者提交的,也可能是我們內部提交的,通過一個提交系統加入到服務隊列中,之後爬蟲服務檢測並啟動爬取任務。這樣一定程度上解決了不穩定的問題,但隨著資料增長,頻寬等因素凸顯出來,因此,我們又加入一些機器,構建一個小型的爬蟲叢集來分布式爬取。但這不算是真正意義上的分布式,並沒有節點
具體實現方面我們採用Python的一個開源爬蟲架構——Scrapy,該架構提供了基本的調度、頁面爬取等功能。我們需要做的是基於該架構設定DOM解析方案和後續資料的處理儲存方案,同時基於該架構搭建一個小型的偽分布式爬取系統。
下面來介紹一下我們在爬蟲設計過程需要考慮的幾個問題。
首先頁面解析問題,因為JS非同步載入的原因,爬蟲實際得到的頁面DOM元素和我們在瀏覽器中開啟頁面得到的DOM元素有點區別,這就不能完全依靠瀏覽器來定位具體的DOM元素。其次,在訪問達到一定次數,特別是並發訪問請求達到一定次數後,Amazon會對請求進行封殺,返回Robot Check頁面甚至是500 Server Error。針對這種情況,一種解決方案是減少並發請求的數目,根據我們實際測試發現,每秒鐘發送的請求如果超過50條會被Amazon返回500 Server Error(可能現在Amazon會不斷更新策略),因此我們設定了並發請求數為32,即一秒鐘一台機器發送32個請求。對於可能會有Robot Check的情況,這個我們還在探索階段,因為此類頁面出現較少且集中出現在商品資訊頁面,而該頁面由於資訊比較固定可以較長時間不更新。目前是加入Proxy作為下載中介軟體(DownloadMiddleware)。另外考慮到可能因為國內訪問過於頻繁的話也會導致此類問題的出現,我們目前正在將爬蟲遷移到Amazon EC2上,一來比較穩定,另外訪問也會比在國內機器上快點。
其次是調度問題。在單機器單任務的爬蟲中不存在這樣的問題。但是在多機器多任務中這是一個比較重要的問題,多個任務提交後怎麼進行調度,如果有優先順序的話是按照優先順序來,否則是預設放在任務隊列裡依次進行。在我們的爬蟲系統中,多台機器組成的爬蟲系統是由一個調度控制,當一個爬取任務提交後,調度將任務拆分並分發到不同的爬蟲機器上,在單個的爬蟲機器上,會有一個爬取隊列,隊列中是分發到該機器上的所有爬取子任務,在目前是預設從隊列中依次擷取任務,一台機器上能同時啟動六個爬取任務進行並行爬取。
最後是流程的自動化問題。在我們的系統中,需要實現任務提交後,在網站上直接看到處理後的資料以可視化圖表展現。這就需要將整個流程實現自動化,提交任務後開始爬取資料,爬取任務完成後對資料進行處理和歸併,產生一些統計資訊,最終得到正常化的資料並在前端可視化展示。這一系列過程主要分為兩個階段,爬取和處理,爬取階段任務提交分發後爬蟲會啟動爬取任務,在爬取完成後,利用Scrapy的介面實現了對爬取任務狀態的修改,例如對於一個任務T,啟動時在資料庫中加入狀態,{‘name’: T, ‘jobid’: ‘Task_id’, ‘status’: ‘running’},在爬取完成後,修改狀態為 finished,同時,會有定時指令碼輪詢看資料庫中各任務是否完成。如果完成的話,啟動資料處理的流程。資料處理完成後歸併資料到正式的項目資料庫中,完成資料的前端可視化展現。由於本項目部署在Linux伺服器上,因此就直接採用了linux下的cronjob來實現了指令碼的輪詢和執行。簡單來說,寫入幾個crontab後,啟動cronjob,這幾個指令碼串接了上述說的每個流程,使其成為完整的一套流程。
上述說的是資料爬取過程中的幾個主要問題,也是比較重要的問題,說實話,即便是現在的系統,仍然沒有完美解決這幾個問題,解析依然會遇到Amazon的封殺,自動化的魯棒性太弱等等。這可能是下一階段需要考慮的問題,同時,資料爬取儲存後依然有不少髒資料(Dirty Data),需要進一步的清洗。