1. 程式人生 > >深入理解協程(四):async/await非同步爬蟲實戰

深入理解協程(四):async/await非同步爬蟲實戰

本文目錄:

  • 同步方式爬取部落格標題
  • async/await非同步爬取部落格標題

本片為深入理解協程系列文章的補充。

你將會在從本文中瞭解到:async/await如何運用的實際的爬蟲中。

案例

從CSDN上批量爬取指定文章的標題。文章列表如下:

urls = [
    'https://blog.csdn.net/Jmilk/article/details/103218919',
    'https://blog.csdn.net/stven_king/article/details/103256724',
    'https://blog.csdn.net/csdnnews/article/details/103154693',
    'https://blog.csdn.net/dg_lee/article/details/103951021',
    'https://blog.csdn.net/m0_37907797/article/details/103272967',
    'https://blog.csdn.net/zzq900503/article/details/49618605',
    'https://blog.csdn.net/weixin_44339238/article/details/103977138',
    'https://blog.csdn.net/dengjin20104042056/article/details/103930275',
    'https://blog.csdn.net/Mind_programmonkey/article/details/103940511',
    'https://blog.csdn.net/xufive/article/details/102993570',
    'https://blog.csdn.net/weixin_41010294/article/details/104009722',
    'https://blog.csdn.net/yunqiinsight/article/details/103137022',
    'https://blog.csdn.net/qq_44210563/article/details/102826406',
]

同步爬蟲

import requests
import time
from lxml import etree

urls = [
    'https://blog.csdn.net/Jmilk/article/details/103218919',
    'https://blog.csdn.net/stven_king/article/details/103256724',
    ...此處略
]

def get_title(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
    }
    r = requests.get(url, headers)
    html = r.content
    title = etree.HTML(html).xpath('//h1[@class="title-article"]/text()')[0]
    print(title)
 
def main():
    for url in urls:
        get_title(url)
        
if __name__ == '__main__':
    start = time.time()
    main()
    print(f'cost time: {time.time() - start}s')

輸出結果如下:

4G LTE/EPC 協議棧
Android-Universal-Image-Loader原始碼分析
8年經驗面試官詳解 Java 面試祕訣
AES中ECB模式的加密與解密(Python3.7)
【圖解演算法面試】記一次面試:說說遊戲中的敏感詞過濾是如何實現的?
java進階(四)------java程式設計規範---程式碼質量檢測工具FindBugs、PMD和CheckStyle的安裝
這是一份集合一線大廠Android工程師必備技能體系+學習路線!
【程式人生】程式設計師接私活常用平臺彙總
你不得不瞭解的卷積神經網路發展史
致 Python 初學者
OOM別慌,手把手教你定位
中國資料庫OceanBase登頂之路
網頁實現一個簡單的音樂播放器(大佬別看。(⊙﹏⊙))
cost time: 6.065227508544922s

用時:6.065227508544922s。

async/await非同步爬蟲

要實現一個真正的非同步爬蟲,就需要引入aiohttp模組,aiohttp是一個利用asyncio的庫,可以暫時看成協程版的requests

import asyncio
import time
import aiohttp
from lxml import etree

urls = [
    'https://blog.csdn.net/Jmilk/article/details/103218919',
    'https://blog.csdn.net/stven_king/article/details/103256724',
    ...此處略
]

async def async_get_url(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
    }
    async with aiohttp.ClientSession() as session:  # 解釋1
        async with session.get(url, headers=headers) as r:
            html = await r.read()
            title = etree.HTML(html).xpath('//h1[@class="title-article"]/text()')[0]
            print(title)
     
