摘要:開始,加入了新的語法,和這兩個關鍵字,也成了標準庫,這對于我們寫異步的程序來說就是如虎添翼,讓我們輕而易舉的實現一個定向抓取新聞的異步爬蟲。網址池異步爬蟲的所有流程不能單單用一個循環來完成,它是多個循環至少兩個相互作用共同完成的。
Python寫爬蟲是非常方便的,爬取的目標不同,實現的方式也有很大不同。新聞爬蟲的方便之處是,新聞網站幾乎沒有反爬蟲策略,不好的地方是你想要爬取的新聞網站非常非常多。這個時候,效率就是你首要考慮的問題。
同步循環的效率在這里相形見絀,你需要的是異步IO實現一個高效率的爬蟲。
Python3.5開始,加入了新的語法,async和await這兩個關鍵字,asyncio也成了標準庫,這對于我們寫異步IO的程序來說就是如虎添翼,讓我們輕而易舉的實現一個定向抓取新聞的異步爬蟲。
異步爬蟲依賴的模塊
asyncio: 標準異步模塊,實現python的異步機制;
uvloop:一個用C開發的異步循環模塊,大大提高異步機制的效率;
aiohttp: 一個異步http請求的模塊,用于下載網頁;
urllib.parse: 解析url網站的模塊;
logging: 記錄爬蟲日志;
leveldb: Google的Key-Value數據庫,用以記錄url的狀態;
farmhash: 對url進行hash計算作為url的唯一標識;
sanicdb: 對aiomysql的封裝,更方便的進行數據庫mysql操作;
異步爬蟲實現的流程
2.1 新聞源列表
本文要實現的異步爬蟲是一個定向抓取新聞網站的爬蟲,所以就需要管理一個定向源列表,這個源列表記錄了很多我們想要抓取的新聞網站的url,這些url指向的網頁叫做hub網頁,它們有如下特點:
它們是網站首頁、頻道首頁、最新列表等等;
它們包含非常多的新聞頁面的鏈接;
它們經常被網站更新,以包含最新的新聞鏈接;
它們不是包含新聞內容的新聞頁面;
Hub網頁就是爬蟲抓取的起點,爬蟲從中提取新聞頁面的鏈接再進行抓取。Hub網址可以保存在MySQL數據庫中,運維可以隨時添加、刪除這個列表;爬蟲定時讀取這個列表來更新定向抓取的任務。這就需要爬蟲中有一個循環來定時讀取hub網址。
2.2 網址池
異步爬蟲的所有流程不能單單用一個循環來完成,它是多個循環(至少兩個)相互作用共同完成的。它們相互作用的橋梁就是“網址池”(用asyncio.Queue來實現)。
這個網址池就是我們比較熟悉的“生產者-消費者”模式。
一方面,hub網址隔段時間就要進入網址池,爬蟲從網頁提取到的新聞鏈接也有進入到網址池,這是生產網址的過程;
另一方面,爬蟲要從網址池中取出網址進行下載,這個過程是消費過程;
兩個過程相互配合,就有url不斷的進進出出網址池。
2.3 數據庫
這里面用到了兩個數據庫:MySQL和Leveldb。前者用于保存hub網址、下載的網頁;后者用于存儲所有url的狀態(是否抓取成功)。
從網頁提取到的很多鏈接可能已經被抓取過了,就不必再進行抓取,所以他們在進入網址池前就要被檢查一下,通過leveldb可以快速查看其狀態。
異步爬蟲的實現細節
前面的爬蟲流程中提到兩個循環:
循環一:定時更新hub網站列表
async def loop_get_urls(self,): print("loop_get_urls() start") while 1: await self.get_urls() # 從MySQL讀取hub列表并將hub url放入queue await asyncio.sleep(50)
循環二: 抓取網頁的循環
async def loop_crawl(self,): print("loop_crawl() start") last_rating_time = time.time() asyncio.ensure_future(self.loop_get_urls()) counter = 0 while 1: item = await self.queue.get() url, ishub = item self._workers += 1 counter += 1 asyncio.ensure_future(self.process(url, ishub)) span = time.time() - last_rating_time if self._workers > self.workers_max: print("got workers_max, sleep 3 sec to next worker") await asyncio.sleep(3)
asyncio 要點:
讀讀asyncio的文檔就可以知道它的運行流程,這里分享一下使用時注意到的地方。
(1)使用loop.run_until_complete(self.loop_crawl())來啟動整個程序的主循環;
(2)使用asyncio.ensure_future() 來異步調用一個函數,它相當于多進程的fork,gevent的spawn(),具體可以參考上述代碼。
文章來源于:猿人學網站的python教程。
版權申明:若沒有特殊說明,文章皆是猿人學原創,沒有猿人學授權,請勿以任何形式轉載。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/43729.html
摘要:所以與多線程相比,線程的數量越多,協程性能的優勢越明顯。值得一提的是,在此過程中,只有一個線程在執行,因此這與多線程的概念是不一樣的。 真正有知識的人的成長過程,就像麥穗的成長過程:麥穗空的時候,麥子長得很快,麥穗驕傲地高高昂起,但是,麥穗成熟飽滿時,它們開始謙虛,垂下麥芒。 ——蒙田《蒙田隨筆全集》 上篇論述了關于python多線程是否是雞肋的問題,得到了一些網友的認可,當然也有...
摘要:一般用進程池維護,的設為數量。多線程爬蟲多線程版本可以在單進程下進行異步采集,但線程間的切換開銷也會隨著線程數的增大而增大。異步協程爬蟲引入了異步協程語法。 Welcome to the D-age 對于網絡上的公開數據,理論上只要由服務端發送到前端都可以由爬蟲獲取到。但是Data-age時代的到來,數據是新的黃金,毫不夸張的說,數據是未來的一切?;诮y計學數學模型的各種人工智能的出現...
摘要:爬蟲神器,對加密降維打擊是對無頭瀏覽器的封裝。使用等其他無頭瀏覽器的最大優勢當然是對加密實行降維打擊,完全無視加密手段,對于一些需要登錄的應用,也可以模擬點擊然后保存。請求過濾你的那一段頁面自動下拉腳本 爬蟲神器pyppeteer,對 js 加密降維打擊 pyppeteer?是對無頭瀏覽器?puppeteer的 Python 封裝。無頭瀏覽器廣泛用于自動化測試,同時也是一種很好地爬蟲思...
摘要:時間永遠都過得那么快,一晃從年注冊,到現在已經過去了年那些被我藏在收藏夾吃灰的文章,已經太多了,是時候把他們整理一下了。那是因為收藏夾太亂,橡皮擦給設置私密了,不收拾不好看呀。 ...
摘要:快速開始在安裝之前在支持異步的過程中,都經歷了哪些比較重大的更新。踏出第一步我們將正式使用來構建一個項目,讓我們踏出第一步,利用來編寫一個返回字符串的服務程序。本次示例的源代碼全部在上,見。 快速開始 在安裝Sanic之前,讓我們一起來看看Python在支持異步的過程中,都經歷了哪些比較重大的更新。 首先是Python3.4版本引入了asyncio,這讓Python有了支持異步IO的標...
閱讀 2208·2021-09-02 15:11
閱讀 1517·2019-08-30 15:43
閱讀 2081·2019-08-29 13:48
閱讀 2801·2019-08-26 13:55
閱讀 2108·2019-08-23 15:09
閱讀 2905·2019-08-23 14:40
閱讀 3436·2019-08-23 14:23
閱讀 2644·2019-08-23 14:20