V nadaljevanju je pojasnjeno, kako v programu Python določiti URL slike, datoteke ZIP, PDF ali druge datoteke v spletu, jo prenesti in shraniti kot lokalno datoteko.
- Prenesite slike z navedbo naslova URL.
- Primer kode
urllib.request.urlopen()
:Odprti URLopen()
:Pisanje v datoteko v binarnem načinu- Enostavnejši primer kode
- Prenesite datoteke ZIP, datoteke PDF itd.
- Izvleček naslova URL slike na spletni strani.
- Če je številka zaporedna
- Izvleček z lepo juho
- Paketni prenos več slik s seznama naslovov URL
Prenesite slike z navedbo naslova URL.
Standardno knjižnico lahko uporabite samo za prenos posameznih datotek z navedbo njihovih naslovov URL; dodatna namestitev ni potrebna.
Primer kode
V nadaljevanju je primer funkcije, ki prenese in shrani datoteko z navedbo naslova URL in ciljne poti ter njene uporabe. Ta koda je zaradi razlage nekoliko razglabljajoča. V nadaljevanju je podan preprost primer.
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)
Če želite določiti ciljni imenik in shraniti datoteko z imenom datoteke URL, naredite naslednje
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)
S funkcijo os.path.basename() izvleče ime datoteke iz naslova URL in ga poveže z imenikom, določenim s funkcijo os.path.join(), da ustvari ciljno pot.
V naslednjih razdelkih sta opisana del pridobivanja podatkov in del shranjevanja podatkov v datoteko.
urllib.request.urlopen(): Odprti URL
Uporabite urllib.request.urlopen(), da odprete naslov URL in pridobite podatke. Upoštevajte, da je urllib.urlopen() v Pythonu 2.6 in prejšnjih različicah zastarel. urllib.request.urlretrieve() še ni zastarel, vendar se lahko zgodi v prihodnosti.
Če se želite izogniti prekinitvi ob pojavu izjeme, ujemite napako s funkcijama try in except.
V primeru je uvožen urllib.error, izrecno pa je zajet samo urllib.error.URLError. Sporočilo o napaki se prikaže, če URL datoteke ne obstaja.
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
Če želite pri lokalnem shranjevanju ujeti tudi izjeme (FileNotFoundError itd.), naredite naslednje.(urllib.error.URLError, FileNotFoundError)
Namesto standardne knjižnice urllib je mogoče za odpiranje url in pridobivanje podatkov uporabiti tudi knjižnico tretje osebe Requests.
Pisanje v datoteko v binarnem načinu v open()
Podatki, ki jih je mogoče pridobiti z urllib.request.urlopen(), so niz bajtov (vrsta bajtov).
Open() z načinom='wb' kot drugim argumentom zapiše podatke v binarni obliki. w pomeni pisanje, b pa binarno.
Enostavnejši primer kode
Vgnezdene izjave z lahko zapišete naenkrat, ločene z vejicami.
Na podlagi tega lahko zapišemo naslednje.
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)
Prenesite datoteke ZIP, datoteke PDF itd.
Dosedanji primeri se nanašajo na prenašanje in shranjevanje slikovnih datotek, ker pa preprosto odpiramo datoteko na spletu in jo shranjujemo kot lokalno datoteko, lahko enake funkcije uporabimo tudi za druge vrste datotek.
Datoteke lahko prenesete in shranite tako, da določite naslov 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)
Upoštevajte, da mora biti URL, ki je naveden v tej funkciji, povezava na samo datoteko.
V primeru datoteke skladišča GitHub ima na primer naslednji naslov URL končnico pdf, vendar je v resnici stran html. Če je ta naslov URL naveden v zgornji funkciji, bo prenesen vir html.
- https://github.com/from-locals/python-snippets/blob/master/notebook/data/src/pdf/sample1.pdf
Povezava do entitete datoteke je naslednji naslov URL, ki ga morate navesti, če želite datoteko prenesti in shraniti.
- https://github.com/from-locals/python-snippets/raw/master/notebook/data/src/pdf/sample1.pdf
Obstajajo tudi primeri, ko je dostop omejen z uporabniškim agentom, napotiteljem itd., kar onemogoča prenos. Ne zagotavljamo, da bodo vse datoteke prenesene.
Za spreminjanje ali dodajanje glave zahtevka, na primer uporabniškega agenta, je enostavno uporabljati zahtevke.
Izvleček naslova URL slike na spletni strani.
Če želite prenesti vse slike na strani naenkrat, najprej izberite naslove URL slik in ustvarite seznam.
Če je številka zaporedna
Če je naslov URL slike, ki jo želite prenesti, preprosta zaporedna številka, je to enostavno. Če naslovi URL niso le zaporedne številke, ampak imajo tudi nekaj pravilnosti, je lažje sestaviti seznam naslovov URL v skladu s pravili, kot pa jih strgati s programom Beautiful Soup (glej spodaj).
Uporabite zapis za razumevanje seznama.
- Povezani članki:Uporaba zapisa za razumevanje seznamov v Pythonu
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']
V zgornjem primeru se {:03} uporablja za trimestno zaporedno številko z ničelno polnitvijo; {} se uporablja, kadar ničelna polnitev ni potrebna, {:05} pa se uporablja za petmestno številko namesto trimestne. Za več informacij o metodi formatiranja niza str si oglejte naslednji članek.
- Povezani članki:Pretvorba formata v Pythonu, format (polnjenje z ničlo, eksponentni zapis, šestnajstiški zapis itd.)
Za lažje branje izpisa uporabljamo tudi program pprint.
Izvleček z lepo juho
Za množično pridobivanje slikovnih naslovov URL s spletnih strani uporabite program Lepa juha.
import os import time import urllib.error import urllib.request from bs4 import BeautifulSoup url = 'https://sl.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 tem primeru je izpisan naslov URL sličice tega spletnega mesta.
Struktura se razlikuje glede na spletno stran, vendar je v osnovi naslednja.
- Pridobi seznam objektov oznake <img> z navedbo razreda, id itd. bloka, ki vsebuje več slik, ki jih želite prenesti.
soup.find(class_='list').find_all('img')
- Pridobite URL slike iz elementa src ali elementa data-src oznake <img>.
img.get('data-src')
Zgornja vzorčna koda je le primer in ni zagotovljeno, da bo delovala.
Paketni prenos več slik s seznama naslovov URL
Če imate seznam naslovov URL, ga lahko vključite v zanko for in pokličete funkcijo za prenos in shranjevanje datoteke s prvim prikazanim naslovom URL. Zaradi začasnega seznama naslovov URL je klic funkcije download_image_dir() tukaj komentiran.
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
Da ne bi preobremenil strežnika, s funkcijo time.sleep() ustvarim čakalni čas za vsak prenos slike. Enota je v sekundah, zato je v zgornjem primeru uvožen in uporabljen modul time.
Primer se nanaša na slikovne datoteke, vendar lahko skupaj prenesete tudi druge vrste datotek, če so navedene na seznamu.