python網頁資料抓取全紀錄

來源:互聯網
上載者:User

標籤:python

       python網頁資料抓取全紀錄

        在本文中,我將會為你展示一個基於新的非同步庫(aiohttp)的請求的代替品。我使用它寫了一些速度的確很快的小資料抓取器,下面我將會為你示範是如何做到的。codego.net中介紹的方法如此多樣的原因在於,資料“抓取”實際上包括很多問題:你不需要使用相同的工具從成千上萬的頁面中抓取資料,同時使一些Web工作流程自動化(例如填一些表單然後取回資料)。




       asyncio的基本概念

       asyncio是在python3.4中被引進的非同步IO庫。你也可以通過python3.3的pypi來安裝它。它相當的複雜,而且我不會介紹太多的細節。相反,我將會解釋你需要知道些什麼,以利用它來寫非同步代碼。


       協同程式和事件迴圈。

       協同程式像是方法,但是它們可以在代碼中的特定點暫停和繼續。當在等待一個IO(比如一個HTTP請求),同時執行另一個請求的時候,可以用來暫停一個協同程式。我們使用關鍵字yield from來設定一個狀態,表明我們需要一個協同程式的傳回值。而事件迴圈則被用來安排協同程式的執行。


關於asyncio還有很多很多,但是以上是我們到目前為止需要知道的。可能你還有些不清楚,那麼讓我們來看一些代碼吧。


       aiohttp       是一個利用asyncio的庫,它的API看起來很像請求的API。到目前為止,codego.net裡面介紹的相關文檔還不健全。我們使用 asyncio.coroutine將一個方法裝飾成一個協同程式。aiohttp.request是一個協同程式,所以它是一個可讀方法,我們需要使用yield from來調用它們。除了這些,下面的代碼看起來相當直觀:

  @asyncio.coroutine def print_page(url):   response = yield from aiohttp.request(‘GET‘, url)   body = yield from response.read_and_close(decode=True)   print(body) 


       我們可以使用yield from從另一個協同程式中調用一個協同程式。為了從同步代碼中調用一個協同程式,我們需要一個事件迴圈。我們可以通過asyncio.get_event_loop()得到一個標準的事件迴圈,之後使用它的run_until_complete()方法來運行協同程式。所以,為了使之前的協同程式運行,我們只需要做下面的步驟:

 loop = asyncio.get_event_loop() loop.run_until_complete(print_page(‘http://example.com‘)) 

一個有用的方法是asyncio.wait,通過它可以擷取一個協同程式的列表,同時返回一個將它們全包括在內的單獨的協同程式,所以我們可以這樣寫:

 loop.run_until_complete(asyncio.wait([print_page(‘http://example.com/foo‘),     

         print_page(‘http://example.com/bar‘)])) 


       另一個是asyncio.as_completed,通過它可以擷取一個協同程式的列表,同時返回一個按完成順序產生協同程式的迭代器,因此當你用它迭代時,會儘快得到每個可用的結果。

資料抓取

現在我們知道了如何做非同步HTTP請求,因此我們可以來寫一個資料抓取器了。我們僅僅還需要一些工具來讀取html頁面,我使用了beautifulsoup來做這個事情,其餘的像 pyquery或lxml也可以實現。


       我們會寫一個小資料抓取器來從海盜灣抓取一些linux distributions的torrent 鏈路(海盜灣(英語:The Pirate Bay,縮寫:TPB)是一個專門儲存、分類及搜尋Bittorrent種子檔案的網站,並自稱“世界最大的BitTorrent tracker(BT種子伺服器)”,提供的BT種子除了有自由著作權的收集外,也有不少被著作人聲稱擁有著作權的音頻、視頻、應用軟體與電子遊戲等,為網路分享與下載的重要網站之一–譯者注來自維基百科)

首先,需要一個輔助協同程式來擷取請求:

@asyncio.coroutine def get(*args, **kwargs):   response = yield from aiohttp.request(‘GET‘, *args, **kwargs)   return (yield from response.read_and_close(decode=True)) 


       解析部分。本文並非介紹beautifulsoup的,所以這部分我會簡寫:我們擷取了這個頁面的第一個磁鏈。


       def first_magnet(page):   soup = bs4.BeautifulSoup(page)   a = soup.find(‘a‘, title=‘Download this torrent using magnet‘)   return a[‘href‘] 

       在這個協同程式中,url的結果通過種子的數量進行排序,所以排名第一的結果實際上是種子最多的:

6 @asyncio.coroutine def print_magnet(query):   url = ‘http://thepiratebay.se/search/{}/0/7/0‘.format(query)   page = yield from get(url, compress=True)   magnet = first_magnet(page)   print(‘{}: {}‘.format(query, magnet)) 


       用下面的代碼來調用以上所有的方法。

distros = [‘archlinux‘, ‘ubuntu‘, ‘debian‘] loop = asyncio.get_event_loop() f = asyncio.wait([print_magnet(d) for d in distros]) loop.run_until_complete(f) 

       現在我們來到了這個部分。你有了一個非同步工作的小抓取器。這意味著多個頁面可以同時被下載,所以這個例子要比使用請求的相同代碼快3倍。現在你應該可以用相同的方法寫出你自己的抓取器了。


你一旦熟悉了這一切,我建議你看一看asyncio的文檔和aiohttp的範例,這些都能告訴你 asyncio擁有怎樣的潛力。

這種方法(事實上是所有手動的方法)的一個局限在於,沒有一個獨立的庫可以用來處理表單。機械化的方法擁有很多協助工具輔助,這使得提交表單變得十分簡單,但是如果你不使用它們,你將不得不自己去處理這些事情。這可能會導致一些bug的出現,所以同時我可能會寫一個這樣的庫(不過目前為止無需為此擔心)。

額外的建議:不要對伺服器要求太多

同時做3個請求很酷,但是同時做5000個就不那麼好玩了。如果你打算同時做太多的請求,連結有可能會斷掉。你甚至有可能會被禁止連結網路。

為了避免這些,你可以使用semaphore。這是一個可以被用來限制同時工作的協同程式數量的同步工具。我們只需要在建立迴圈之前建立一個semaphore ,同時把我們希望允許的同時請求的數量作為參數傳給它既可:


 sem = asyncio.Semaphore(5) 


然後,我們只需要將下面

 



 page = yield from get(url, compress=True) 


替換成被semaphore 保護的同樣的東西。

 



 with (yield from sem):   page = yield from get(url, compress=True) 

這就可以保證同時最多有5個請求會被處理。

tqdm是一個用來產生進度條的優秀的庫。這個協同程式就像asyncio.wait一樣工作,不過會顯示一個代表完成度的進度條。

@asyncio.coroutine def wait_with_progress(coros):   for f in tqdm.tqdm(asyncio.as_completed(coros), total=len(coros)):     yield from f 


本文出自 “tianajiejue” 部落格,請務必保留此出處http://10068262.blog.51cto.com/10058262/1627628

python網頁資料抓取全紀錄

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.