Muat turun imej dan fail lain dari web dalam Python (secara individu atau dalam kelompok)

Perniagaan

Yang berikut menerangkan cara untuk menentukan URL imej, ZIP, PDF atau fail lain di Web dalam Python, muat turun dan simpan sebagai fail setempat.

  • Muat turun imej dengan menentukan URL.
    • Contoh kod
    • urllib.request.urlopen():Buka URL
    • open():Tulis ke fail dalam mod binari
    • Contoh kod yang lebih mudah
  • Muat turun fail ZIP, fail PDF, dsb.
  • Ekstrak URL imej pada halaman web.
    • Jika nombor itu berurutan
    • Ekstrak dengan Sup Cantik
  • Muat turun kumpulan berbilang imej daripada senarai URL

Muat turun imej dengan menentukan URL.

Anda boleh menggunakan perpustakaan standard sahaja untuk memuat turun fail individu dengan menyatakan URL mereka; tiada pemasangan tambahan diperlukan.

Contoh kod

Berikut ialah contoh fungsi yang memuat turun dan menyimpan fail dengan menentukan URL dan laluan destinasi serta penggunaannya. Kod ini agak bertele-tele untuk penjelasan. Contoh mudah diberikan di bawah.

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)

Untuk menentukan direktori destinasi dan menyimpan fail dengan nama fail URL, lakukan perkara berikut

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)

Ia mengekstrak nama fail daripada URL dengan os.path.basename() dan menyertainya dengan direktori yang ditentukan dengan os.path.join() untuk menjana laluan destinasi.

Bahagian berikut menerangkan bahagian pemerolehan data dan bahagian penyimpanan data sebagai fail.

urllib.request.urlopen():Buka URL

Gunakan urllib.request.urlopen() untuk membuka URL dan mendapatkan semula data. Ambil perhatian bahawa urllib.urlopen() telah ditamatkan dalam Python 2.6 dan lebih awal. urllib.request.urlretrieve() masih belum ditamatkan lagi, tetapi mungkin pada masa hadapan.

Untuk mengelakkan berhenti apabila pengecualian berlaku, tangkap ralat dengan cuba dan kecuali.

Dalam contoh, urllib.error diimport dan hanya urllib.error.URLError ditangkap secara eksplisit. Mesej ralat akan dipaparkan apabila URL fail tidak wujud.

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

Jika anda juga ingin menangkap pengecualian (FileNotFoundError, dll.) semasa menyimpan secara setempat, lakukan perkara berikut.
(urllib.error.URLError, FileNotFoundError)

Anda juga boleh menggunakan Permintaan perpustakaan pihak ketiga dan bukannya urllib perpustakaan standard untuk membuka url dan mendapatkan data.

Tulis ke fail dalam mod binari dalam open()

Data yang boleh diperolehi dengan urllib.request.urlopen() ialah rentetan bait (jenis bait).

Open() dengan mod=’wb’ sebagai hujah kedua menulis data sebagai binari. w bermaksud tulis dan b bermaksud binari.

Contoh kod yang lebih mudah

Bersarang dengan pernyataan boleh ditulis sekali gus, dipisahkan dengan koma.

Menggunakan ini, kita boleh menulis yang berikut.

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)

Muat turun fail ZIP, fail PDF, dsb.

Contoh setakat ini adalah untuk memuat turun dan menyimpan fail imej, tetapi memandangkan kami hanya membuka fail di web dan menyimpannya sebagai fail tempatan, fungsi yang sama boleh digunakan untuk jenis fail lain.

Anda boleh memuat turun dan menyimpan fail dengan menentukan 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)

Ambil perhatian bahawa URL yang dinyatakan dalam fungsi ini mestilah pautan ke fail itu sendiri.

Sebagai contoh, dalam kes fail repositori GitHub, URL berikut mempunyai sambungan pdf tetapi sebenarnya adalah halaman html. Jika URL ini dinyatakan dalam fungsi di atas, sumber html akan dimuat turun.

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

Pautan ke entiti fail ialah URL berikut, yang anda perlu tentukan jika anda ingin memuat turun dan menyimpan fail.

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

Terdapat juga kes di mana akses dihadkan oleh ejen pengguna, perujuk, dsb., menjadikannya mustahil untuk dimuat turun. Kami tidak menjamin bahawa semua fail akan dimuat turun.

Mudah untuk menggunakan Permintaan untuk menukar atau menambah pengepala permintaan seperti ejen pengguna.

Ekstrak URL imej pada halaman web.

Untuk memuat turun semua imej dalam halaman sekali gus, mula-mula ekstrak URL imej dan buat senarai.

Jika nombor itu berurutan

Jika URL imej yang anda ingin muat turun ialah nombor jujukan yang mudah, ia adalah mudah. Jika URL bukan sahaja nombor berjujukan tetapi juga mempunyai beberapa keteraturan, adalah lebih mudah untuk membuat senarai URL mengikut peraturan daripada mengikis dengan Sup Cantik (lihat di bawah).

Gunakan notasi pemahaman senarai.

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

Dalam contoh di atas, {:03} digunakan untuk nombor jujukan isi sifar 3 digit; {} digunakan apabila pengisian sifar tidak diperlukan dan {:05} digunakan untuk nombor 5 digit dan bukannya 3 digit. Untuk mendapatkan maklumat lanjut tentang kaedah format string str, lihat artikel berikut.

Juga, di sini kami menggunakan pprint untuk menjadikan output lebih mudah dibaca.

Ekstrak dengan Sup Cantik

Untuk mengekstrak URL imej daripada halaman web secara pukal, gunakan Sup Cantik.

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

from bs4 import BeautifulSoup

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

Dalam contoh, URL imej kecil tapak web ini diekstrak.

Struktur berbeza bergantung pada halaman web, tetapi pada asasnya ia diperoleh seperti berikut.

  • Dapatkan senarai <img> teg objek dengan menyatakan kelas, id, dsb. bagi blok yang mengandungi berbilang imej yang anda ingin muat turun.
    • soup.find(class_='list').find_all('img')
  • Dapatkan URL imej daripada elemen src atau elemen data-src bagi <img> tag.
    • img.get('data-src')

Kod sampel di atas hanyalah contoh dan tidak dijamin berfungsi.

Muat turun kumpulan berbilang imej daripada senarai URL

Jika anda mempunyai senarai URL, anda hanya boleh mengubahnya dalam gelung untuk dan memanggil fungsi untuk memuat turun dan menyimpan fail dengan URL pertama ditunjukkan. Kerana senarai URL sementara, fungsi panggilan download_image_dir() diulas di sini.

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

Untuk tidak membebankan pelayan, saya menggunakan time.sleep() untuk mencipta masa menunggu bagi setiap muat turun imej. Unit adalah dalam saat, jadi dalam contoh di atas, modul masa diimport dan digunakan.

Contohnya adalah untuk fail imej, tetapi jenis fail lain boleh dimuat turun bersama-sama juga, asalkan ia disenaraikan.