Descărcați imagini și alte fișiere de pe web în Python (individual sau în loturi)

Afaceri

În cele ce urmează se explică cum să specificați în Python adresa URL a unei imagini, a unui fișier ZIP, PDF sau a altui fișier de pe Web, să îl descărcați și să îl salvați ca fișier local.

  • Descărcați imagini prin specificarea URL-ului.
    • Exemplu de cod
    • urllib.request.urlopen():Deschideți URL-ul
    • open():Scrieți într-un fișier în modul binar
    • Un exemplu de cod mai simplu
  • Descărcați fișiere ZIP, fișiere PDF etc.
  • Extrageți adresa URL a imaginii de pe pagina web.
    • În cazul în care numărul este secvențial
    • Extract cu Beautiful Soup
  • Descărcați pe loturi mai multe imagini dintr-o listă de URL-uri

Descărcați imagini prin specificarea URL-ului.

Puteți utiliza biblioteca standard numai pentru a descărca fișiere individuale prin specificarea URL-urilor acestora; nu este necesară nicio instalare suplimentară.

Exemplu de cod

Următorul este un exemplu de funcție care descarcă și salvează un fișier prin specificarea adresei URL și a căii de destinație, precum și utilizarea acestuia. Acest cod este un pic mai stufos, pentru a fi explicat. Un exemplu simplu este dat mai jos.

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)

Pentru a specifica directorul de destinație și a salva fișierul cu numele de fișier URL, procedați după cum urmează

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)

Acesta extrage numele fișierului din URL cu os.path.basename() și îl unește cu directorul specificat cu os.path.join() pentru a genera calea de destinație.

Următoarele secțiuni descriu partea de achiziție a datelor și partea de salvare a datelor sub formă de fișier.

urllib.request.urlopen(): Deschideți URL-ul

Utilizați urllib.request.urlopen() pentru a deschide URL-ul și a prelua datele. Rețineți că urllib.urlopen() a fost depreciat în Python 2.6 și versiunile anterioare. urllib.request.urlretrieve() nu a fost încă depreciat, dar ar putea fi depreciat în viitor.

Pentru a evita oprirea la apariția unei excepții, prindeți eroarea cu try și except.

În exemplu, urllib.error este importat și numai urllib.error.URLError este capturat în mod explicit. Mesajul de eroare va fi afișat în cazul în care URL-ul fișierului nu există.

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

Dacă doriți să prindeți și excepții (FileNotFoundError, etc.) la salvarea locală, procedați după cum urmează.
(urllib.error.URLError, FileNotFoundError)

De asemenea, este posibil să se utilizeze biblioteca terță parte Requests în locul bibliotecii standard urllib pentru a deschide adresa URL și a obține datele.

Scrierea într-un fișier în modul binar în open()

Datele care pot fi obținute cu urllib.request.urlopen() sunt un șir de octeți (tip bytes).

Open() cu mode='wb' ca al doilea argument scrie datele sub formă binară. w înseamnă scris și b înseamnă binar.

Un exemplu de cod mai simplu

Instrucțiunile „with” imbricate pot fi scrise simultan, separate prin virgule.

Folosind acest lucru, putem scrie următoarele.

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)

Descărcați fișiere ZIP, fișiere PDF etc.

Exemplele de până acum se referă la descărcarea și salvarea fișierelor de imagine, dar, din moment ce deschidem pur și simplu un fișier de pe web și îl salvăm ca fișier local, aceleași funcții pot fi utilizate și pentru alte tipuri de fișiere.

Puteți descărca și salva fișiere prin specificarea URL-ului.

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)

Rețineți că URL-ul specificat în această funcție trebuie să fie un link către fișierul în sine.

De exemplu, în cazul unui fișier din depozitul GitHub, următorul URL are extensia pdf, dar este de fapt o pagină html. Dacă această adresă URL este specificată în funcția de mai sus, sursa html va fi descărcată.

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

Linkul către entitatea de fișier este următoarea adresă URL, pe care trebuie să o specificați dacă doriți să descărcați și să salvați fișierul.

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

Există, de asemenea, cazuri în care accesul este restricționat în funcție de user agent, referrer etc., ceea ce face imposibilă descărcarea. Nu garantăm că toate fișierele vor fi descărcate.

Este ușor de utilizat Requests pentru a modifica sau adăuga anteturi de cerere, cum ar fi user agent.

Extrageți adresa URL a imaginii de pe pagina web.

Pentru a descărca simultan toate imaginile dintr-o pagină, extrageți mai întâi adresele URL ale imaginilor și creați o listă.

În cazul în care numărul este secvențial

Dacă adresa URL a imaginii pe care doriți să o descărcați este un simplu număr secvențial, este ușor. Dacă URL-urile nu sunt doar numere secvențiale, ci au și o anumită regularitate, este mai ușor să faceți o listă de URL-uri în conformitate cu regulile decât să faceți scraping cu Beautiful Soup (a se vedea mai jos).

Utilizați notația de înțelegere a listei.

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']

În exemplul de mai sus, {:03} este utilizat pentru un număr secvențial de 3 cifre completat cu zero; {} este utilizat atunci când nu este necesară completarea cu zero, iar {:05} este utilizat pentru un număr de 5 cifre în loc de 3 cifre. Pentru mai multe informații despre metoda de formatare a șirului de caractere str, consultați următorul articol.

De asemenea, aici folosim pprint pentru a face ca rezultatul să fie mai ușor de citit.

Extract cu Beautiful Soup

Pentru a extrage în masă URL-uri de imagini din pagini web, utilizați Beautiful Soup.

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

from bs4 import BeautifulSoup

url = 'https://ro.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')]

În exemplu, este extrasă adresa URL a imaginii în miniatură a acestui site web.

Structura variază în funcție de pagina web, dar, în principiu, se obține după cum urmează.

  • Obține o listă de obiecte ale etichetei <img> prin specificarea clasei, id-ului, etc. ale blocului care conține imaginile multiple pe care doriți să le descărcați.
    • soup.find(class_='list').find_all('img')
  • Obțineți URL-ul imaginii din elementul src sau din elementul data-src al etichetei <img>.
    • img.get('data-src')

Modelul de cod de mai sus este doar un exemplu și nu este garantat că va funcționa.

Descărcați pe loturi mai multe imagini dintr-o listă de URL-uri

Dacă aveți o listă de adrese URL, puteți să o transformați într-o buclă for și să apelați funcția pentru a descărca și salva fișierul cu prima adresă URL afișată. Din cauza listei temporare de URL-uri, apelul funcției download_image_dir() este comentat aici.

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

Pentru a nu supraîncărca serverul, folosesc time.sleep() pentru a crea un timp de așteptare pentru fiecare imagine descărcată. Unitatea de măsură este în secunde, așa că în exemplul de mai sus, modulul time este importat și utilizat.

Exemplul este pentru fișiere de imagine, dar și alte tipuri de fișiere pot fi descărcate împreună, atâta timp cât sunt listate.

Copied title and URL