1. 程式人生 > >python學習(7):python爬蟲之爬取動態載入的圖片,以百度圖片為例

python學習(7):python爬蟲之爬取動態載入的圖片,以百度圖片為例

前言:

前面我們爬取圖片的網站都是靜態的,在頁面中右鍵檢視原始碼就能看到網頁中圖片的位置。這樣我們用requests庫得到頁面原始碼後,再用bs4庫解析標籤即可儲存圖片到本地。

當我們在看百度圖片時,右鍵–檢查–Elements,點選箭頭,再用箭頭點選圖片時,會顯示圖片的位置和樣式。但是,當我們右鍵檢視網頁原始碼時,出來的卻是一大堆JavaScript程式碼,並沒有圖片的連結等資訊。這是為什麼呢?

檢視頁面元素能找到圖片

頁面原始碼並沒有圖片URL

這是因為,百度圖片的網頁是一個動態頁面,它的網頁原始資料其實是沒有這個圖片的,通過執行JavaScript,把這個圖片資料把它插入到網頁的html標籤裡面,那這樣造成的結果是,我們在開發者工具中雖然能看到這個html標籤,但實際上,當我們在看網頁的原始資料的時候,其實是沒有這個標籤的,它只在執行時載入和渲染,那這個時候怎麼辦呢?怎麼把這個圖片給下載下來呢?這裡面我們就換一個思路,我們就來抓包。

我們點選Network–XHR,然後我們在往下滑動滾動條時,會一直出現一個名為:acjson?tn=resultjson&ipn=…的請求,點選它再點Preview,我們看到這是一條json資料,點開data,我們看到這裡面有30條資料,每一條都對應著一張圖片。

執行步驟

於是我們就清楚了,百度圖片一開始只加載30張圖片,當我們往下滑動滾動條時,頁面會動態載入1條json資料,每條json資料裡面包含了30條資訊,資訊裡面又包含了圖片的URL,JavaScript會將這些url解析並顯示出來。這樣,每次滾動到底就又多出30張圖片。

那麼,這些一直出現的json資料有什麼規律呢?我們點選Headers,然後對比這些json資料的頭部資訊。通過對比,我們發現headers下的Query String Parameters中的欄位大多保持不變,只有pn欄位保持以30為步長遞增。wonderful!這下找到規律啦!

json規律

正文:

既然知道了原理,我們就來寫程式碼實現python爬蟲抓取百度圖片。
二話不說就上程式碼:

import requests
import os

def getManyPages(keyword,pages):
    params=[]
    for i in range(30,30*pages+30,30):
        params.append({
                      'tn': 'resultjson_com',
                      'ipn': 'rj',
                      'ct': 201326592
, 'is': '', 'fp': 'result', 'queryWord': keyword, 'cl': 2, 'lm': -1, 'ie': 'utf-8', 'oe': 'utf-8', 'adpicid': '', 'st': -1, 'z': '', 'ic': 0, 'word': keyword, 's': '', 'se': '', 'tab': '', 'width': '', 'height': '', 'face': 0, 'istype': 2, 'qc': '', 'nc': 1, 'fr': '', 'pn': i, 'rn': 30, 'gsm': '1e', '1488942260214': '' }) url = 'https://image.baidu.com/search/acjson' urls = [] for i in params: urls.append(requests.get(url,params=i).json().get('data')) return urls def getImg(dataList, localPath): if not os.path.exists(localPath): # 新建資料夾 os.mkdir(localPath) x = 0 for list in dataList: for i in list: if i.get('thumbURL') != None: print('正在下載:%s' % i.get('thumbURL')) ir = requests.get(i.get('thumbURL')) open(localPath + '%d.jpg' % x, 'wb').write(ir.content) x += 1 else: print('圖片連結不存在') if __name__ == '__main__': dataList = getManyPages('王尼瑪',10) # 引數1:關鍵字,引數2:要下載的頁數 getImg(dataList,'e:/pythonSpiderFile/img17/') # 引數2:指定儲存的路徑

程式碼可以隨意指定要下載圖片的關鍵字和下載多少頁,上述程式碼就可以下載10頁(300張)關於王尼瑪的圖片,是不是很方便,快動手試一試吧!