使用python抓取網頁

來源:互聯網
上載者:User

 

使用python抓取網頁(以人人網新鮮事和團購網資訊為例)

from http://www.pinkyway.info/2010/12/19/fetch-webpage-by-python/?replytocom=448

by 穎風斯特 

 BeautifulSoup, Python, urllib, 人人網, 團購 12 Comments

前一段時間寫的小東西,一直沒工夫把他系統寫出來,今天眼睛疼,就寫寫吧~~(原來博主不蛋疼時也會更新部落格的哈~)

python抓取網頁基礎

python自己帶有很多網路應用相關的模組,如:ftplib用於FTP相關操作,smtplib和poplib用於收發電子郵件等等,利用這些
模組自己寫一個FTP軟體或是郵件用戶端類軟體完全是可能的,我就簡單的試過完全用python指令碼收發郵件和操作自己的FTP伺服器。當然,這都不是今
天的主角,我們今天要用到的幾個模組是:urllib,urllib2,cookielib,BeautifulSoup,我們先來簡單介紹下。
urllib和urllib2自然都是處理URL相關的操作,urllib可以從指定的URL下載檔案,或是對一些字串進行編碼解碼以使他們成為特定的
URL串,而urllib2則比urllib更2一點,哦不對,是更牛逼一點。它有各種各樣的Handler啊,Processor啊可以處理更複雜的問
題,比如網路認證,使用Proxy 伺服器,使用cookie等等。第三個cookielib,顧名思義,專門處理cookie相關的操作,其他的我也沒深入過。
而最後一個包,BeautifulSoup,“美麗的湯”,它是一個第三方的包,專門用於解析HTML和XML檔案,使用非常之傻瓜,我們就要靠它來解析
網頁原始碼了,可以從這裡下載,當然你也可以用easy_install安裝它,這裡還有它的中文使用文檔,有多例子是相當不錯的。

我們先來看看最簡單的網頁抓取,其實網頁抓取就是將所要的網頁原始碼檔案下載下來,然後對其分析以提取對自己有用的資訊。最簡單的抓取用一句話就可以搞定:

12 import urllib html_src = urllib.urlopen('http://www.baidu.com').read()

這樣就會列印出百度首頁的HTML源碼了,還是很easy的。urllib的urlopen函數會返回一個“類檔案”對象,所以直接調用
read()即可擷取裡面的內容了。但是這樣列印得到的內容是一團糟,排版不好看,編碼問題也沒解決,所以是看不到中文字元的。這就需要我們的
BeautifulSoup包了,我們可以使用上面得到的原始碼字串html_src來初始化一個BeautifulSoup對象:

12 from BeautifulSoup import BeautifulSoup parser = BeautifulSoup(html_src)

這樣,後續處理HTML源碼的工作交給parser變數來負責就好,我們可以簡單的調用parser的prettify函數來相對美觀的顯示源碼,
可以看到這樣就能看到中文字元了,因為BeautifulSoup能自動處理字元問題,並將返回結果都轉化為Unicode編碼格式。另
外,BeautifulSoup還能迅速定位到滿足條件的指定標籤,後面我們會用到~

 

抓取人人網的新鮮事

前面講的是最簡單的抓取情形了,但通常我們需要面對更複雜的情形,拿人人網來說,需要登入自己的帳號才能顯示新鮮事,這樣我們就只能求助於更2一點
的urllib2模組了。試想,我們需要一個opener來開啟你的人人網首頁,而為了進入首先就需要認證,而這個登入認證需要cookie的支援,那我
們就需要在這個opener之上搭建一個處理cookie的Handler:

1234 import urllib,urllib2,cookielib from BeautifulSoup import BeautifulSoup myCookie = urllib2.HTTPCookieProcessor(cookielib.CookieJar()); opener = urllib2.build_opener(myCookie)

首先import我們需要的所有模組,然後使用urllib2模組的HTTPCookieProcessor搭建一個處理cookie的
Handler,傳入cookielib模組的CookieJar函數作為參數,這個這個函數處理HTTP的cookie,簡單地說,它從HTTP請求中
提取cookie,然後將其返回給HTTP響應。然後利用urllib2的build_opener來建立我們需要的opener,這個opener已經
滿足我們處理cookie的要求了。

那麼這個Handler怎麼工作呢,前面說了,它需要捕捉到HTTP請求才行,也就是說,我們需要知道,登入人人的時候發了什麼資料包出去,牛逼的
人可以使用各種命令列抓包工具如Tcpdump一類的,我等小民還是圖形化的吧。這裡我們藉助於Firefox的HttpFox來實現,可以從這裡添 加這個牛逼的外掛程式。安裝好該外掛程式以後,我們用Firefox登入人人網,然後輸入自己的帳號和密碼,然後,別急,不要按登入按鈕,從狀態列開啟
HttpFox外掛程式,點擊Start按鈕開始抓包,然後點擊人人網的登陸,登陸過程完成後點擊HttpFox的Stop停止抓包,如果一切正常的話應該可
以看到如下資訊了。


