Python TagebuchPython lernen – mein persönliches Tagebuch

Tagebuch-Eintrag #53
Dateien aus dem US National Archiv automatisch herunterladen

Browser-Automatisierung mit Selenium. Mein erstes Python-Projekt mit Selenium. Und es funktioniert prima!
Werbung/Anzeige

Für ein Hobby von mir sind Informationen aus dem US National Archiv sehr interessant und hilfreich für die Recherche. Die Dokumenten sind öffentlich zugänglich und können von der Webseite des National Archivs heruntergeladen werden.

Jedoch gestaltet sich der Download der Dateien sehr mühselig. Die Dateien befinden sich in einem „Ordner“, die mit einem Link aufgerufen werden. In einem Ordner können mehrere Dateien vorhanden sein. Meistens zwischen 15 und 30. (1) Man muss jede Datei anklicken und (2) danach den Download-Button anklicken. (3) Anschließend öffnet sich die JPG-Datei in einem neuen Tab. (4) Diese Datei muss ich wiederum manuell abspeichern.

Das mag für eine handvoll Dateien in einem „Ordner“, die ich herunterladen möchte funktionieren. Bei 15 oder gar 50 bis 90 Dateien, die in Ausnahmefällen vorkommen, macht es keinen Spaß mehr 😉

Python hilft mir mit Selenium

Und weil ich gerade Python lerne und schon mal was von Selenium gehört habe, dachte ich mir, dass es doch genau das ist, was mir die mühselige Arbeit abnehmen kann 😉

Selenium ist ein Modul, welches Browser automatisiert. Anders als das Python-Modul Webbrowser, welches nur den Browser öffnet, kann mit Selenium auch Klicks auf Elemente der Webseite programmiert werden.

Nicht nur, dass ich die Dateien herunterlade. Ich habe mein Programm soweit geschrieben, dass es nach dem Download die Dateien umbenennt und in einem anderen Ziel-Ordner verschiebt. Alles automatisiert. Wirklich cool! 🙂

Insgesamt habe ich vielleicht einen normalen Arbeitstag damit verbracht das Programm zu schreiben. Und ich war sehr erstaunt und glücklich, dass es sogar funktioniert! 🙂

Mein Python-Selenium-Beispiel

Hier ist mein Python-Programm. Ich nenne es MACR-Downloader. Beim starten des Programms werden drei Daten per Input-Befehlt abgefragt:

  1. Die URL zum „Ordner“:
    Quelle der Dateien
  2. Die Nummer des MACR:
    Ist am Ende auch die Bezeichnung des Ordernamen im Ziel-Order. Beispiel: „MACR_XXXX“.
  3. Die Seriennummer:
    ist die Prefix der Dateinamen, die heruntergeladen und umbenannt werden.

Das Programm funktioniert natürlich nicht, nur weil Selenium importiert wird. Es sind andere Python-Module notwendig, dass das gesamte Programm so funktioniert und automatisch abläuft, wie ich es am Ende benötige. Zum Beispiel Dateien umbenennen, Dateien verschieben.

Wichtig ist noch der Webdriver – in meinem Fall der Chromedriver, dieser wird von Selenium benötigt um den Browser zu starten und letztendlich auch die automatisierten Schritte durchführen zu können. Der Webdriver muss auch für die installierte Version des Browsers vorhanden sein. Bei mir befindet sich der Chromedriver im gleichen Verzeichnis, wie der Programm-Code.

Verzeichnis MACR-Downloader
Verzeichnis MACR-Downloader

Neben dem Chromedriver, gibt es auch den Edgedriver. Ich verwende jedoch den Chromedriver, weil der Google Chrome Browser mein Standard-Browser ist.

Hier ist mein Programm-Code und ich habe die wichtigen Abläufe kommentiert.

"""
Ablauf:
1. Seite mit MACR öffnen
2. Prüfen ob "Load All"-Button vorhanden ist
2.1: Wenn ja, darauf klicken und zu Schritt 3
2.2: Wenn nein, weiter zu Schritt 3
3: Erstes Thumbnail anklicken
3.1: Dann auf den Download-Button klicken und den Pfad zur Original-Datei abspeichern.      
3.2: Desktop wählen - Ordner mit MACR_NUMMER erstellen
3.3. Dateien einzeln darin speichern.
"""

import time
import requests
import urllib
import shutil
import os
import glob
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.common.exceptions import ElementNotInteractableException
from bs4 import BeautifulSoup

