天天看點

python的爬蟲(九)(适合新手)

——個人筆記

一系列:

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)
#執行任務清單裡的所有任務,就是讓爬蟲開始爬取網站。
           
python的爬蟲(九)(适合新手)

看了代碼和圖示,可能還是有點懵,其實大概說一下,我們先定義一個爬取資料的函數,然後

task = gevent.spawn(crawler,url)

這裡的 gevent.spawn()就是建立協程任務,第一個參數就是函數名,然後後面的參數就是第一個參數的函數的參數(可能有點繞口,了解一下,如果你調用的函數沒有參數,那麼就隻有第一個參數),你把所有任務都放進清單中後,調用gevent.joinall()就可以執行了。

但是上面的方法沒辦法直接控制爬蟲數量,也就是說,如果我要爬取1000個網站而不是8個,那麼會壓垮伺服器,怎麼解決呢?那麼我們可以想象一下日常生活我們是怎麼解決的,排隊!那麼同樣,這也可以排隊,我們就要引入queue(隊列,隊列就是先進先出)了,

from gevent.queue import Queue

從gevent庫裡導入queue子產品。其實queue也是存儲結構,隻不過,它具有先存儲進去的要先取出來的特性而已。那麼我們看看queue有什麼方法:

python的爬蟲(九)(适合新手)

非常簡單,其實就是存資料,取資料,檢視還有多少。

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方法,執行任務清單裡的所有任務,就是讓爬蟲開始爬取網站。