注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

淘尽网 官方博客

淘尽网http://www.tao3w.com做最好的比价网站

 
 
 

日志

 
 
关于我

淘尽网 http://www.tao3w.com 做最好的比价网站,做最好的数据抓取专家。

网易考拉推荐

抓取網頁的最佳語言 : Python  

2012-05-06 00:50:32|  分类: spider |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

最初

最早我用C/C++語言慢慢寫抓網頁的用它來抓網頁真的是程式,一開始甚至打算自己寫抓取網頁的函式庫,想說當做練習,可是HTTP協定 雖然不難,可是煩,要處理的細節太多了,後來受不了,轉而使用現成的Library : cUrl,但是C/C++語言開發這類東西的效率實在太慢了,我的程式不停的修改、不停的修改,光是編譯的時間就吃掉了不知道多少,字串的處理C/C++ 沒有內建正規表示法或一些好用的字串函數之類的,處理起來也礙手礙腳,當時,我想將我寫好的函數庫寫成能讓Lua呼叫的形式,或著甚是C/C++來呼叫Lua,因為C/C++有很多細節要處理,Memory leak有的沒有的雜事,我想要的只是專注在寫抓取網頁的程式,因此用Lua包裝似乎是不錯的選擇,但是開發時間太久了,事情一直沒有變好

直到

我下了一個結論,C/C++不適合寫抓取網頁的程式,我開始思考我需要什麼,我想我既然要包裝成其它語言將細節藏起來,為何不直接使用script語言? 我最早一直擔心的是效率的問題,但是到後來想想反正真正沒效率的部份包給C/C++去做事實上沒有太大的差別,而且又有動態語言的彈性、除錯上的方便等等好處,何樂不為? 於是我開始尋找一款合適的語言

Perl 如何?

很早以前我有用Perl寫過一些CGI程式、留言版、網站管理系統、文章管理系統等等,有人說Perl是只能寫一次的語言,它有很多很簡短的符號所構成的表示法,可讀性不是很好,模組化設計也沒有非常好的支援,OO也是一樣,新版的Perl遲遲沒有推出,似乎已經有點變成遺產的感覺,或許是上面的理由還是偏見,總而言之我不喜歡Perl

PHP?

做為一個以網頁為主要用途的語言,拿來當做其它用途總有種不太合適的感覺,從它的語法來看,很明顯是參考C語言、Perl等等而來的,但是卻沒有加以改進,我個人認為它可能沒有預料到PHP居然會紅成這樣,變成網頁程式設計的主流語言,後來有很多缺點就變得顯而易見,不夠嚴僅的語法、不夠好的模組化設計、不良的OO支援、容易寫出安全性有問題的程式等等,命名空間也是它一大缺點之一,光是看到一大堆前綴字開頭的函數就有種倒胃口的感覺,有人說

PHP is the BASIC of the 21st century

在這個影片裡,總合種種理由,做為抓取網頁的用途,PHP出局

Lua

Lua做為輕量級的語言相當的優秀,可是你不會想用Lua來寫大型的程式,我也不會想這麼做,它語言的設計都是以速度為優先考量,寫起來並不怎麼順手的感覺,再加上目前的資源不多,可能很多東西都得自行包裝,這樣就和我原先想做的事是一樣的,因此不考慮Lua

Java

Java是和網路一起成長的程式語言,做為抓取網頁的用途,它絕對有能力勝任,但是…,我嫌它太囉唆了,還有太癡肥,當一款語言太囉唆和太癡肥往往會令人討厭,歐! 想到Java我就想起eclipse在我那台只有256扣掉分給顯示記憶體的筆電上執行的情況,讓我想把電腦砸掉,不好意思,我不喜歡Java

在前面的影片裡的老兄一樣也有提到,有興趣可以看看

Java is the COBOL of the 21st century

Python

最後,我在PTT的程式設計討論版上描述了我的需求,有人推文說 Python,我抓了抓頭髮,Python? WTF? 這是什麼? 我從來沒有聽過這款語言,於是上網找了一下資料,和問了一些問題,發現這款語言正是我想要的,它很容易被擴充,因此效能不足可以用C/C++補強,你想得到的函式庫幾乎都已經有人寫好了,光從下載網頁這件工作來看,它的標準函式庫已經有了這樣的功能,你覺得不夠好還有其它很多的選擇,開箱即用的哲學,讓安裝函式庫非常簡單,不像C/C++的編譯惡夢讓你抓光頭髮,而它最優秀的地方之一就是它的可讀性,寫起來相當順手、優雅,讀起來也一樣順眼,重要的是很有趣,那麼開發大型的程式呢? script語言常見的問題就是對於開發大型程式來說很不適合,但是Python卻不是如此,良好的OO、模組化等等它都有良好的支援,再加上Google也是Python的愛用者,YouTube也是用Python開發的,有了這些大咖背書,證明這款語言的確是相當優秀,在決定使用Python之後我就立刻訂購了一本Learning Python,開始學習Python