def macr_downloader(macr_url, macr_no, b17_sn):
    # Schritt 1: Seite mit MACR Öffnen
    options = webdriver.ChromeOptions()
    options.add_argument("--headless")    
    driver = webdriver.Chrome("chromedriver/chromedriver.exe", options=options)
    # driver = webdriver.Edge("edgedriver/MicrosoftWebDriver.exe")https://catalog.archives.gov/id/90926279
    driver.get(macr_url)
    time.sleep(10)
    # Schritt 2: Load All Button prüfen. Wenn vorhanden, klicken. Ansonsten weitermachen.
    try:
        driver.find_element(By.XPATH, '//button[text()="Load All"]')
        driver.find_element(By.XPATH, '//button[text()="Load All"]').click()
    except ElementNotInteractableException:
        print("Load All Button nicht vorhanden. Download wird fortgesetzt.")
    time.sleep(2)
    # Schritt 2.1: Popup wegkllicken
    popup = driver.find_element_by_class_name("mc-closeModal")
    popup.click()
    time.sleep(4)
    # Schritt 3: Thumbnail anklicken:
    thumbnails = driver.find_elements_by_css_selector("div.img-with-text")   
    dl_button = driver.find_element_by_id("downloadFullImage")    
    img_url = dl_button.get_attribute("href")
    # Leere Liste.
    macr_files = []
    # For-Schleife um Datei-Pfad in einer leeren Liste abspeichern.
    for thumb in thumbnails:
        thumb.click()
        time.sleep(2)
        img_url = dl_button.get_attribute("href")
        print("Dokument gefunden:\n", img_url)
        macr_files.append(img_url)
        time.sleep(2)
    print("Es wurden", len(macr_files), "Dokumente gefunden")
    for file in macr_files:
        print("Datei: ", file, "wird heruntergeladen.")
        filename = file.split('/')[-1]
        step_name = filename.split("_")
        step_name.pop(0)
        new_name = str(b17_sn) + "__" + step_name[0] + "_" + step_name[-1]
        print("Neuer Dateiname:", new_name)
        urllib.request.urlretrieve(file, new_name) 
    # Schritt 4: Datein in den passenden Ordner verschieben
    target = (r"D:\_MACR\downloaded" + "\\" + "MACR_" + macr_no)
    source = os.path.dirname(os.path.realpath(__file__))
    files = glob.iglob(os.path.join(source, "*.jpg"))
    # Wenn es den Ordner "MACR_XXXX" nicht gibt, bitte erstellen
    if not os.path.exists(target):
        print("Order", target, "erstellt")
        os.makedirs(target)
    for file in files:
        if os.path.isfile(file):
            shutil.move(file,target)
            print("verschoben:", file)
        else:
            print("failed")
    print("Erledigt. Browserfenster geschlossen.")
    driver.quit()

macr_url = input("MACR URL: ")
macr_no = input("MACR #: ")
b17_sn = input("B-17 S/N #: ")

macr_downloader(macr_url, macr_no, b17_sn)

Hinweise zum Programm-Code

Zeile 28
Hier kommt der Text options.add_argument(„–headless“) wird angewiesen, dass der Browser nicht geöffnet wird. Sondern ungeöffnet die im Code vorgegebenen Schritte durchführen soll. Das ist ganz nützlich, weil der Browser startet und manuell minimiert werden muss.

Zeile 29:
Pfad zum ChromeDriver

Zeile 68: target
Ziel-Pfad für die heruntergeladenen Dateien

Ausprobieren

Probiert den Code gerne mal aus.

  1. Hier ist eine URL für eine Quelle mit 71 Dateien: https://catalog.archives.gov/id/90887953
  2. Die dazugehörige MACR Nummer: 7547
  3. Die Seriennummer: 42-31128
  4. Bei Bedarf muss bei dir ggf. der WebDriver (z.B. ChromeDriver) aktualisiert werden.
Input für das Selenium-Beispiel
Input für das Selenium-Beispiel
Programm-Ablauf im Terminal zum o.g. Beispiel
Programm-Ablauf im Terminal zum o.g. Beispiel
Dateien werden umbenannt mit der Seriennummer als Präfix.
Dateien werden umbenannt mit der Seriennummer als Präfix.

Weiterführende Tutorials, die mir bei meinem Selenium-Programm geholfen haben:

# # ## ENDE Tagebuch-Eintrag #53 | Dateien aus dem US National Archiv automatisch herunterladen
Werbung/Anzeige
Schlagwörter im Tagebuch-Eintrag:

Kommentar schreiben




Werbung/Anzeige