單執行緒 非同步協程的簡單爬蟲模型

2022-08-18 05:00:14 字數 3777 閱讀 6117

event_loop:事件迴圈,相當於乙個無限迴圈(不清楚迴圈多少次),我們可以把一些特殊函式註冊(放置)到這個事件迴圈上,當滿足某些條件的時候,函式就會被迴圈執行。程式是按照設定的順序從頭執行到尾,執行的次數也是完全按照設定。當在編寫非同步程式時,必然其中有部分程式的執行耗時是比較久的,需要先讓出當前程式的控制權,讓其在背後(掛起)執行,讓另一部分的程式先執行起來。當背後執行的程式完成後,也需要及時通知主程式已經完成任務可以進行下一步操作,但這個過程所需的時間是不確定的,需要主程式不斷的監聽狀態,一旦收到了任務完成的訊息,就開始進行下一步。loop就是這個持續不斷的監視器。

coroutine:中文翻譯叫協程,在 python 中常指代為協程物件型別,我們可以將協程物件註冊到事件迴圈中,

它會被事件迴圈呼叫。我們可以使用 async 關鍵字來定義乙個方法,這個方法在呼叫時不會立即被執行,

而是返回乙個協程物件。

task:任務,它是對協程物件的進一步封裝,包含了任務的各個狀態。

future:代表將來執行或還沒有執行的任務,實際上和 task 沒有本質區別。

另外我們還需要了解 async/await 關鍵字,它是從 python 3.6 才出現的,專門用於定義協程。其中,async 定義乙個協程,await 用來掛起阻塞方法的執行。

import

asyncio

async

defrequest(url):

print('

正在請求:

#第一步:例項化乙個事件迴圈物件

loop =asyncio.get_event_loop()

#第二步:建立乙個任務物件,將協程物件封裝到了該物件中

#task = loop.create_task(c)

#另一種形式例項化任務物件的方法

task =asyncio.ensure_future(c)

#將協程物件註冊到事件迴圈物件中,並且我們需要啟動事件迴圈物件

loop.run_until_complete(task)

#列印task可以看到任務物件狀態

print(task)

繫結**函式,在爬蟲中必須用**函式,因為在資料爬取下來後,用**函式可以進行資料解析

import

asyncio

async

defrequest(url):

print('

正在請求:

',url)

print('

',url)

return

url#

**函式必須有乙個引數:task

#task.result():任務物件中封裝的協程物件對應的特殊函式內部的返回值

#給任務物件繫結乙個**函式

#建立任務物件

task =asyncio.ensure_future(c)

#繫結**函式

task.add_done_callback(callbak)

#註冊到時間迴圈中

loop =asyncio.get_event_loop()

loop.run_until_complete(task)

多工非同步協程

正在請求:

',url)

#在多工非同步協程實現中,不可以出現不支援非同步的相關**。

#sleep(2)

await asyncio.sleep(2)

print('

',url)

loop =asyncio.get_event_loop()

#任務列表:放置多個任務物件

tasks =

for url in

urls:

c =request(url)

task =asyncio.ensure_future(c)

loop.run_until_complete(asyncio.wait(tasks))

print(time.time()-start)

單執行緒+多工非同步

#

面試問題,如何提公升爬取效率

#使用方向:資料量大,資料佔記憶體大

#aiohttp:支援非同步的乙個基於網路請求的模組

#和requests模組功能應用都一樣,區別就是支援非同步

#單執行緒+多工非同步協程

urls =[

'','',

'']#非同步效果,遇到阻塞,掛起阻塞,執行別的任務

#**操作:

#請求物件,with不關閉資源,

#拿響應資料有可能阻塞所以需要await, 這裡是text方法,request是text方法

page_text =await response.text()

#借助於**函式進行響應資料的解析操作

return

page_text

#封裝**函式用於資料解析

defparse(task):

#1.獲取響應資料

page_text =task.result()

print(page_text+'

,即將進行資料解析!!!')

#解析操作寫在該位置

start =time.time()

tasks =

for url in

urls:

c =get_pagetext(url)

task =asyncio.ensure_future(c)

#給任務物件繫結**函式用於資料解析

task.add_done_callback(parse)

loop =asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait(tasks))

print(time.time()-start)

爬蟲 單執行緒 多工非同步協程

要點 1.resquests模組不支援非同步,在需要非同步的地方使用aiohttp模組進行替換 2.定義乙個協程函式,建立協程任務,將 協程 打包為乙個 task 排入日程準備執行。返回task物件 獲取當前事件迴圈,開啟迴圈 data await response.read 此處參考aiohttp...

爬蟲 單執行緒 多工非同步協程

任務物件 事件迴圈 aiohttp 支援非同步網路請求的模組 伺服器端 from flask import flask import time def index bobo time.sleep 2 return hello index1 def index jay time.sleep 2 ret...

python 單執行緒和非同步協程工作方式解析

在python3.4之後新增了asyncio模組,可以幫我們檢測io 只能是網路io http連線就是網路io操作 實現應用程式級別的切換 非同步io 注意 asyncio只能發tcp級別的請求,不能發http協議。非同步io 所謂 非同步 io 就是你發起乙個 網路io 操作,卻不用等它結束,你可...