愛上Python

Python並沒有讓我失望,能用Python寫的東西都不太想用C/C++去寫,開發效率非常高、寫起來很順手、豐富的資源,讓我覺得這真的是優秀的語言,它的確很適合拿來抓取網頁,不過抓取網頁還有更多東西要考慮

Twisted

用Python抓取網頁的HTML只是小菜一盤,用Python標準函數庫就辦得到,但不是那麼好用,最後我發現了Twisted,就改用Twisted來抓網頁,它有優秀的非同步事件驅動的架構,常見的協定都已經有實做,包括HTTP、SMTP等等,用它來抓網頁真的是再容易不過了

getPage("http://www.google.com").addCallback(printPage)

是的,一行就可以抓網頁,夠簡單吧,而且你想要傳POST或GET等參數,或是修改HTTP的header都沒有問題

BeautifulSoup

抓網頁事實上不是什麼難事,解析HTML要來得更麻煩,最初使用Python的標準函式庫內建的HTMLParser來解析網頁,但是功能太陽春,加上最頭痛的問題是,大部份的網頁都沒有完全尊照標準來寫,各種莫明奇妙的錯誤令人想要找出那個寫網頁的人痛打他一頓,為了解決容錯的問題,一開始我使用BeautifulSoup來抓取網頁,它是以容錯著名的HTML Parser,但是,它的效率很差,又或著說,找到目標HTML標籤的方式很沒效率,一般都用find等方式來找到所要的標籤

soup.find('div', dict(id='content'))

它真的很沒效率,當你抓取大一點的網頁時,多塞幾個一起抓和解析,你就會看見你的CPU使用率永遠是滿的狀態,原本我預計抓網頁的瓶頸都會落在網路IO上面,但是用它來抓取網頁卻超出我預料,沒想到它會這麼吃重,於是沒辦法,我開始尋找更好的選擇

lxml

我找到一個Blog的文章 : Python HTML Parser Performance,介紹了Python各種Parser的效能,效能最亮眼的,就是lxml,我最初擔心的是找到資料標籤會不會很困難,但是我發現它支援xpath,就試著改寫原本BeautifulSoup用find等等函數寫的尋找標籤程式,發現xpath遠比那種方式來得好用太多了,而且效率好太多了,BeautifulSoup的find極度的沒有效率,大部份的CPU時間都耗在一堆find函數走訪HTML樹上,而xpath篩選標籤的方式來得有效率多了,以下舉幾個我實際用在抓取網頁的案子中的例子

def getNextPageLink(self, tree):     """Get next page link       @param tree: tree to get link     @return: Return url of next page, if there is no next page, return None     """     paging = tree.xpath("//span[@class='paging']")     if paging:         links = paging[0].xpath("./a[(text(), '%s')]" % self.localText['next'])         if links:             return str(links[0].get('href'))     return None
listPrice = tree.xpath("//*[@class='priceBlockLabel']/following-sibling::*") if listPrice:     detail['listPrice'] = self.stripMoney(listPrice[0].text)

原本使用BeautifulSoup在尋找標籤遇到麻煩的走訪羅輯上的問題還得寫程式解決,xpath本身就有豐富的語法可以提供各種篩選的條件,羅輯從程式碼被移到了xpath語法上,有了這樣的語法,尋找目標標籤輕鬆了許多,而且效率也很好,從此我就和BeautifulSoup說再見,改用lxml來找標籤

配合FireFox的工具

如果有一些工具可以幫助寫解析網頁的程式該有多好,這也是我希望能有的,使用了xpath之後,我找到了FireFox的插件,XPath checker等xpath的工具,可以先用它來確定抓到的元素是正確的,然後FireBug在檢視網頁結構上也有很大的幫助

FireFox插件XPath checker畫面

FireFox插件XPath checker畫面

使用FireBug檢視網頁元素

使用FireBug檢視網頁元素

結論

就目前一路走過來的經驗來看,抓取網頁Python的確是最佳的選擇,不過我們到目前為止我們都只討論到工具,事實上還有設計上的問題要解決,留在下一次寫

  评论这张
 
阅读(1270)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017