Python異步爬蟲多線程與線程池示例詳解

背景

當對多個url發送請求時,隻有請求完第一個url才會接著請求第二個url(requests是一個阻塞的操作),存在等待的時間,這樣效率是很低的。那我們能不能在發送請求等待的時候,為其單獨開啟進程或者線程,繼續請求下一個url,執行並行請求

異步爬蟲方式

多線程,多進程(不建議)

好處:可以為相關阻塞的操作單獨開啟線程或者進程,阻塞操作就可以異步會執行

弊端:不能無限制開啟多線程或者多進程(需要頻繁的創建或者銷毀進程,線程)

線程池,進程池(適當使用)

好處:可以降低系統對進程或線程創建和銷毀的頻率,從而很好的而降低系統的開銷

弊端:線程或進程池中的數量是有上限的

單線程+異步協程(推薦)

多線程

正常運行如下的代碼,需要花費8秒鐘的時間,因為sleep是一個阻塞的操作,在等待的時候不會執行別的操作,極大地降低瞭效率

from time import sleep
import time
start = time.time()
def xx(str):
    print('正在下載:', str)
    sleep(2)
str = ['xiaozi', 'aa', 'bb', 'cc']
for i in str:
    xx(i)
end = time.time()
print('程序運行時間:',end-start)

使用多線程後

from threading import Thread
from time import sleep
import time
start = time.time()
def xx(str):
        print('正在下載:',str)
        sleep(2)
str =  ['xiaozi','aa','bb','cc']
def main():
    for s in str:
        #開啟線程,target=函數名,args=(xx,) ,xx為向函數傳遞的參數,必須為元組類型,所以後面需要加,
        t = Thread(target=xx,args=(s,))
        t.start()
if __name__ == '__main__':
    main()
    end = time.time()
    print('程序運行時間:',end-start)

但是我們發現下面的運行順序貌似有點亂的

線程池

對上面的改為線程池後運行

#倒入線程池模塊對應的類
from multiprocessing.dummy import Pool
from time import sleep
import time
start = time.time()
def xx(str):
        print('正在下載:',str)
        sleep(2)
str =  ['xiaozi','aa','bb','cc']
#實例化一個線程池對象,線程池中開辟四個線程對象,並行4個線程處理四個阻塞操作
pool = Pool(4)
#將列表中的每一個列表元素(可迭代對象)傳遞給xx函數(發生阻塞的操作)進行處理
#map方法會有一個返回值為函數的返回值(一個列表),但是這裡沒有返回值所以不考慮
#調用map方法
pool.map(xx,str)
end = time.time()
print('程序運行時間:',end-start)

以上就是Python異步爬蟲多線程與線程池示例詳解的詳細內容,更多關於Python異步多線程與線程池的資料請關註WalkonNet其它相關文章!

推薦閱讀: