Kuvien ja muiden tiedostojen lataaminen verkosta Pythonilla (yksittäin tai erissä)

liiketoiminta

Seuraavassa kerrotaan, miten Pythonissa määritetään Webissä olevan kuvan, ZIP-, PDF- tai muun tiedoston URL-osoite, ladataan se ja tallennetaan paikallisena tiedostona.

  • Lataa kuvia määrittämällä URL-osoite.
    • Esimerkki koodista
    • urllib.request.urlopen():Avaa URL-osoite
    • open():Kirjoittaminen tiedostoon binääritilassa
    • Yksinkertaisempi esimerkki koodista
  • Lataa ZIP-tiedostoja, PDF-tiedostoja jne.
  • Pura verkkosivulla olevan kuvan URL-osoite.
    • Jos numero on juokseva
    • Ote Kaunis keitto
  • Useiden kuvien lataaminen eräajona URL-osoitteiden luettelosta

Lataa kuvia määrittämällä URL-osoite.

Voit käyttää vakiokirjastoa vain yksittäisten tiedostojen lataamiseen määrittämällä niiden URL-osoitteet; lisäasennusta ei tarvita.

Esimerkki koodista

Seuraavassa on esimerkki funktiosta, joka lataa ja tallentaa tiedoston määrittämällä URL-osoitteen ja kohdepolun sekä sen käytön. Tämä koodi on selityksen vuoksi hieman laajahko. Alla on yksinkertainen esimerkki.

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)

Voit määrittää kohdehakemiston ja tallentaa tiedoston URL-tiedostonimellä seuraavasti

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)

Se poimii tiedoston nimen URL-osoitteesta os.path.basename()-komennolla ja yhdistää sen os.path.join()-komennolla määritettyyn hakemistoon luodakseen kohdepolun.

Seuraavissa kohdissa kuvataan tiedonkeruun osa ja tiedon tallentamisen osa tiedostona.

urllib.request.urlopen(): Avaa URL-osoite

Käytä urllib.request.urlopen() -ohjelmaa URL-osoitteen avaamiseen ja tietojen hakemiseen. Huomaa, että urllib.urlopen() on vanhentunut Python 2.6:ssa ja sitä aikaisemmissa versioissa. urllib.request.urlretrieve() ei ole vielä vanhentunut, mutta se saattaa tulla vanhentuneeksi tulevaisuudessa.

Jos haluat välttää pysähtymisen poikkeuksen sattuessa, ota virhe kiinni try- ja except-toiminnoilla.

Esimerkissä urllib.error on tuotu ja vain urllib.error.URLError on nimenomaisesti otettu talteen. Virheilmoitus näytetään, kun tiedoston URL-osoitetta ei ole olemassa.

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

Jos haluat ottaa kiinni myös poikkeuksia (FileNotFoundError jne.), kun tallennat paikallisesti, toimi seuraavasti.
(urllib.error.URLError, FileNotFoundError)

On myös mahdollista käyttää kolmannen osapuolen kirjastoa Requests vakiokirjaston urllib sijasta url-osoitteen avaamiseen ja tietojen saamiseen.

Kirjoittaminen tiedostoon binääritilassa komennossa open()

Tiedot, jotka voidaan saada urllib.request.urlopen() -toiminnolla, ovat tavujono (tyyppi bytes).

Open(), jonka toisena argumenttina on mode='wb', kirjoittaa tiedot binäärimuodossa. w tarkoittaa kirjoitusta ja b tarkoittaa binäärimuodossa.

Yksinkertaisempi esimerkki koodista

Sisäkkäiset with-lausekkeet voidaan kirjoittaa kerralla pilkulla erotettuna.

Tämän avulla voimme kirjoittaa seuraavan.

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)

Lataa ZIP-tiedostoja, PDF-tiedostoja jne.

Tähänastiset esimerkit koskevat kuvatiedostojen lataamista ja tallentamista, mutta koska avaamme tiedoston verkossa ja tallennamme sen paikallisena tiedostona, samoja toimintoja voidaan käyttää myös muuntyyppisiin tiedostoihin.

