——個人筆記
一系列:
python爬蟲(一)
python爬蟲(二)
python爬蟲(三)
python爬蟲(四)
python爬蟲(五)
python爬蟲(六)
python爬蟲(七)
python爬蟲(八)
python爬蟲(十)
python爬蟲(十一)
爬蟲如果按照之前是按照順序執行的,那麼當我們要爬取很多資料時那麼就會很慢。相信大家可能會知道有協程(類似多線程,但是是有差別的),但是當協程數量多,我們就要對多協程控制執行數量。
同樣我們要實作多協程,那麼我們同樣要引入gevent庫,和之前一樣,在終端輸入
pip install gevent
運作,然後我們就可以開始了。首先我們要在開頭申明這個程式是協作式執行的:
from gevent import monkey
#從gevent庫裡導入monkey子產品。
monkey.patch_all()
#monkey.patch_all()能把程式變成協作式運作,就是可以幫助程式實作異步。
那麼我們就可以開始爬了:
url_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/']
#把8個網站封裝成清單。
def crawler(url):
#定義一個crawler()函數。
r = requests.get(url)
#用requests.get()函數爬取網站。
print(url,time.time()-start,r.status_code)
#列印網址、請求運作時間、狀态碼。
tasks_list = [ ]
#建立空的任務清單。
for url in url_list:
#周遊url_list。
task = gevent.spawn(crawler,url)
#用gevent.spawn()函數建立任務。
tasks_list.append(task)
#往任務清單添加任務。
gevent.joinall(tasks_list)
#執行任務清單裡的所有任務,就是讓爬蟲開始爬取網站。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPR9EeBRVT3NmeNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL5MzN5UzM0MjM3IDOwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
看了代碼和圖示,可能還是有點懵,其實大概說一下,我們先定義一個爬取資料的函數,然後
task = gevent.spawn(crawler,url)
這裡的 gevent.spawn()就是建立協程任務,第一個參數就是函數名,然後後面的參數就是第一個參數的函數的參數(可能有點繞口,了解一下,如果你調用的函數沒有參數,那麼就隻有第一個參數),你把所有任務都放進清單中後,調用gevent.joinall()就可以執行了。
但是上面的方法沒辦法直接控制爬蟲數量,也就是說,如果我要爬取1000個網站而不是8個,那麼會壓垮伺服器,怎麼解決呢?那麼我們可以想象一下日常生活我們是怎麼解決的,排隊!那麼同樣,這也可以排隊,我們就要引入queue(隊列,隊列就是先進先出)了,
from gevent.queue import Queue
從gevent庫裡導入queue子產品。其實queue也是存儲結構,隻不過,它具有先存儲進去的要先取出來的特性而已。那麼我們看看queue有什麼方法:
非常簡單,其實就是存資料,取資料,檢視還有多少。
work = Queue()
這樣就建立了一個queue對象,那麼看完整代碼:
from gevent import monkey
#從gevent庫裡導入monkey子產品。
monkey.patch_all()
#monkey.patch_all()能把程式變成協作式運作,就是可以幫助程式實作異步。
import gevent,time,requests
#導入gevent、requests
from gevent.queue import Queue
#從gevent庫裡導入queue子產品
url_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()
#建立隊列對象,并指派給work。
for url in url_list:
#周遊url_list
work.put_nowait(url)
#用put_nowait()函數可以把網址都放進隊列裡。
def crawler():
while not work.empty():
#當隊列不是空的時候,就執行下面的程式。
url = work.get_nowait()
#用get_nowait()函數可以把隊列裡的網址都取出。
r = requests.get(url)
#用requests.get()函數抓取網址。
print(url,work.qsize(),r.status_code)
#列印網址、隊列長度、抓取請求的狀态碼。
tasks_list = [ ]
#建立空的任務清單
for x in range(2):
#相當于建立了2個爬蟲
task = gevent.spawn(crawler)
#用gevent.spawn()函數建立執行crawler()函數的任務。
tasks_list.append(task)
#往任務清單添加任務。
gevent.joinall(tasks_list)
#用gevent.joinall方法,執行任務清單裡的所有任務,就是讓爬蟲開始爬取網站。