學習爬蟲有一段時間了,期間接觸了很多相關的庫,不禁感慨Python就是強大,當你遇到任何問題的時候基本上都有前人造好的輪子,只要直接 import 就行了。在此把爬蟲相關的庫及方法做個簡單的總結,也歡迎大家做補充。
一、引言
爬蟲主要分為:網頁采集、網頁解析、數據存儲、數據分析這么幾步,每一步都有各自的難點。此外,為了提高爬蟲的效率,程序的運行還可采用多進程、多線程、協程和分布式這么幾種。目前流行的爬蟲框架有scrapy、pyspider等。以下對相關類庫做簡單介紹。
二、網頁采集
網頁采集算是爬蟲程序的核心了,因為在web技術飛速發展的今天,你面對的早已不再是一個不設防的靜態網頁的世界,取而代之的是一山更比一山高的反爬技術,處處使用ajax異步加載的網頁,筆者資歷尚淺,踩過的坑不多,在此就我使用過的一些庫做些簡單的介紹。
urllib模塊
urllib 是 Python 自帶的 web 模塊,包含了平常我們使用的大多數功能。
值得一提的是 urllib 在 Python2 和 Python3 中有所不同,在此就不細說了。
urllib2文檔? for python2.7
urllib文檔? for python3.6
requests模塊
requests是一個相對urllib而言更加人性化的模塊,它支持 HTTP 連接保持和連接池,支持使用 cookie 保持會話,支持文件上傳,支持自動確定響應內容的編碼,支持國際化的 URL 和 POST 數據自動編碼。
使用requests可以方便的對登錄的賬號使用session保持會話,此外還能自動解析gzip壓縮的網頁,十分強大。
selenium模塊
目前很多網頁都使用異步加載的技術,一般都是通過抓包,分析出異步加載的鏈接,然后在對加載的數據進行解析,但是對于很多加密的異步鏈接,可能就需要很大的功夫才能破解。selenium 模塊原來是用來做web測試的,它可以模擬不同瀏覽器,因此使用 selenium 模塊,配合不同瀏覽器的 driver,就相當于在瀏覽器中打開鏈接,并可以對 dom 進行操作,加載異步的數據。
selenium支持IE、firefox、chrome、opera等瀏覽器,但是使用這些瀏覽器時往往會打開一個瀏覽器窗口,因此爬蟲程序通常使用PhantomJS,它是一個基于WebKit的服務器端 JavaScriptAPI,相當于一個無界面瀏覽器。基于 selenium 和 PhantomJS 可以很簡單的加載異步數據并依此對網頁進行爬取。
三、網頁解析
網頁解析一般用的是 lxml 和 BeautifulSoup,當然BeautifulSoup也支持lxml解析。
lxml模塊
lxml,使用 xpath 語法,解析速度快是它的優點。
BeautifulSoup模塊
BeautifulSoup是一個功能強大的 HTML及XML解析模塊,支持Python標準庫中的HTML解析器,以及第三方的lxml解析器和html5lib解析器,功能強大而且語法人性化。
四、數據存儲
從網頁采集到數據后,常常需要將數據保存進行分析,對于少量的數據,可以用 json /excel進行保存,而對于大量的數據,則必須使用數據庫進行存儲,數據庫又分為兩大類 SQL數據庫和NoSQL數據庫。常用的SQL數據庫有:SQL Server、MySQL、Oracle等,常用的NoSQL數據庫有MongoDb、Redis等。相應的,python也提供了相應的模塊對數據庫進行操作。
json模塊
python使用自帶模塊 json, 對 json 數據進行操作。
xlwt模塊 及 xlrd模塊
xlwt 和 xlrd 都是 Python 操作excel文檔的模塊。
MySQLdb模塊
MySQLdb 是 MySQL的 Python 接口開發包。
PyMango模塊
PyMango 是 MongoDB 的 Python 接口開發包。
redis-py模塊
redis-py 是 redis 的 Python 接口開發包。
五、數據分析
數據分析是一個很大的范疇,涉及數據分析的模塊太多了,在此就不一一介紹了,簡單介紹幾個常用的模塊吧。
數值計算:NumPy和SciPy模塊
NumPy是Python的一種開源的數值計算擴展。這種工具可用來存儲和處理大型矩陣,比Python自身的嵌套列表(nested list structure)結構要高效的多。
scipy函數庫在NumPy庫的基礎上增加了眾多的數學、科學以及工程計算中常用的庫函數。例如線性代數、常微分方程數值求解、信號處理、圖像處理、稀疏矩陣等等。
自然語言分析:結巴分詞、NLTK模塊
結巴中文分詞是一個非常好用的中文分詞組件,經過分析,語料就可以直接投入NLTK進行分析了。
NLTK工具集是目前最流行的自然語言分析模塊
圖片處理:OpenCV、PIL、matplotlib模塊
OpenCV、PIL、pillow、matplotlib 都是python對圖片進行處理的模塊,無論是對爬取的圖片進行保存,還是對驗證碼進行識別,你難免都會用手它們,因為筆者使用較少,就不多介紹了。
六、效率提升
一般爬蟲程序耗時的過程都不是計算,大部分是在應對反爬(例如單IP一小時限制爬取次數)、網絡請求響應、數據庫IO上。而如何提升爬蟲的效率,無疑是后期一個爬蟲工程師所關注的重點,一般可以使用多進程、多線程、異步IO、分布式來優化爬蟲,各自方法有各自的優點和適用范圍。
多進程
要實現高并發,直接開多個任務分配給幾個進程當然是最簡單的方法,multiprocessing提供了Python對多進程的支持。
多線程
多進程開銷大,同樣也可以使用多線程對爬蟲程序進行改進,multiprocessing也提供了多線程的接口,此外還有thread和threading模塊,thread是低級模塊,threading是高級模塊,對thread進行了封裝。絕大多數情況下,我們只需要使用threading這個高級模塊。
協程及異步IO
其實對于網絡編程,多進程和多線程都不是特別好的解決方法,因為網絡請求是阻塞的,這也意味著一個任務,可能你要用90%的時間用來等待網絡請求的返回,如果能用等待網絡請求的時間進行后續操作,這將節省很多時間。于是就有了異步IO這種解決方案。加上Python3.5以后 async/await 等語法的加入,對異步的支持也越來越強大,所以相信以后異步的庫也會越來越多。
gevent
gevent為Python提供了比較完善的協程支持。gevent是第三方庫,通過greenlet實現協程,其基本思想是:當一個greenlet遇到IO操作時,比如訪問網絡,就自動切換到其他的greenlet,等到IO操作完成,再在適當的時候切換回來繼續執行。由于IO操作非常耗時,經常使程序處于等待狀態,有了gevent為我們自動切換協程,就保證總有greenlet在運行,而不是等待IO。
asyncio
asyncio作為一個python3.4引入的標準庫,提供了異步IO的解決方案,而且在python3.5、3.6兩個版本中都對asyncio增加了更多的支持,其功能也越來越強大。
aiohttp
我一直把aiohttp當成是異步版的requests庫,易用性強,加上對異步的支持,我覺得已經可以拋棄對python3支持不好的twisted庫了。
分布式
嚴格意義上說,分布式應該算是一種架構,其思想就是用一些機器作為master,一些機器作為slaver,master分配任務給slaver,這樣就實現了爬蟲在不同機器上分別進行,提高效率。分布式最強大的地方在于,它能最有效突破IP的限制,這是前幾種爬蟲很難達到的(當然,你可以說用代理池,我認為代理池也可以算是分布式的一種特例)。
筆者用的最多是用redis數據庫作為任務的分配中心,因為redis操作具有原子性,而且redis基于內存,訪問速度極快。
七、爬蟲框架
目前應用較多的爬蟲框架有Scrapy、pyspider,其中,每個框架還有各自的擴展。
scrapy
Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架,相信寫過爬蟲的沒有不知道它的。值得一提的是,scrapy是基于twisted異步框架實現的,也就是說,scrapy本身是異步IO的。
因為 scrapy 的強大,很多開發者對 scrapy 進行了擴展,常用的有:scrapy-redis、scrapy-splash
scrapy-redis
scrapy-redis是基于scrapy 和 redis 實現的分布式爬蟲拓展
scrapy-splash
splash與phantomjs類似,是基于Twisted和QT開發的輕量瀏覽器引擎,scrapy-splash 對異步加載網頁提供了高效的支持
pyspider
一個國人編寫的強大的網絡爬蟲系統并帶有強大的WebUI。采用Python語言編寫,分布式架構,支持多種數據庫后端,強大的WebUI支持腳本編輯器,任務監視器,項目管理器以及結果查看器。