Python 使用爬蟲批次下載網頁圖片 (Python Using Requests download imgae files)

2021-07-07

筆記拋棄式的簡單爬蟲腳本,示範如何實作批次下載網頁圖片、自動抓圖與下載檔案,達到自動化作業的目的。同時也會使用到爬蟲常用的套件、模組,例如 requests 的安裝方式與使用介紹。

logo

從 HTML 取得圖片連結後下載

Modules

使用的模組包含 requests, os,其中 datas 為自定義的 python module,內容為要迭代查詢的 URL 集合。

pip install requests

獲得圖片的連結

對網頁 Html 進行處理,搭配 Beautiful Soup 取出所有 Html 中的 Img Element,再進行加入至 list 提供迭代下載圖片使用。

from bs4 import BeautifulSoup

response = requests.get('https://URL')
soup = BeautifulSoup(response.content, 'html.parser')

datas = []

for i in soup.find_all('img'):
  datas.append(i.attrs['src'])

datas.py

datas = [
    'https://via.placeholder.com/300.png',
    'https://via.placeholder.com/300.jpg',
    'https://via.placeholder.com/300.gif',
]

Main

count 為檔名的流水編號,本次以 1024 開始做遞減,另藉由 os Module 將作業目錄切換到要儲存圖片的位置。

開始迭代 datas list 物件,藉由 requests.get 取得圖片內容,並識別副檔名 (extension),識別的方式是網址分割英文句號「.」後的最後一組資料。

import requests
import os
import datas

count = 1024
os.chdir(r'C:\Downlaods')

for url in datas.datas:
  img = requests.get(url)
  extension = url.split('.')[-1]

  with open(f"{start}.{extension}", "wb") as f:
    f.write(img.content)
    f.close()

  start -= 1

由網址列清單批次下載圖片

問就是下列 Scripts 直接使用,調整 data list 馬上開始下載。

sleepCount
下載多少圖片後進行休息
sleepMaxSecs
每次休息最大隨機秒數
downloadPath
下載圖片的儲存位置
logsPath
下載 logs 的儲存位置
import requests
import os
import time
import random

def getFileNameExtension(url):
  name = url.split('/')[-1].split('.')[0]
  extension = url.split('.')[-1]
  return (name, extension)

datas = [
'https://sdwh.dev/1024.gif',
'https://sdwh.dev/512.gif',
'https://sdwh.dev/32.gif',
]

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

requestsParameter = {
  'sleepCount': 10,
  'sleepMaxSecs': 5,
  'downloadPath': r'C:\Users\sdwh\Desktop\imgs',
  'logsPath': r'c:\users\sdwh\desktop\logs.txt'
}

os.chdir(requestsParameter['downloadPath'])
count = 0

for url in datas:
  count += 1
  if count % requestsParameter['sleepCount'] == 0:
    time.sleep(random.randint(1, requestsParameter['sleepMaxSecs']))

  name, extension = getFileNameExtension(url)
  exists = os.path.exists(f'.\{name}.{extension}')

  print(f'{name}.{extension} ({count}/{len(datas)}) {"Exists" if exists == True else ""}')
  if exists:
    continue

  try:
    img = requests.get(url, headers=headers)
    with open(f"{name}.{extension}", "wb") as f:
      f.write(img.content)
      f.close()
  except:
    with open(requestsParameter['logsPath'], "a") as logf:
      logf.write(f'{name}.{extension} download failed\n')
      logf.close()

無法由網址預知副檔名的情境

datas.py

datas = [
    'https://via.placeholder.com/300',
    'https://via.placeholder.com/450',
]

Main

藉由 Header 的 Content/Type 來識別 extension

for url in datas.datas:
  img = requests.get(url)
  contentType = img.headers['Content-Type']
  # image/png

  extension = contentyType.split('/')[-1]

參考資料

Python Modules - Requests