def async_main():
    loop = asyncio.get_event_loop()
    tasks = [async_get_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
 
if __name__ == '__main__':
    start = time.time()
    async_main()
    print(f'cost time: {time.time() - start}s')

輸出結果:

網頁實現一個簡單的音樂播放器(大佬別看。(⊙﹏⊙))
【程式人生】程式設計師接私活常用平臺彙總
致 Python 初學者
中國資料庫OceanBase登頂之路
Android-Universal-Image-Loader原始碼分析
OOM別慌,手把手教你定位
這是一份集合一線大廠Android工程師必備技能體系+學習路線!
AES中ECB模式的加密與解密(Python3.7)
4G LTE/EPC 協議棧
【圖解演算法面試】記一次面試:說說遊戲中的敏感詞過濾是如何實現的?
8年經驗面試官詳解 Java 面試祕訣
java進階(四)------java程式設計規範---程式碼質量檢測工具FindBugs、PMD和CheckStyle的安裝
你不得不瞭解的卷積神經網路發展史
cost time: 0.6428999900817871s

說明:

解釋1:此處為非同步的上下文管理器,是aiohttp官方文件提供的寫法。如果對上下文管理器不是很瞭解的話,可以參看【吃透Python上下文管理器】。

用時:0.6428999900817871s。從兩種爬蟲的輸出結果中可以看到:

  • 文章標題的順序不同。同步爬蟲會按照urls內部的url順序依次爬取文章標題。而非同步爬蟲爬取的順序並不完全和urls中的url順序相同。
  • 爬取速度差異很大。非同步爬蟲速度大概是普通同步爬蟲的8~10倍。非同步爬蟲充分利用了網路請求這段時間。從而提高了爬取效率。

關於aiohttp的更多用法。會在後面文章講到。

推薦閱讀

深入理解協程(一):協程的引入

深入理解協程(二):yield from實現非同步協程

深入理解協程(三):async/await實現非同步協程

Python進階:上下文管理器

關注公眾號西加加先生一起玩轉Python。

相關推薦

深入理解async/await非同步爬蟲實戰

本文目錄: 同步方式爬取部落格標題 async/await非同步爬取部落格標題 本片為深入理解協程系列文章的補充。 你將會在從本文中瞭解到:async/await如何運用的實際的爬蟲中。 案例 從CSDN上批量爬取指定文章的標題。文章列表如下: urls = [ 'https://blog.csd

深入理解async/await實現非同步

原創不易,轉載請聯絡作者 深入理解協程分為三部分進行講解: 協程的引入 yield from實現非同步協程 async/await實現非同步協程 本篇為深入理解協程系列文章的最後一篇。 從本篇你將瞭解到: async/await的使用。 如何從yield from風格的協程修改為async/aw

深入理解yield from實現非同步

原創不易,轉載請聯絡作者 深入理解協程分為三部分進行講解: 協程的引入 yield from實現非同步協程 async/await實現非同步協程 本篇為深入理解協程系列文章的第二篇。 yield from yield from是Python3.3(PEP 380)引入的新語法。主要用於解決在生成器

並發編ThreadLocal從源碼分析總結到內存泄漏

ngs 一個 交互 而且 當前 logs 點雲 然而 垃圾 一、目錄 1、ThreadLocal是什麽?有什麽用? 2、ThreadLocal源碼簡要總結? 3、ThreadLocal為什麽會導致內存泄漏? 二、ThreadLocal是

深入理解JavaScript系列16閉包Closures

ava hive auto flow style this quest 情況 知識 介紹 本章我們將介紹在JavaScript裏大家常常來討論的話題 —— 閉包(closure)。閉包事實上大家都已經談爛了。雖然如此,這裏還是要試著從理論角度來討論下閉包,

shell 編變量

shell bash 變量 declare set 變量 變量是能儲存計算結果或能表示值抽象概念。變量可以通過變量名訪問。 變量聲明 聲明變量一般使用下面方式: root@iZuf6ilzd4iqvuj4dvuiwtZ:~# var=test #這裏聲明了一個名為 var 的變量,並給

多線前臺和後臺線

current pro oid nag 線程 dsta reads reg con class Program11 { private static void ExecuteInForeground() {

深入理解設計模式12職責鏈模式

一、什麼是職責鏈模式 客戶端發出一個請求,鏈上的物件都有機會來處理這一請求,而客戶端不需要知道誰是具體的處理物件。這樣就實現了請求者和接受者之間的解耦,並且在客戶端可以實現動態的組合職責鏈。使程式設計更有靈活性。 定義:使多個物件都有機會處理請求,從而避免了請求的傳送者和接受者之間的耦合關係。將這些物件連

深入理解JavaScript系列5強大的原型和原型鏈

JavaScript 不包含傳統的類繼承模型,而是使用 prototypal 原型模型。 雖然這經常被當作是 JavaScript 的缺點被提及,其實基於原型的繼承模型比傳統的類繼承還要強大。實現傳統的類繼承模型是很簡單,但是實現 JavaScript 中的原型繼承則要困難的多。 &l

深入理解JavaScript系列2揭祕命名函式表示式 命名函式表示式 函式表示式 函式宣告

還有一種函式表示式不太常見,就是被括號括住的(function foo(){}),他是表示式的原因是因為括號 ()是一個分組操作符,它的內部只能包含表示式,我們來看幾個例子: 函式宣告只能出現在程式或函式體內。 如果function foo(){}是作為賦值表示式的一部分的

深入理解設計模式13直譯器模式

一、什麼是直譯器模式 定義:給定一個語言,定義一個文法的一種表示, 並定義一個直譯器, 這個直譯器使用該表示來解釋語言中的句子。   直譯器模式所涉及的角色如下所示:   (1)抽象表示式(Expression)角色:宣告一個所有的具體表達式角色都需要實現的抽象介面。這個介面主要是一個i

Java——深入理解Class物件Class物件的載入及其獲取方式

上一篇部落格Java——深入理解Class物件(一)帶大家簡單認識了一下Java中Class物件。 現在帶大家瞭解一下Class物件的載入及其獲取方式。 1.Class物件的載入 在Java——深入理解Class物件(一)我們已提到過,Class物件是由JVM載入的,那它必然不會是胡亂載

Java——深入理解Class物件什麼是Class物件

Class類是我們再熟悉不過的東西,但是對於Class物件,很多人卻是一臉懵逼。 Class物件到底是什麼呢?今天我們就來深入瞭解一下它。 1.RTTI的概念 RTTI(Run-Time Type Identification),即執行時型別識別,這個詞一直是 C++ 中的概念,至

深入理解JavaScript系列2揭祕命名函式表示式

還有一種函式表示式不太常見,就是被括號括住的(function foo(){}),他是表示式的原因是因為括號 ()是一個分組操作符,它的內部只能包含表示式,我們來看幾個例子: 函式宣告只能出現在程式或函式體內。 如果function foo(

深入理解設計模式15訪問者模式

一、什麼是訪問者模式 定義:表示一個作用於其物件結構中的各元素的操作,它使你可以在不改變各元素類的前提下定義作用於這些元素的新操作。 可以對定義這麼理解:有這麼一個操作,它是作用於一些元素之上的,而這些元素屬於某一個物件結構。同時這個操作是在不改變各元素類的前提下,在這個前提下定義新操作是訪問者模式精髓中

深入理解JavaScript系列4立即呼叫的函式表示式

javascript 函式function前面的一元操作符, 感嘆號、小括號、一元操作符!()+-|| 看下面內容之前可以先看看上面的文章,總結的非常贊 前言 大家學JavaScript的時候,經常遇到自執行匿名函式的程式碼,今天我們主要就來想想說一下自執行 在詳細

原理

協程,又稱微執行緒和纖程等,據說源於 Simula 和 Modula-2 語言(我沒有深究,有錯請指正),現代程式語言基本上都有支援,比如 Lua、ruby 和最新的 Google Go,當然也還有最近很讓我驚豔的 falcon。協程是使用者空間執行緒,作業系統其存

深入理解JavaScript系列15函式Functions

  詳情請檢視:https://www.cnblogs.com/TomXu/archive/2012/01/30/2326372.html   本章節我們要著重介紹的是一個非常常見的ECMAScript物件——函式(function),我們將詳細講解一下各種型別的函式

深入理解計算機系統筆記連結

理解連結有很多好處: 有助於構造大型程式有助於避免一些危險程式設計錯誤有助於理解其他重要的系統概念讓你能夠利用共享庫1. 編譯器驅動程式 編譯命令,假設有main.c和swap.c兩個原始檔 $ gcc -O2 -g -o p main.c swap.c 實際上編譯過程

深入理解JavaScript系列36設計模式之中介者模式

介紹 中介者模式(Mediator),用一箇中介物件來封裝一系列的物件互動。中介者使各物件不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。 主要內容來自:http://www.addyosmani.com/resources/essentia