我們可以看到登陸人人的過程中瀏覽器向人人的伺服器發送POST請求資料,有四項,其中兩項是你的帳號和密碼。下面我們就利用代碼類比發出同樣的請求就可以啦。

123456789 post_data = {     'email':'xxxxx',     'password':'xxxxx',     'origURL':'http://www.renren.com/Home.do',     'domain':'renren.com'} req = urllib2.Request('http://www.renren.com/PLogin.do', urllib.urlencode(post_data)) html_src = openner.open(req).read() parser = BeautifulSoup(html_src)

首先,構造一個字典來儲存我們剛才抓到的POST資料,然後通過urllib2的Request類來自己構造一個“請求”對象,請求的遞交網址就是
上面捕捉的POST請求的URL部分,後面跟著我們的POST資料,注意,這裡需要使用urllib的urlencode方法重新編碼,以使其成為合法的
URL串。下面的過程就跟前面提到的簡單抓取過程一樣,只不過這裡開啟的不是簡單的網址,而是將網址和POST資料封裝後的Request請求,同樣,我
們將源碼賦給BeautifulSoup以便後面處理。

現在我們的parser裡儲存的就是含有好友新鮮事的網頁源碼了,我們怎樣提取有用的資訊呢?分析網頁這種粗活還是交給Firefox的FireBug(這裡下載)來玩吧。登入你的人人網,隨意右擊一下新鮮事裡某個人的狀態,選擇“查看元素”,就會蹦出如下視窗,顯示出你所點擊的部分對應的源碼:

我們可以看到,每個新鮮事對應著article標籤,我們再仔細看看article標籤的詳細內容:

裡面的h3標籤包含了好友的姓名和狀態,當然,還有一些肥豬流的表情地址,接觸過HTML的對這個應該不陌生吧。所以我們要抓的就是這個h3啦!

BeautifulSoup抓取標籤內容

下面就是我們的parser露臉的時候了,BeautifulSoup提供了很多定位標籤的方法,簡單的說,主要就是find函數和findAll
函數了,常用的參數就是name和attrs,一個是標籤的名字,一個是標籤的屬性,name是個字串,而attrs是個字典,比如說
find(‘img’,{‘src’:’abc.jpg’})就會返回類似這樣的標籤:<img 
src=”abc.jpg”>。而find與findAll的區別就是,find只返回第一個滿足要求的標籤,而findAll返回所有符合要求的
標籤的列表。擷取標籤後,還有很多方便的方法擷取子標籤,例如,通過點操作符,tag.a可以擷取tag所代表的標籤下的子標籤a,再如
tag.contents可以擷取其所有孩子的列表,更多應用可以查看它的文檔。下面就具體到本例來看怎麼抓取我們想要的內容。

1234567891011 article_list = parser.find('div','feed-list').findAll('article') for my_article in article_list:     state = []     for my_tag in my_article.h3.contents:         factor = my_tag.string         if factor != None:             factor = factor.replace(u'/xa0','')             factor = factor.strip(u'/r/n')             factor = factor.strip(u'/n')             state.append(factor)     print ' '.join(state)

這裡,我們通過find(‘div’,’feed-list’).findAll(‘article’)擷取class屬性為‘feed-
list’的div標籤,第二個參數直接為一個字串時代表的就是CSS的class屬性了,然後擷取其所有article的列表,對照上面的圖,這句其
實就是獲得了所有新鮮事的列表。然後我們遍曆這個列表,對於每個article標籤再擷取其h3標籤,並提取內容,如果標籤中直接含有文本,則可以通過
string屬性獲得,最後,我們去掉一些控制字元,如換行一類的。最終將結果列印出來,當然這隻能擷取一小部分,“更多新鮮事”的功能還不能達到,有興
趣的繼續研究吧,我覺得通過HttpFox是不難實現的吧。

團購資訊彙總小工具

用同樣的知識,我們還可以做一些有趣的應用,像現在很火的團購資訊彙總,其實思路還是很容易的,就是分析網站的原始碼,提取團購的標題,圖片和價格
就好了。這裡放出源碼檔案,有興趣的可以研究下!用PyQt做的介面,按鈕的功能還沒有實現,只能提取“美團”,“糯米網”,“QQ團購”三個網站,從下
拉列表框裡選擇就可顯示,圖片會儲存在本地目錄裡,來個看看吧~

打叉的按鈕功能沒有實現哦~這裡是檔案下載,一個pyw主表單檔案,兩外兩個py檔案一個是UI,一個是Resource。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.