Piltide ja muude failide allalaadimine veebist Pythonis (üksikult või partiidena)

Äri

Järgnevalt selgitatakse, kuidas Pythonis määrata veebis oleva pildi, ZIP-, PDF- või muu faili URL-aadress, laadida see alla ja salvestada see kohaliku failina.

  • Piltide allalaadimine, määrates URL-aadressi.
    • Koodinäide
    • urllib.request.urlopen():Avatud URL
    • open():Kirjutamine faili binaarses režiimis
    • Lihtsam koodinäide
  • ZIP-failide, PDF-failide jne allalaadimine.
  • Eraldage veebilehe pildi URL-aadress.
    • Kui number on järjestikune
    • Väljavõte ilusa supiga
  • Mitme pildi partii allalaadimine URL-ide loendist

Piltide allalaadimine, määrates URL-aadressi.

Standardraamatukogu saate kasutada ainult üksikute failide allalaadimiseks, määrates nende URL-aadressid; lisainstallatsiooni ei ole vaja.

Koodinäide

Järgnevalt on toodud näide funktsioonist, mis laeb alla ja salvestab faili, määrates URL-i ja sihtkoha tee ning selle kasutamise. See kood on selgituse huvides veidi laialivalguv. Allpool on toodud lihtne näide.

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)

Sihtkataloogi määramiseks ja faili salvestamiseks URL-faili nimega tehke järgmist

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)

See ekstraheerib failinime URL-ist os.path.basename() abil ja ühendab selle os.path.join() abil määratud kataloogiga, et luua sihtkoha teekond.

Järgnevalt kirjeldatakse andmete kogumise osa ja andmete failina salvestamise osa.

urllib.request.urlopen(): Avatud URL

Kasutage urllib.request.urlopen(), et avada URL ja saada andmeid. Pange tähele, et urllib.urlopen() on Python 2.6 ja varasemates versioonides aegunud. urllib.request.urlretrieve() ei ole veel aegunud, kuid võib olla tulevikus.

Et vältida peatumist, kui tekib erand, püüdke viga try ja except abil.

Näites on urllib.error imporditud ja ainult urllib.error.URLError on selgesõnaliselt salvestatud. Veateade kuvatakse, kui faili URL ei ole olemas.

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

Kui soovite lokaalsel salvestamisel ka erandeid (FileNotFoundError jne) püüda, tehke järgmist.
(urllib.error.URLError, FileNotFoundError)

Samuti on võimalik kasutada URL-i avamiseks ja andmete saamiseks standardraamatukogu urllib asemel kolmanda osapoole raamatukogu Requests.

Kirjutamine faili binaarses režiimis funktsioonis open()

Andmed, mida saab urllib.request.urlopen() abil saada, on baitide string (baitide tüüp).

Open(), mille teise argumendina on mode='wb', kirjutab andmed binaarselt. w tähendab kirjutamist ja b tähendab binaarselt.

Lihtsam koodinäide

Sisestatud koos avaldused võib kirjutada korraga, eraldatuna komadega.

Seda kasutades saame kirjutada järgmist.

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)

ZIP-failide, PDF-failide jne allalaadimine.

Senised näited on mõeldud pildifailide allalaadimiseks ja salvestamiseks, kuid kuna me lihtsalt avame faili veebis ja salvestame selle kohaliku failina, saab samu funktsioone kasutada ka muud tüüpi failide puhul.

Saate faile alla laadida ja salvestada, määrates URL-aadressi.

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)

Pange tähele, et selles funktsioonis määratud URL peab olema faili enda link.

Näiteks GitHubi repositooriumi faili puhul on järgmisel URL-l pdf-laiend, kuid tegelikult on tegemist html-leheküljega. Kui see URL on ülaltoodud funktsioonis määratud, laaditakse alla html-allika.

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

Failiüksuse link on järgmine URL, mille peate täpsustama, kui soovite faili alla laadida ja salvestada.

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

On ka juhtumeid, kus juurdepääs on piiratud kasutajaagentide, viitajate jne alusel, mis muudab allalaadimise võimatuks. Me ei garanteeri, et kõik failid saab alla laadida.

Requests'i on lihtne kasutada päringu päiste, näiteks kasutajaagendi muutmiseks või lisamiseks.

Eraldage veebilehe pildi URL-aadress.

Selleks, et laadida alla kõik lehel olevad pildid korraga, eraldage kõigepealt piltide URL-aadressid ja koostage nimekiri.

Kui number on järjestikune

Kui allalaaditava pildi URL on lihtne järjekorranumber, on see lihtne. Kui URL-id ei ole ainult järjekorranumbrid, vaid neil on ka mingi korrapärasus, on lihtsam teha reeglite järgi URL-ide nimekiri, mitte kraapida Beautiful Soupiga (vt allpool).

Kasutage loetelu mõistmise märkimist.

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

Ülaltoodud näites kasutatakse {:03} 3-kohalise nulliga täidetud järjekorranumbri puhul; {} kasutatakse, kui nulliga täitmine ei ole vajalik, ja {:05} kasutatakse 5-kohalise numbri puhul 3 numbri asemel. Lisateavet string str-i vormingumeetodi kohta leiate järgmisest artiklist.

Samuti kasutame siin pprint'i, et väljundit oleks lihtsam lugeda.

Väljavõte ilusa supiga

Pildi URL-aadresside hulgi väljavõtmiseks veebilehtedelt kasutage Beautiful Soup'i.

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

from bs4 import BeautifulSoup

url = 'https://et.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äites ekstraheeritakse selle veebisaidi pisipildi URL-aadress.

Struktuur varieerub sõltuvalt veebilehest, kuid põhimõtteliselt saadakse see järgmiselt.

  • Hangi nimekiri <img> sildi objektidest, määrates selle ploki klassi, id jne, mis sisaldab mitut pilti, mida soovid alla laadida.
    • soup.find(class_='list').find_all('img')
  • Saage pildi URL aadress <img> sildi src elemendist või data-src elemendist.
    • img.get('data-src')

Ülaltoodud näidiskood on vaid näide ja selle toimimine ei ole garanteeritud.

Mitme pildi partii allalaadimine URL-ide loendist

Kui teil on olemas URL-ide nimekiri, võite lihtsalt keerata selle for-tsüklisse ja kutsuda funktsiooni, et laadida alla ja salvestada faili esimese näidatud URL-iga. Ajutise URL-loendi tõttu on funktsiooni download_image_dir() üleskutse siin välja kommenteeritud.

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

Selleks, et mitte üle koormata serverit, kasutan time.sleep(), et luua iga pildi allalaadimise jaoks ooteaeg. Ühik on sekundites, seega on ülaltoodud näites imporditud ja kasutatud time-moodulit.

Näide puudutab pildifaile, kuid ka muud tüüpi faile võib koos alla laadida, kui need on loetletud.