Python|用aiohttp和uvloop實現(xiàn)一個高性能爬蟲,分分鐘上千張圖片

asyncio于Python3.4引入標準庫,增加了對異步I/O的支持,asyncio基于事件循環(huán),可以輕松實現(xiàn)異步I/O操作。接下來,我們用基于asyncio的庫實現(xiàn)一個高性能爬蟲。

準備工作

Earth View from Google Earth是一款Chrome插件,會在打開新標簽頁時自動加載一張來自Google Earth的背景圖片。

Python|用aiohttp和uvloop實現(xiàn)一個高性能爬蟲,分分鐘上千張圖片

ssets/data/v2/1234.json的JSON文件,文件中包含了經(jīng)過Base64的圖片內(nèi)容,觀察發(fā)現(xiàn),圖片的ID范圍大致在1000-8000之間,我們的爬蟲就要來爬取這些精美的背景圖片。

實現(xiàn)主要邏輯

由于爬取目標是JSON文件,爬蟲的主要邏輯就變成了爬取JSON-->提取圖片-->保存圖片。

requests是一個常用的http請求庫,但是由于requests的請求都是同步的,我們使用aiohttp這個異步http請求庫來代替。

Python|用aiohttp和uvloop實現(xiàn)一個高性能爬蟲,分分鐘上千張圖片

aiohttp基于asyncio,所以在調(diào)用時需要使用async/await語法糖,可以看到,由于aiohttp中提供了一個ClientSession上下文,代碼中使用了async with的語法糖。

加入并行邏輯

上面的代碼是抓取單張圖片的邏輯,批量抓取圖片,需要再嵌套一層方法:

Python|用aiohttp和uvloop實現(xiàn)一個高性能爬蟲,分分鐘上千張圖片

接下來,將這個方法加入到asyncio的事件循環(huán)中。

Python|用aiohttp和uvloop實現(xiàn)一個高性能爬蟲,分分鐘上千張圖片

使用uvloop加速

uvloop基于libuv,libuv是一個使用C語言實現(xiàn)的高性能異步I/O庫,uvloop用來代替asyncio默認事件循環(huán),可以進一步加快異步I/O操作的速度。

uvloop的使用非常簡單,只要在獲取事件循環(huán)前,調(diào)用如下方法,將asyncio的事件循環(huán)策略設(shè)置為uvloop的事件循環(huán)策略。

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

使用上面的代碼,我們可以快速將大約1500張的圖片爬取下來。

Python|用aiohttp和uvloop實現(xiàn)一個高性能爬蟲,分分鐘上千張圖片

性能對比

為了驗證aiohttp和uvloop的性能,筆者使用requests+concurrent庫實現(xiàn)了一個多進程版的爬蟲,分別爬取20個id,消耗的時間如圖。

Python|用aiohttp和uvloop實現(xiàn)一個高性能爬蟲,分分鐘上千張圖片

可以看到,耗時相差了大概7倍,aiohttp+uvloop的組合在爬蟲這種I/O密集型的場景下,可以說具有壓倒性優(yōu)勢。相信在不遠的將來,基于asyncio的庫會將無數(shù)爬蟲工程師從加班中拯救出來。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容