使用 Python + Selenium 批量下載素材

使用 Python + Selenium 批量下載素材

本文簡單介紹使用 Python + Selenium 從ManyPixels線上圖庫批量下載素材的方法。截止到現在(2020/3/13),ManyPixels 上一共有 19 頁的插圖素材, 437 個文件。手工點擊逐個下載是很不實際的,手指都可能點斷,有必要使用代碼實現程序自動批量下載。

ManyPixels 線上圖庫

ManyPixels,是一個免費線上圖庫,主要以收錄插圖素材爲主。插圖還可以自定義顏色。提供 PNG,SVG 格式下載。根據許可,ManyPixels 發佈於此插圖圖庫的所有素材皆可免費使用,無論是用於非商業或商業用途,無需向創作者或原發布商獲得許可,下載後的插圖可自由修改、編輯或複製。

ManyPixels Illustration Gallery

Selenium

Selenium 是一個用於 Web 應用程序測試的工具。支持多平臺:windows、linux、MAC ,支持多瀏覽器:ie、ff、safari、opera、chrome,多語言 C、 java、ruby、python、或者是 C#。「Selenium 測試直接運行在瀏覽器中,就像真正的用戶在操作一樣」。嗯,看中的就是:

就像真正的用戶在操作一樣

初看「批量下載」應該是一個爬蟲任務,但爲什麼要用一個測試工具呢?因爲通過右鍵查看 ManyPixels 的源碼和普通的頁面很不一樣,根本看不到圖片的標籤。這就不能用傳統的urllib.request或者是Scrapy了。在這裏我不需要效率,只作爲業餘使用的工具,怎麼方便怎麼來,也懶得去深入urllib.request或者是Scrapy,就像用戶去一個一個圖片點擊下載一樣,那就是 Selenium 了。要在 Python 中使用 Selenium,先通過pip安裝:pip install selenium,然後還得配合chromedriver才能使用(如果是 Chrome 瀏覽器),而且得是對應的版本。2020/3/14 更新,爲方便 selenium 初學者使用,特上傳到 CSDN 資源供各位下載,版本爲 chromedriver win32,匹配最新的 Chrome81,下載地址爲:https://download.csdn.net/download/chenbingcai/12247260

代碼實現

因爲我的工作語言不是 Python,作爲工具,可能有點亂,完全不是Pythonic,這裏只是提供一種思路。代碼在運行中出現了以下幾個問題,經調試在我本機環境上可成功運行。在這裏我是下載 SVG 版本,而不是 PNG 版本,因爲 SVG 在後期還可以通過svg-inject等 JS 庫在網頁中動態修改。

  1. ssl_client_socket_impl.cc(941)] handshake failed
    解決辦法:ChromeOptions添加一個參數:opt.add_argument('--ignore-certificate-errors')

  2. HTML 元素無法執行click事件
    解決辦法:通過 JS 選擇這個元素,然後執行這段 JS,driver.execute_script(js)

  3. gcm_channel_status_request.cc(145) GCM channel request failed
    解決辦法:這個錯誤暫時無法解決,但並不影響本次運行功能。

  4. no such element
    解決辦法:可能是元素的xpath不正確,或頁面沒加載完成。在 Chrome 開發者工具中選中元素,右鍵Copy XPath;等待頁面加載完成,until(),在這裏我偷懶,簡單粗暴的用了time.sleep(),不可取。這裏通通清一式用find_element_by_xpath()可能也不是一個好的方法,只是目前剛好能成功運行。另外,判斷元素是否存在,我是用了try except實現,或者還有更好的方法吧。

最後,拋磚引玉,以下是本功能的全部代碼:

# -*- coding: utf-8 -*-

from selenium import webdriver
import time
import random

def sleep_by_time(seconds=3):
    sleep_time=random.random()*seconds
    time.sleep(sleep_time)

def download_SVG(xpath,driver):
    driver.find_element_by_xpath(xpath).click()


def save_SVG():

    opt = webdriver.ChromeOptions()
    opt.add_argument('--ignore-certificate-errors')
    driver = webdriver.Chrome(options=opt)
    driver.maximize_window()

    driver.implicitly_wait(30)

    driver.get('https://www.manypixels.co/gallery/')

    page_count = int(driver.find_element_by_xpath('//*[@id="body"]/div[1]/div/div[2]/ul/li[last()-1]').text) + 1

    for i in range(1,page_count):
        
        js = 'document.querySelector("#body > div.style__ContainerIllustrations-sc-1olxldb-2.irWJZG > div > div.style__ContainerGallery-sc-3zib4p-1.bdbuba > div.style__Container-sc-3zib4p-0.iYHiIc > div:nth-child(1)").click()'
        driver.execute_script(js)

        sleep_by_time()

        j = 0
        while True:
            j = j+1
            download_SVG('//*[@id="body"]/div[1]/div/div[1]/div[2]/div[2]/button[1]',driver)
            
            if j == 1:
                next_span = driver.find_element_by_xpath('//*[@id="body"]/div[1]/div/div[1]/div[2]/div[3]/span')
            else:
                try:
                    next_span = driver.find_element_by_xpath('//*[@id="body"]/div[1]/div/div[1]/div[2]/div[4]/span')
                except :
                    driver.find_element_by_xpath('//*[@id="body"]/div[1]/div/div[1]/div[2]/div[1]/span').click()
                    break

            next_span.click()
            sleep_by_time(5)
            

        # 下一頁
        try:
            driver.find_element_by_xpath('//*[@id="body"]/div[1]/div/div[2]/ul/li[last()]').click()
        except:
            break

        sleep_by_time()

    driver.close()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章