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

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

轉: https://blog.csdn.net/qq_32166627/article/details/60882964

前言:

前面我們爬取圖片的網站都是靜態的,在頁面中右鍵檢視原始碼就能看到網頁中圖片的位置。這樣我們用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('36D美女',10)  # 引數1:關鍵字,引數2:要下載的頁數
    getImg(dataList,'C:/Users/mycomm/Desktop/photo') # 引數2:指定儲存的路徑
  •