一、 理論基礎
1、線程是有限的,線程開啟過多,CPU吃不消
2、多任務--理論上每個線程下可以開啟很多協程,但實際效果一般
500個最佳,速度最快
‘’’
二、爬蟲推薦單線程+多任務異步協程
1、協程
是一個對象,可以吧協程當做衣蛾特殊的函數,如果一個函數的
定義被async關鍵字修飾,該特殊的函數被調用後函數内部的程式語
句不會被立即執行,而是會傳回一個協程對象,如eg1
2、任務對象(task):
所謂的任務對象就是協程對象的進一步封裝
( 即是一個進階的協程對象)
在任務對象中可以實作顯示協程對象的運作狀況
-任務對象需要被注冊到時間循環對象中
-核心:綁定回調
-回調函數綁定給任務隊象,隻有當任務隊象的特殊函數執行完
畢後,回調函數才會被執行
3、事件循環對象
無限循環的對象(可以将其了解為一中容器,該容器中需要放置多
個任務對象)就是一組待執行的任務
-無線循環:指所有的任務因為阻塞可能執行無數次,不是指含
有無限個任務
-異步的提現:當事件循環開啟後,該對象就會按照順序執行每
一個任務對象
4、await
挂起的操作-可了解為交出CPU的使用權,(程序和線程中
系統會對阻塞的任務自動挂起),但在協程中,需手動進行
挂起操作
main_program:
from time import sleep
import asyncio
# 回調函數,其預設參數為任務隊象
def call_back(task):
print('i am callback!!!','開始執行我了')
print(task.result()) #這裡的傳回值就是任務隊象中那個特殊的函數的傳回值
async def get_request(url):
print('現在請求:',url)
sleep(2)
print('請求結束了!!',url)
return 'xinixn'
eg1:協程對象
#建立一個協程對象
c=get_request('www.huhu.com')
print(c)
傳回為一個協程對象:<coroutine object get_request
at 0x00000000021A6EC0>
eg2: 任務對象與事件循環對象的使用
#封裝一個任務對象
task=asyncio.ensure_future(c)
# 給任務對象綁定回調函數
task.add_done_callback(callback)
# 建立一個事件循環對象
loop=asyncio.get_event_loop()
loop.run_until_complete(task)
#将任務對象注冊到事件循環對象中并且開啟了事件循環
應用場景總結:
1、爬蟲中,爬取響應和資料解析和兩個過程,必須分先後進行(即隻能能串行),是以上述
任務對象: 可封裝爬取部分
回調函數:封裝解析資料部分
2、任務對象就是:
封裝的待執行的特殊代碼塊
3、事件循環對象中
預設有一個事件執行情況監控機制,運作過程中某個事件發生了阻
塞,就會自動切換另外任務執行,進而實作異步