Im Folgenden wird erläutert, wie Sie in Python die URL einer Bild-, ZIP-, PDF- oder anderen Datei im Web angeben, sie herunterladen und als lokale Datei speichern.
- Bilder durch Angabe der URL herunterladen.
- Code-Beispiel
urllib.request.urlopen()
:URL öffnenopen()
:Schreiben in eine Datei im Binärmodus- Ein einfacheres Codebeispiel
- Herunterladen von ZIP-Dateien, PDF-Dateien, usw.
- Extrahieren Sie die URL des Bildes auf der Webseite.
- Wenn die Nummer fortlaufend ist
- Auszug mit Beautiful Soup
- Batch-Download mehrerer Bilder aus einer Liste von URLs
Bilder durch Angabe der URL herunterladen.
Sie können die Standardbibliothek nur zum Herunterladen einzelner Dateien verwenden, indem Sie deren URLs angeben; eine zusätzliche Installation ist nicht erforderlich.
Code-Beispiel
Im Folgenden finden Sie ein Beispiel für eine Funktion, die eine Datei herunterlädt und speichert, indem sie die URL und den Zielpfad sowie deren Verwendung angibt. Dieser Code ist etwas ausführlich, um ihn zu erklären. Ein einfaches Beispiel ist unten angegeben.
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)
Um das Zielverzeichnis anzugeben und die Datei unter dem URL-Dateinamen zu speichern, gehen Sie wie folgt vor
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)
Es extrahiert den Dateinamen aus der URL mit os.path.basename() und verbindet ihn mit dem mit os.path.join() angegebenen Verzeichnis, um den Zielpfad zu erzeugen.
Die folgenden Abschnitte beschreiben den Teil der Datenerfassung und den Teil der Datenspeicherung als Datei.
urllib.request.urlopen(): URL öffnen
Verwenden Sie urllib.request.urlopen(), um die URL zu öffnen und die Daten abzurufen. Beachten Sie, dass urllib.urlopen() in Python 2.6 und früher veraltet ist. urllib.request.urlretrieve() ist noch nicht veraltet, könnte es aber in Zukunft sein.
Um zu vermeiden, dass Sie beim Auftreten einer Ausnahme anhalten, fangen Sie den Fehler mit try und except ab.
Im Beispiel wird urllib.error importiert und nur urllib.error.URLError wird explizit erfasst. Die Fehlermeldung wird angezeigt, wenn die URL der Datei nicht vorhanden ist.
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
Wenn Sie beim lokalen Speichern auch Ausnahmen (FileNotFoundError usw.) abfangen wollen, gehen Sie wie folgt vor.(urllib.error.URLError, FileNotFoundError)
Es ist auch möglich, die Drittanbieter-Bibliothek Requests anstelle der Standardbibliothek urllib zu verwenden, um die URL zu öffnen und die Daten zu erhalten.
Schreiben in eine Datei im Binärmodus in open()
Die Daten, die mit urllib.request.urlopen() abgerufen werden können, sind ein Byte-String (Typ Bytes).
Open() mit mode='wb' als zweitem Argument schreibt die Daten im Binärformat. w bedeutet write und b bedeutet binär.
Ein einfacheres Codebeispiel
Verschachtelte with-Anweisungen können auf einmal geschrieben werden, getrennt durch Kommas.
Daraus lässt sich folgendes ableiten.
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)
Herunterladen von ZIP-Dateien, PDF-Dateien, usw.
Die bisherigen Beispiele beziehen sich auf das Herunterladen und Speichern von Bilddateien. Da wir jedoch lediglich eine Datei im Internet öffnen und als lokale Datei speichern, können die gleichen Funktionen auch für andere Dateitypen verwendet werden.
Sie können Dateien herunterladen und speichern, indem Sie die URL angeben.
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)
Beachten Sie, dass die in dieser Funktion angegebene URL ein Link auf die Datei selbst sein muss.
Im Falle einer GitHub-Repository-Datei hat die folgende URL beispielsweise eine PDF-Erweiterung, ist aber eigentlich eine HTML-Seite. Wenn diese URL in der obigen Funktion angegeben wird, wird die HTML-Quelle heruntergeladen.
- https://github.com/from-locals/python-snippets/blob/master/notebook/data/src/pdf/sample1.pdf
Der Link zur Datei-Entität ist die folgende URL, die Sie angeben müssen, wenn Sie die Datei herunterladen und speichern möchten.
- https://github.com/from-locals/python-snippets/raw/master/notebook/data/src/pdf/sample1.pdf
Es gibt auch Fälle, in denen der Zugang durch einen Benutzer-Agenten, einen Referrer usw. eingeschränkt ist, so dass ein Download nicht möglich ist. Wir garantieren nicht, dass alle Dateien heruntergeladen werden können.
Es ist einfach, Requests zum Ändern oder Hinzufügen von Request-Headern wie z. B. User Agent zu verwenden.
Extrahieren Sie die URL des Bildes auf der Webseite.
Um alle Bilder einer Seite auf einmal herunterzuladen, extrahieren Sie zunächst die URLs der Bilder und erstellen Sie eine Liste.
Wenn die Nummer fortlaufend ist
Wenn die URL des Bildes, das Sie herunterladen möchten, eine einfache fortlaufende Nummer ist, ist es einfach. Wenn die URLs nicht nur fortlaufende Nummern sind, sondern auch eine gewisse Regelmäßigkeit aufweisen, ist es einfacher, eine Liste von URLs nach den Regeln zu erstellen, als mit Beautiful Soup zu scrapen (siehe unten).
Verwenden Sie die Notation des Listenverständnisses.
- Verwandte Artikel:Verwendung der Python-Notation für Listenauflösungen
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']
Im obigen Beispiel wird {:03} für eine dreistellige, mit Nullen aufgefüllte fortlaufende Nummer verwendet; {} wird verwendet, wenn das Auffüllen mit Nullen nicht notwendig ist, und {:05} wird für eine fünfstellige Nummer anstelle von drei Ziffern verwendet. Weitere Informationen über die Formatierungsmethode von string str finden Sie im folgenden Artikel.
- Verwandte Artikel:Formatkonvertierung in Python, Format (Nullen, Exponentialschreibweise, Hexadezimal, usw.)
Außerdem verwenden wir hier pprint, um die Ausgabe besser lesbar zu machen.
Auszug mit Beautiful Soup
Um Bild-URLs aus Webseiten in Massen zu extrahieren, verwenden Sie Beautiful Soup.
import os import time import urllib.error import urllib.request from bs4 import BeautifulSoup url = 'https://de.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')]
In diesem Beispiel wird die URL des Miniaturbildes dieser Website extrahiert.
Die Struktur variiert je nach Webseite, aber im Grunde wird sie wie folgt erhalten.
- Rufen Sie eine Liste von <img>-Tag-Objekten ab, indem Sie die Klasse, ID usw. des Blocks angeben, der die mehreren Bilder enthält, die Sie herunterladen möchten.
soup.find(class_='list').find_all('img')
- Beziehen Sie die URL des Bildes aus dem src-Element oder data-src-Element des <img>-Tags.
img.get('data-src')
Der obige Beispielcode ist nur ein Beispiel und garantiert nicht, dass er funktioniert.
Batch-Download mehrerer Bilder aus einer Liste von URLs
Wenn Sie eine Liste von URLs haben, können Sie diese einfach in eine for-Schleife verwandeln und die Funktion zum Herunterladen und Speichern der Datei mit der ersten angezeigten URL aufrufen. Wegen der temporären URL-Liste ist der Funktionsaufruf download_image_dir() hier auskommentiert.
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
Um den Server nicht zu überlasten, verwende ich time.sleep(), um eine Wartezeit für jeden Bilddownload zu erzeugen. Die Einheit ist in Sekunden, daher wird im obigen Beispiel das Zeitmodul importiert und verwendet.
Das Beispiel bezieht sich auf Bilddateien, aber auch andere Dateitypen können zusammen heruntergeladen werden, sofern sie aufgelistet sind.