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