1. 程式人生 > >[Python爬蟲]爬蟲例項:爬取PEXELS圖片---解決非同步載入問題

[Python爬蟲]爬蟲例項:爬取PEXELS圖片---解決非同步載入問題

第一次嘗試爬取—>[Python爬蟲]爬蟲例項:三種方式爬取PEXELS圖片
在爬取PEXELS時,遇到了這樣問題:
頁面使用Ajax的非同步載入技術來實現分頁,所以通過request.text無法獲取動態載入的內容.而如果想正確獲取這些資料,則需要使用名為逆向工程的過程(“抓包”).PS:如果對上面的文字感到疑惑,那麼可以閱讀下面的例子和說明,做基礎的瞭解.
例如:要在PEXELS上看貓片 https://www.pexels.com/search/cat/ ,我們雖然在瀏覽器中看到很多圖片,如圖:
在這裡插入圖片描述
但是使用在response能爬到的下載連結卻只有這麼一點:
在這裡插入圖片描述
意味著網站的每一頁只重新整理15張圖片,每次拖動滾動條向下,才再次重新整理15張圖片.

非同步載入的說明

傳統的網頁如果需要更新內容,必須過載整個網頁頁面,網頁載入速度慢,使用者體驗差,而且資料傳輸少,會造成頻寬浪費.非同步載入技術(AJAX),是指一種建立互動式網頁應用的網頁開發技術.通過在後臺與伺服器進行少量資料交換,AJAX可以使網頁實現非同步更新.意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新.

逆向工程的說明

因為使用非同步載入技術後,不再是立刻載入所有的網頁內容然後返回response就完事了,所以展示的新內容就不再HTML的原始碼中,無法抓取這些新的資料.於是我們需要抓取這些通過非同步載入方法的網頁資料,需要了解網頁是如何載入這些資料,這個過程就叫做逆向過程.

逆向工程的實踐

通過逆向工程,能夠找到網頁新載入的資料以及對應的新頁面用於設計新的爬蟲程式碼.
開啟網頁https://www.pexels.com/search/cat/ ,按F12開啟開發者工具,選擇Network選項卡,找到並點選XHR,之後向下拖動滾動條,就能發現右側刷新出來一些新的檔案,如圖:

在這裡插入圖片描述
點第一個檔案看到Headers請求的URL,https://www.pexels.com/search/cat/?page=2&format=js&seed=2018-11-15 03:21:06 +0000
在這裡插入圖片描述
然後點Response
在這裡插入圖片描述
複製內容到文字
在這裡插入圖片描述
這不就是我要爬取的圖片的地址嗎?
https://www.pexels.com/search/cat/?page=2&format=js&seed=2018-11-15 03:21:06 +0000


猜測上面網址將?page=2改為page=x就能得到第x頁的資訊了,將後面的刪掉後直接訪問也沒問題了:https://www.pexels.com/search/cat/?page=3
就這樣,我們得到了需要爬取的網頁.
在這裡插入圖片描述
印證了前面的每一頁重新整理15張圖片的結論.
現在知道了網頁的地址,那麼爬蟲修改起來也很方便,

爬蟲程式碼

import requests
import re
import time

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                  'AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/67.0.3396.79 Safari/537.36'
}


def pic_scratch(url):
    res = requests.get(url, headers)
    links = re.findall('<a href=\"(.*)\" download>', res.text)
    for link in links:
        pic = requests.get(link, headers)
        pic_name = re.search('(?<=dl=).*\.jpg', link).group()
        with open('d:/cat/' + pic_name, 'wb') as pf:
            pf.write(pic.content)
        print("完成圖片下載:" + pic_name)


if __name__ == '__main__':
    start_time = time.time()
    urls = ['https://www.pexels.com/search/cat/?page=={}'.format(i) for i in range(1, 7)]
    for url in urls:
        pic_scratch(url)
    end_time = time.time()
    print("總用時:", end_time - start_time)

爬取結果

在這裡插入圖片描述
在這裡插入圖片描述

寫在最後

為什麼圖片沒有截全部,因為下載真的超!級!慢,對於現在這個爬蟲手段,是單程序爬蟲,也就是說,在每爬取一張圖片時,必須先等待載入完這張圖片,再爬下一張,可見如果像在網路較差的地方,那麼載入時間將會非常長,不划算.所以在下一次爬取中,我將實現多程序爬蟲,以加快爬取速度