用python做網頁抓取與解析入門筆記[zz]


(from http://chentingpc.me/article/?id=961)

 

事情的起因是,我做survey的時候搜到了這兩本書:Computational Social Network AnalysisComputational Social Network,感覺都蠻不錯的,想下載下來看看,但是點開網頁發現這個只能分章節下載,暈,我可沒時間一章一章下載,想起了迅雷的下載全部鏈接,試試看,果真可以把他們一網打盡,但是,sadly,迅雷下載的時候,文件名沒辦法跟章節名對應起來,暈,我可沒時間一章一章去改名字,怎么辦呢?由於做過網站,我看着它那“整潔”的頁面就笑了,因為這種規整的頁面是有規律可循的,雖然下載PDF的每個鏈接都含有用HASH隨機生成的數字碼,但是HTML+CSS的排版是規整的,就可以用正則等方法來把title和PDF都挖出來並且一一對應上。想到下一步是要用到網頁分析、抓取、下載的技術的,所以,今天就把這個技術給拿下吧。由於python似乎是我知道的這方面的“利器”,有比較好的原生和社區支持,簡單明了以及良好的跨平台性,所以就用python來做這個工作了。

S1.目標

  1. 抓取一個網頁並分析,從而:
    • 得到半結構化數據,如抓取新浪微博一個頁面中的內容。
    • 得到其他網頁的指針,如抓取新浪微博中下一個頁面。
    • 下載文件,如這次要下載PDF的任務。
  2. 多線程抓取與分布式抓取。
  3. 自動密鑰破解。

S2.方法概述

有多少種方法可以用的呢?

1.自己寫

urllib2+urlparse+re

最原始的辦法,其中urllib2是python的web庫、urlparse能處理url、re是正則庫,這種方法寫起來比較繁瑣,但也比較“實在”,具體可以參考[4].

urllib2+beautifulsoup

這里的得力干將是beautifulsoup[5],beautifulsoup可以非常有效的解析HTML頁面,就可以免去自己用re去寫繁瑣的正則等。我比較喜歡這種方法,在下面具體講解部分會詳解。

Mechanize+BeautifulSoup

Mechanize是對於urllib2的部分功能的替換,使得除了http以外其他任何連接也都能被打開,也更加動態可配置,具體參考[6].

PycURL,據說速度非常快,具體方法可以參考[1][2].

2.公開庫

Scrapy

這個暫且未嘗試,這種公開的庫的有點應該就是速度快、更強大,好像是可以並行的,所以以后有時間再嘗試下。

其他更多的開源庫參考[3].

S3.具體講解

假設你已經把python安裝好了(我用的版本是python2.7),現在我們用urllib2+BeautifulSoup的方法來抓取springerlink網站上的Computational Social Network Analysis和Computational Social Network,也就是上面提到的,這兩本書。

BeautifulSoup的安裝,我是在Windows下安裝的,官網上沒有window下安裝的教程,我是憑感覺裝上的。它有一個setup.py,我就用"python.exe setup.py install"運行了,但提示"error: package directory 'bs4' does not exist",原來是默認python執行路徑不在當前目錄,而是在C盤下面的用戶目錄中,所以把bs4文件移動過去就好了。跑完好,生成一個build文件夾,我知道它肯定要放到Python文件下的LIB文件夾里面去,所以就把下面的bs4移到LIB中去,就可以了。以后要用,直接import即可。如果是linux用戶裝起來應該會更順利些。

用urllib2抓取網頁/下載文件,urllib中最關鍵的可能就是urlopen這個函數了,返回的就是這個webpage/文件對象,可以用read等方法將其讀出來。urlopen這個函數的參數可以是url也可以是Request,如下:

 

req = urllib2.Request(url, headers={'User-Agent' : "Magic Browser"})

webpage= urllib2.urlopen(req)

webpage.read()...

 

這里要注意的一點是headers={‘User-Agent’:'Magic Browser'},這個最好加上,否則的話,由於內部信息默認顯示為機器代理,可能被服務器403 Forbidden拒絕訪問,在抓取springelink.com上數據的時候不加上一定會被403斃掉的。

用BeautifulSoup處理解析網頁,import后,一切從soup = BeautifulSoup(webpage.read( ))開始,你可以用python的終端自己玩玩這個產生的soup對象。我這里就說下一種我比較喜歡的用法,詳細具體的API參考[9].我喜歡用嵌套的方式來提取內容,什么意思呢,其實我認為大多數解析定位問題,其實就是下面這樣一個問題:

假設有一個頁面如下:

並且你已經用soup = BeautifulSoup()初始過了,現在你要根據<div id="a"> -> <div class='aa'> -> <p>這樣的結構把下面所有的鏈接抽取出來,怎么做呢?比較簡單的做法,就是一層一層向下分析,具體如下:

 

top_div = soup.find('div', {'id':'a'}) #注意:返回的是list對象

aa_div = top_div.findAll('div', {'class':'aa'}) #同樣是list對象

links = [div.findAll('a') for div in aa_div] #還是list對象

links[0].get('href') ##

links[0].contents #ff

 

除了鏈接以外,其他內容也是通過類似的方法解析得到。(PS,我發現我若干個小時前自己還沒解決這個問題的時候在SO上發的一個問題已經有人回答了,真好,那時候其實是困在了對list對象直接用find_all出錯)

S4.Ending

好吧,最后看看我們的戰利品:

聲明1,其實有一個2M多的文件下載失敗了,今天網絡確實有點慢,其實用chrome下載它也差點失敗了,因此,其實還是有可改進的地方。當然,可改進地方多了,多線程啥的,暫不討論了。

聲明2,由於是用T學校的網來下的,並且沒有復制擴散內容,所以沒有侵權!

最后感嘆下,最近多以看論文為主,好久沒學“技術”了,今天用了一些時間搞搞這種敏捷學習,重新體驗那種多線程、開N個窗口、各種任務並發的感覺,真舒服,哈哈:-D

Reference

[1] http://stackoverflow.com/questions/419235/anyone-know-of-a-good-python-based-web-crawler-that-i-could-use#answer-8310728

[2] http://pycurl.sourceforge.net/

[3] http://en.wikipedia.org/wiki/Web_crawler#Open-source_crawlers

[4] http://ryanmerl.com/2009/02/14/python-web-crawler-in-less-than-50-lines/

[5] http://www.crummy.com/software/BeautifulSoup/

[6] http://wwwsearch.sourceforge.net/mechanize/

[7] http://scrapy.org/

[8] https://github.com/scrapy/dirbot

[9] http://www.crummy.com/software/BeautifulSoup/bs4/doc/

源代碼下載:code

(from http://chentingpc.me/article/?id=961)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM