A continuación explícase como especificar o URL dunha imaxe, ZIP, PDF ou outro ficheiro na web en Python, descargalo e gardalo como ficheiro local.
- Descarga imaxes especificando o URL.
- Exemplo de código
urllib.request.urlopen()
:Abrir URLopen()
:Escribir nun ficheiro en modo binario- Un exemplo de código máis sinxelo
- Descargar ficheiros ZIP, PDF, etc.
- Extrae o URL da imaxe da páxina web.
- Se o número é secuencial
- Extracto con bonita sopa
- Descarga por lotes varias imaxes dunha lista de URL
Descarga imaxes especificando o URL.
Podes usar a biblioteca estándar só para descargar ficheiros individuais especificando os seus URL; non se precisa instalación adicional.
Exemplo de código
O seguinte é un exemplo dunha función que descarga e garda un ficheiro especificando o URL e o camiño de destino e o seu uso. Este código é un pouco detallado para explicar. A continuación dáse un exemplo sinxelo.
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)
Para especificar o directorio de destino e gardar o ficheiro co nome do ficheiro URL, faga o seguinte
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)
Extrae o nome do ficheiro do URL con os.path.basename() e únese ao directorio especificado con os.path.join() para xerar o camiño de destino.
Nas seguintes seccións descríbense a parte da adquisición de datos e a parte dos datos gardados como ficheiro.
urllib.request.urlopen():Abrir URL
Use urllib.request.urlopen() para abrir o URL e recuperar os datos. Teña en conta que urllib.urlopen() quedou en desuso en Python 2.6 e anteriores. urllib.request.urlretrieve() aínda non quedou en desuso, pero pode estarlo no futuro.
Para evitar deterse cando se produce unha excepción, detecta o erro con try e except.
No exemplo, impórtase urllib.error e só se captura explícitamente urllib.error.URLError. A mensaxe de erro mostrarase cando o URL do ficheiro non exista.
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
Se tamén queres detectar excepcións (FileNotFoundError, etc.) ao gardar localmente, fai o seguinte.(urllib.error.URLError, FileNotFoundError)
Tamén é posible usar as solicitudes de bibliotecas de terceiros en lugar do urllib da biblioteca estándar para abrir o URL e obter os datos.
Escribir nun ficheiro en modo binario en open()
Os datos que se poden obter con urllib.request.urlopen() son unha cadea de bytes (tipo bytes).
Open() con mode=’wb’ como segundo argumento escribe os datos como binarios. w significa escribir e b significa binario.
Un exemplo de código máis sinxelo
Anidados con declaracións pódense escribir á vez, separados por comas.
Usando isto, podemos escribir o seguinte.
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)
Descargar ficheiros ZIP, PDF, etc.
Os exemplos ata agora son para descargar e gardar ficheiros de imaxe, pero como simplemente estamos abrindo un ficheiro na web e gardándoo como un ficheiro local, pódense utilizar as mesmas funcións para outro tipo de ficheiros.
Podes descargar e gardar ficheiros especificando o 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)
Teña en conta que o URL especificado nesta función debe ser unha ligazón ao propio ficheiro.
Por exemplo, no caso dun ficheiro de repositorio de GitHub, o seguinte URL ten unha extensión pdf pero en realidade é unha páxina html. Se se especifica este URL na función anterior, descargarase a fonte html.
- https://github.com/from-locals/python-snippets/blob/master/notebook/data/src/pdf/sample1.pdf
A ligazón á entidade do ficheiro é o seguinte URL, que debes especificar se queres descargar e gardar o ficheiro.
- https://github.com/from-locals/python-snippets/raw/master/notebook/data/src/pdf/sample1.pdf
Tamén hai casos nos que o acceso está restrinxido polo axente de usuario, o referente, etc., o que fai imposible a descarga. Non garantimos que se descarguen todos os ficheiros.
É doado de usar Solicitudes para cambiar ou engadir cabeceiras de solicitudes como o axente de usuario.
Extrae o URL da imaxe da páxina web.
Para descargar todas as imaxes dunha páxina á vez, primeiro extrae os URL das imaxes e crea unha lista.
Se o número é secuencial
Se o URL da imaxe que queres descargar é un simple número secuencial, é doado. Se os URL non son só números secuenciais senón que tamén teñen certa regularidade, é máis fácil facer unha lista de URL segundo as regras en lugar de raspar con Beautiful Soup (ver máis abaixo).
Usa a notación de comprensión de listas.
- Artigos relacionados:Usando a notación de comprensións de listas de Python
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']
No exemplo anterior, {:03} úsase para un número secuencial de 3 díxitos con cero; {} úsase cando non é necesario o recheo de cero e {:05} úsase para un número de 5 díxitos en lugar de 3 díxitos. Para obter máis información sobre o método de formato da cadea str, consulte o seguinte artigo.
- Artigos relacionados:Conversión de formato en Python, formato (recheo cero, notación exponencial, hexadecimal, etc.)
Ademais, aquí estamos usando pprint para facilitar a lectura da saída.
Extracto con bonita sopa
Para extraer URL de imaxes de páxinas web de forma masiva, utiliza Beautiful Soup.
import os import time import urllib.error import urllib.request from bs4 import BeautifulSoup url = 'https://gl.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')]
No exemplo, extráese o URL da imaxe en miniatura deste sitio web.
A estrutura varía segundo a páxina web, pero basicamente obtense do seguinte xeito.
- Obter unha lista de <img> etiqueta os obxectos especificando a clase, id, etc. do bloque que contén as varias imaxes que queres descargar.
soup.find(class_='list').find_all('img')
- Obter o URL da imaxe do elemento src ou do elemento data-src do <img> etiqueta.
img.get('data-src')
O código de mostra anterior é só un exemplo e non se garante que funcione.
Descarga por lotes varias imaxes dunha lista de URL
Se tes unha lista de URL, podes transformala nun bucle for e chamar á función para descargar e gardar o ficheiro co primeiro URL mostrado. Debido á lista de URL temporal, a chamada de función download_image_dir() é comentada aquí.
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
Para non sobrecargar o servidor, uso time.sleep() para crear un tempo de espera para cada descarga de imaxe. A unidade está en segundos, polo que no exemplo anterior impórtase e úsase o módulo de tempo.
O exemplo é para ficheiros de imaxe, pero tamén se poden descargar outros tipos de ficheiros xuntos, sempre que estean listados.