Voit ladata ja tallentaa tiedostoja määrittämällä URL-osoitteen.

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)

Huomaa, että tässä toiminnossa määritetyn URL-osoitteen on oltava linkki itse tiedostoon.

Esimerkiksi GitHub-repositoriotiedoston tapauksessa seuraavalla URL-osoitteella on pdf-pääte, mutta se on todellisuudessa html-sivu. Jos tämä URL-osoite määritetään yllä olevassa toiminnossa, html-lähde ladataan.

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

Linkki tiedostokokonaisuuteen on seuraava URL-osoite, joka sinun on määritettävä, jos haluat ladata ja tallentaa tiedoston.

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

On myös tapauksia, joissa pääsy on rajoitettu käyttäjäagentin, lähettäjän jne. perusteella, jolloin lataaminen on mahdotonta. Emme takaa, että kaikki tiedostot ladataan.

Requestsia on helppo käyttää pyynnön otsikoiden, kuten käyttäjäagentin, muuttamiseen tai lisäämiseen.

Pura verkkosivulla olevan kuvan URL-osoite.

Jos haluat ladata kaikki sivulla olevat kuvat kerralla, poimi ensin kuvien URL-osoitteet ja luo luettelo.

Jos numero on juokseva

Jos ladattavan kuvan URL-osoite on pelkkä juokseva numero, se on helppoa. Jos URL-osoitteet eivät ole pelkkiä juoksevia numeroita, vaan niissä on myös jonkinlaista säännönmukaisuutta, on helpompi tehdä sääntöjen mukainen luettelo URL-osoitteista kuin kaapia Beautiful Soup -ohjelmalla (ks. jäljempänä).

Käytä luettelon ymmärtämisen merkintätapaa.

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

Yllä olevassa esimerkissä {:03} käytetään kolminumeroiselle nollatäytteiselle juoksevalle numerolle; {} käytetään, kun nollatäyttö ei ole tarpeen, ja {:05} käytetään 5-numeroiselle numerolle kolmen numeron sijasta. Lisätietoja merkkijonon str format-menetelmästä on seuraavassa artikkelissa.

Tässä käytämme myös pprint-toimintoa, jotta tuloste olisi helpommin luettavissa.

Ote Kaunis keitto

Kun haluat poimia kuvien URL-osoitteita verkkosivuilta irtotavarana, käytä Beautiful Soup -ohjelmaa.

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

from bs4 import BeautifulSoup

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

Esimerkissä poimitaan tämän verkkosivuston pikkukuvan URL-osoite.

Rakenne vaihtelee verkkosivun mukaan, mutta periaatteessa se saadaan seuraavasti.

  • Hae luettelo <img>-tunnisteen objekteista määrittämällä sen lohkon luokka, id jne., joka sisältää useita kuvia, jotka haluat ladata.
    • soup.find(class_='list').find_all('img')
  • Hanki kuvan URL-osoite <img>-tunnisteen src-elementistä tai data-src-elementistä.
    • img.get('data-src')

Yllä oleva esimerkkikoodi on vain esimerkki, eikä sen taata toimivan.

Useiden kuvien lataaminen eräajona URL-osoitteiden luettelosta

Jos sinulla on luettelo URL-osoitteista, voit vain tehdä siitä for-silmukan ja kutsua funktiota lataamaan ja tallentamaan tiedoston ensimmäisellä URL-osoitteella. Tilapäisen URL-luettelon vuoksi funktiokutsu download_image_dir() on kommentoitu tässä pois.

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

Jotta palvelin ei ylikuormittuisi, käytän time.sleep() -ohjelmaa odotusajan luomiseen jokaiselle kuvan lataukselle. Yksikkö on sekunneissa, joten yllä olevassa esimerkissä tuodaan ja käytetään time-moduulia.

Esimerkki koskee kuvatiedostoja, mutta myös muita tiedostotyyppejä voidaan ladata yhdessä, kunhan ne on lueteltu.

Copied title and URL