python3协程 queue_使用gevent库+queue模块实现多协程爬虫,提高爬取效率!
協程是干什么的?
協程可以提高任務執行的效率!它的執行原理就是當計算機在執行某個任務的時候,如果需要等待(比如爬取網站需要等待網站響應等),可以先去執行其他的任務,等等待結束(網站響應)時,再回來繼續任務。本質上就是減少等待的時間,提高爬取的效率。
代碼解析:
使用簡單代碼講解
接下來來看看這么實現它,先用一個比較簡單的代碼來看看:
from gevent import monkey
monkey.patch_all()
import gevent
from gevent.queue import Queue
list = [1,2,3,4,5,6]
work = Queue()
for i in list:
work.put_nowait(i)
def crawler():
while not work.empty():
num = work.get_nowait()
print(num,work.qsize())
tasks_list = [ ]
for x in range(2):
task = gevent.spawn(crawler)
tasks_list.append(task)
gevent.joinall(tasks_list)
基本知識點講解:
第1行:從gevent庫里導入monkey模塊;
第2行:monkey.patch_all()能把程序變成協作式運行;
第3行:調用gevent庫;
第4行:調用queue模塊中的Queue類;
第7行:實例化Queue類,創建一個隊列;
第8行:遍歷列表中的元素;
第9行:Queue.put_nowait()方法是把列表中的元素依次加入隊列中;
第11~14行:創建crawler函數
Queue.empty()判斷隊列是否為空,空返回True;
Queue.get_nowait()從隊列中取值(即第9行添加的值);
Queue.qsize()返回隊列的長度。
第16行:創建空列表tasks_list,用于后面添加任務;
第17~19:創建2個協程,創建任務并把任務添加到任務列表中
gevent.spawn(crawler)創建任務,這里傳入的是函數名;
第20行:gevent.joinall(tasks_list)執行任務。
使用爬蟲代碼測試
接下來通過爬取8個網站來做一下測試:
from gevent import monkey
monkey.patch_all()
import gevent,requests
from gevent.queue import Queue
list = ['https://www.baidu.com/',
'https://www.sina.com.cn/',
'http://www.sohu.com/',
'https://www.qq.com/',
'https://www.163.com/',
'http://www.iqiyi.com/',
'https://www.tmall.com/',
'http://www.ifeng.com/']
work = Queue()
for url in list:
work.put_nowait(url)
def crawler():
while not work.empty():
url = work.get_nowait()
res = requests.get(url)
print(url,work.qsize(),res.status_code) # 打印網址,隊列長度,請求返回情況
tasks_list = []
for x in range(2):
task = gevent.spawn(crawler)
tasks_list.append(task)
gevent.joinall(tasks_list)
那么,怎么看效率提高了呢?
3
2
1
0 揭曉答案:
可以調用time模塊的time()方法來計算,代碼如下:
from gevent import monkey
monkey.patch_all()
import gevent,requests,time
from gevent.queue import Queue
start = time.time() # 獲取開始運行時間戮
list = ['https://www.baidu.com/',
'https://www.sina.com.cn/',
'http://www.sohu.com/',
'https://www.qq.com/',
'https://www.163.com/',
'http://www.iqiyi.com/',
'https://www.tmall.com/',
'http://www.ifeng.com/']
work = Queue()
for url in list:
work.put_nowait(url)
def crawler():
while not work.empty():
url = work.get_nowait()
res = requests.get(url)
print(url, work.qsize(), res.status_code)
tasks_list = []
for x in range(2):
task = gevent.spawn(crawler)
tasks_list.append(task)
gevent.joinall(tasks_list)
end = time.time() # 獲取運行結束時間戮
print('運行耗時'+str(end-start)+'秒') # 相減即可獲取運行時間
運行結果如下:
去掉gevent庫,測試一下運行時間:
import requests,time
start = time.time()
def crawler(url):
res = requests.get(url)
print(url, res.status_code)
list = ['https://www.baidu.com/',
'https://www.sina.com.cn/',
'http://www.sohu.com/',
'https://www.qq.com/',
'https://www.163.com/',
'http://www.iqiyi.com/',
'https://www.tmall.com/',
'http://www.ifeng.com/']
for url in list:
crawler(url)
end = time.time()
print('運行耗時'+str(end-start)+'秒')
運行結果如下:
從結果查看:
有gevent庫+queue模塊時運行只需要1.96秒左右;
沒有gevent庫+queue模塊時運行需要4.02秒左右。
當然,這不代表使用gevent庫+queue模塊速度可以減少一半,只能說明使用gevent庫+queue模塊能夠很好的提高效率!
注意:當crawler()函數有參數的時候,gevent.spawn()這個函數傳入的參數為gevent.spawn(函數名,參數)。傳函數名即可,不用加括號(加括號變成了調用函數,傳入的是函數的返回值),然后函數的參數,跟在后面,spawn()會把參數傳進函數進行調用。
如果crawler()函數沒有有參數,則直接使用gevent.spawn(函數名)即可。
-END-
總結
以上是生活随笔為你收集整理的python3协程 queue_使用gevent库+queue模块实现多协程爬虫,提高爬取效率!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python3 生成器的send_Pyt
- 下一篇: python中二维数组如何按索引找元素_