Stahování obrázků a dalších souborů z webu v jazyce Python (jednotlivě nebo v dávkách).

Podnikání

V následujícím textu je vysvětleno, jak v jazyce Python zadat adresu URL obrázku, souboru ZIP, PDF nebo jiného souboru na webu, stáhnout jej a uložit jako místní soubor.

  • Stáhněte obrázky zadáním adresy URL.
    • Příklad kódu
    • urllib.request.urlopen():Otevřít adresu URL
    • open():Zápis do souboru v binárním režimu
    • Jednodušší příklad kódu
  • Stahování souborů ZIP, PDF atd.
  • Výpis adresy URL obrázku na webové stránce.
    • Pokud je číslo sekvenční
    • Výpis s krásnou polévkou
  • Dávkové stahování více obrázků ze seznamu adres URL

Stáhněte obrázky zadáním adresy URL.

Standardní knihovnu můžete použít pouze ke stažení jednotlivých souborů zadáním jejich adresy URL; není nutná žádná další instalace.

Příklad kódu

Následuje příklad funkce, která stáhne a uloží soubor zadáním adresy URL a cílové cesty a jejím použitím. Tento kód je kvůli vysvětlení poněkud mnohomluvný. Jednoduchý příklad je uveden níže.

import os
import pprint
import time
import urllib.error
import urllib.request

def download_file(url, dst_path):
    try:
        with urllib.request.urlopen(url) as web_file:
            data = web_file.read()
            with open(dst_path, mode='wb') as local_file:
                local_file.write(data)
    except urllib.error.URLError as e:
        print(e)
url = 'https://www.python.org/static/img/python-logo.png'
dst_path = 'data/temp/py-logo.png'
download_file(url, dst_path)

Chcete-li zadat cílový adresář a uložit soubor s názvem URL, postupujte takto.

def download_file_to_dir(url, dst_dir):
    download_file(url, os.path.join(dst_dir, os.path.basename(url)))

dst_dir = 'data/temp'
download_file_to_dir(url, dst_dir)

Pomocí funkce os.path.basename() extrahuje název souboru z adresy URL a spojí jej s adresářem zadaným pomocí funkce os.path.join(), čímž vytvoří cílovou cestu.

Následující části popisují část sběru dat a část ukládání dat do souboru.

urllib.request.urlopen(): Otevřít adresu URL

Pomocí urllib.request.urlopen() otevřete adresu URL a získáte data. Všimněte si, že funkce urllib.urlopen() byla v Pythonu 2.6 a starších verzích zrušena. urllib.request.urlretrieve() zatím zrušena nebyla, ale v budoucnu se tak může stát.

Chcete-li se vyhnout zastavení při výskytu výjimky, zachyťte chybu pomocí try a except.

V příkladu je importován soubor urllib.error a explicitně je zachycen pouze urllib.error.URLError. Chybové hlášení se zobrazí, pokud URL souboru neexistuje.

url_error = 'https://www.python.org/static/img/python-logo_xxx.png'
download_file_to_dir(url_error, dst_dir)
# HTTP Error 404: Not Found

Pokud chcete při lokálním ukládání zachytit také výjimky (FileNotFoundError atd.), postupujte takto.
(urllib.error.URLError, FileNotFoundError)

K otevření url a získání dat je také možné použít knihovnu třetí strany Requests namísto standardní knihovny urllib.

Zápis do souboru v binárním režimu v open()

Data, která lze získat pomocí urllib.request.urlopen(), jsou řetězce bajtů (typ bytes).

Open() s mode='wb' jako druhým argumentem zapíše data jako binární. w znamená zápis a b znamená binární.

Jednodušší příklad kódu

Vnořené příkazy s lze psát najednou, oddělené čárkami.

Na základě toho můžeme napsat následující.

def download_file(url, dst_path):
    try:
        with urllib.request.urlopen(url) as web_file, open(dst_path, 'wb') as local_file:
            local_file.write(web_file.read())
    except urllib.error.URLError as e:
        print(e)

Stahování souborů ZIP, PDF atd.

Dosud uvedené příklady se týkají stahování a ukládání obrázkových souborů, ale vzhledem k tomu, že jednoduše otevíráme soubor na webu a ukládáme jej jako místní soubor, lze stejné funkce použít i pro jiné typy souborů.

Soubory můžete stahovat a ukládat zadáním adresy URL.

url_zip = 'https://from-locas.com/sample_header.csv.zip'
download_file_to_dir(url_zip, dst_dir)

url_xlsx = 'https://from-locas/sample.xlsx'
download_file_to_dir(url_xlsx, dst_dir)

url_pdf = 'https://from-locas/sample1.pdf'
download_file_to_dir(url_pdf, dst_dir)

Všimněte si, že adresa URL zadaná v této funkci musí být odkazem na samotný soubor.

Například v případě souboru úložiště GitHub má následující adresa URL příponu pdf, ale ve skutečnosti se jedná o stránku html. Pokud je tato adresa URL zadána ve výše uvedené funkci, bude stažen zdroj html.

  • https://github.com/from-locals/python-snippets/blob/master/notebook/data/src/pdf/sample1.pdf

Odkazem na entitu souboru je následující adresa URL, kterou je třeba zadat, pokud chcete soubor stáhnout a uložit.

  • https://github.com/from-locals/python-snippets/raw/master/notebook/data/src/pdf/sample1.pdf

Existují také případy, kdy je přístup omezen podle agenta uživatele, odkazu atd., což znemožňuje stahování. Nezaručujeme, že budou staženy všechny soubory.

Pomocí aplikace Požadavky lze snadno měnit nebo přidávat hlavičky požadavků, například agenta uživatele.

Výpis adresy URL obrázku na webové stránce.

Chcete-li stáhnout všechny obrázky na stránce najednou, nejprve extrahujte adresy URL obrázků a vytvořte jejich seznam.

Pokud je číslo sekvenční

Pokud je adresa URL obrázku, který chcete stáhnout, jednoduché pořadové číslo, je to snadné. Pokud adresy URL nejsou jen pořadová čísla, ale mají i určitou pravidelnost, je jednodušší vytvořit seznam adres URL podle pravidel než škrábat pomocí Beautiful Soup (viz níže).

Použijte zápis pro porozumění seznamu.

url_list = ['https://example.com/basedir/base_{:03}.jpg'.format(i) for i in range(5)]
pprint.pprint(url_list)
# ['https://example.com/basedir/base_000.jpg',
#  'https://example.com/basedir/base_001.jpg',
#  'https://example.com/basedir/base_002.jpg',
#  'https://example.com/basedir/base_003.jpg',
#  'https://example.com/basedir/base_004.jpg']

Ve výše uvedeném příkladu se {:03} používá pro třímístné pořadové číslo vyplněné nulou; {} se používá, pokud vyplnění nulou není nutné, a {:05} se používá pro pětimístné číslo místo třímístného. Další informace o metodě formátování řetězce str naleznete v následujícím článku.

Také zde používáme pprint, aby byl výstup lépe čitelný.

Výpis s krásnou polévkou

Chcete-li hromadně extrahovat adresy URL obrázků z webových stránek, použijte aplikaci Beautiful Soup.

import os
import time
import urllib.error
import urllib.request

from bs4 import BeautifulSoup

url = 'https://cs.from-locals.com/'
ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) '\
     'AppleWebKit/537.36 (KHTML, like Gecko) '\
     'Chrome/55.0.2883.95 Safari/537.36 '

req = urllib.request.Request(url, headers={'User-Agent': ua})
html = urllib.request.urlopen(req)

soup = BeautifulSoup(html, "html.parser")

url_list = [img.get('data-src') for img in soup.find(class_='list').find_all('img')]

V příkladu je extrahována adresa URL miniatury obrázku této webové stránky.

Struktura se liší v závislosti na webové stránce, ale v zásadě se získá následujícím způsobem.

  • Získání seznamu objektů značky <img> zadáním třídy, id atd. bloku obsahujícího více obrázků, které chcete stáhnout.
    • soup.find(class_='list').find_all('img')
  • Získejte adresu URL obrázku z prvku src nebo data-src tagu <img>.
    • img.get('data-src')

Výše uvedený ukázkový kód je pouze příkladem a není zaručeno, že bude fungovat.

Dávkové stahování více obrázků ze seznamu adres URL

Pokud máte seznam adres URL, můžete jej jednoduše otočit do smyčky for a zavolat funkci pro stažení a uložení souboru s první zobrazenou adresou URL. Kvůli dočasnému seznamu URL je zde volání funkce download_image_dir() zakomentováno.

download_dir = 'data/temp'
sleep_time_sec = 1

for url in url_list:
    print(url)
#     download_file_dir(url, download_dir)
    time.sleep(sleep_time_sec)
# https://example.com/basedir/base_000.jpg
# https://example.com/basedir/base_001.jpg
# https://example.com/basedir/base_002.jpg
# https://example.com/basedir/base_003.jpg
# https://example.com/basedir/base_004.jpg

Abych nepřetěžoval server, používám time.sleep() k vytvoření čekací doby pro každé stažení obrázku. Jednotka je v sekundách, takže ve výše uvedeném příkladu je importován a použit modul time.

Příklad se týká obrázkových souborů, ale společně lze stahovat i jiné typy souborů, pokud jsou uvedeny v seznamu.

Copied title and URL