Vorwort

Das folgende Dokument wurde als HTML-Export eines Jupyter-Notebook-Dokuments (https://jupyter.org/) generiert. Diese HTML-Version enthält denselben Inhalt, aber das Code-Highlighting ist etwas unübersichtlicher und der Code ist nicht direkt ausführbar. Wenn Sie stattdessen direkt das IPYNB-Dokument öffnen möchten, benötigen Sie eine Jupyter-Notebook-Installation (https://jupyter.org/install.html). Diese installieren Sie, falls Sie Python bereits installiert haben, mit dem Befehl > pip install notebook. Das Programm starten können Sie anschließend mit > jupyter notebook.

Einleitung

In diesem Notebook finden Sie erklärten Code, mit dem Sie alle Ressourcen eines Zeitungsunernehmens herunterladen können, die mit Visual Library gehostet werden.

Diese dritte Version erweitert die zweite Version um die Möglichkeit, sehr detailliert festzulegen, wie die Ordner und die heruntergeladenen Dateien heißen sollen. Dies kann unter anderem für die anschließende Weiterverarbeitung mit anderen Programmen hilfreich sein.

Das hier erläuterte Beispiel ist das Zeitungsunternehmen Augsburger Postzeitung: https://visuallibrary.net/dps/periodical/titleinfo/436884.

Um diesem Notebook folgen zu können, ist ein Blick in die erste und zweite Version wahrscheinlich hilfreich, da dort das prinzipielle Vorgehen und einige verwendete Techniken genauer erklärt werden.

In dieser Version liegt der Fokus darauf, die Optionen zur Namenskonfiguration zu erklären; nicht darauf, den Code zu erklären, der dies bewerkstelligt.

Idee

Der Ansatz ist derselbe wie in der Basisversion: Über die OAI/METS-Dokumente wird von der höchsten Hierarchie-Ebene (dem Zeitungsunternehmen) subsequent auf die Kinder der jeweils tieferen Ebene zugegriffen. Daneben werden mit XPath-Abfragen detaillierte Metadaten aus den MODS-Elementen (http://dfg-viewer.de/fileadmin/groups/dfgviewer/MODS-Anwendungsprofil_2.3.1.pdf) extrahiert, die in die METS-Dokumente eingebettet sind.

Um die Informationen aus den MODS-Elementen für die Speicherung zu verwenden, benutzen wir Funktionen, um jeden einzelnen logischen Teil, also Zeitungsunternehmen - Zeitung - Jahrgang - Ausgabe - Seite, in die gewünschte Namensform zu bringen. Die Namen dieser logischen Einheiten können dann an zwei verschiedenen Stellen genutzt werden: einerseits bei der Erstellung der Ordnernamen, in denen die einzelnen Seiten gespeichert werden sollen; andererseits in den Dateinamen der Seiten.

Die üblichwerweise vorhandenen Ressourcen sind ein Bild von jeder Zeitungsseite in unterschiedlicher Auflösung und ein PDF-Dokument von jeder Ausgabe. Daneben gibt es häufig Volltexte von einzelnen Seiten, meistens im ALTO-Format, manchmal auch (zusätzlich) im HTML-Format.

Code

Wir erledigen zunächst die notwendigen Importe und definieren die XML-Namespaces.

Wir geben die URL des Zeitungsunternehmens an.

Wir legen fest, welche Formate wir herunterladen wollen. Wenn mehr als eines der Formate 'Max', 'Min', 'Default', 'Thumbs' benutzt wird, wird das letzte davon die vorherigen überschreiben, weil sie namensgleiche JPEG-Dateien erzeugen.

Namenskonfiguration

Hier kann das Download-Verzeichnis festgelegt werden. In dieses und seine noch festzulegenden Unterverzeichnisse werden alle Ressourcen heruntergeladen. Es kann ein relativer Pfad sein, d.h. im Ordner, wo dieses Notebook gespeichert ist, wird ein neuer Ordner dieses Namens erzeugt, oder ein absoluter Pfad, d.h. ausgehend vom Laufwerk wird der genaue Pfad angegeben.

Nun kann die Ordnerstruktur festgelegt werden, in der die einzelnen Seiten gespeichert werden sollen. Die sechs Bestandteile 'base', 'newspaper_series', 'newspaper', 'year', 'issue' und 'fmt' können beliebig arangiert und/oder ausgelassen werden. Die Ordnernamen werden gemäß dieser Liste von links nach rechts gebildet. Dadurch kann die Feinheit der Ordnergliederung beliebig kontrolliert werden. Im Wesentlichen gibt es hier zwei Entscheidungen zu treffen. Erstens kann festgelegt werden, wie tief die Ordnerstruktur die logische Zugehörigkeitsstruktur einer Seite nachbilden soll. Zweitens kann festgelegt werden, in welcher Tiefe die Aufspaltung in verschiedene Formate stattfinden soll. Einige Beispiele:

A) Alle Ressourcen, die zu einer Zeitung gehören, sollen in dasselbe Verzeichnis heruntergeladen werden. Diese Verzeichnisse sollen einfach (für jede Zeitung) im aktuellen Ordner erstellt werden: </br> folder_structure = ['newspaper']

B) Analog zu A, aber die verschiedenen Formate sollen für jede Zeitung in getrennten Ordnern gespeichert werden: </br> folder_structure = ['newspaper', 'fmt']

C) Im aktuellen Verzeichnis soll ein neuer Ordner angelegt werden. Es soll zuerst nach Formaten unterschieden werden, dann für jeden Jahrgang ein Ordner angelegt werden, in diesem soll nach Zeitungen separiert gespeichert werden, und zuletzt in jedem Zeitungsordner jede Ausgabe in einem eigenen Ordner: </br> folder_structure = ['base', 'fmt', 'year', 'newspaper', 'issue']

Hierbei ist zu beachten, dass es insbesondere beim Speichern in einer wenig verästelten Ordnerstruktur schnell zu Namensdopplungen kommen kann. Wenn beispielsweise wie in B nur nach Zeitung und Format getrennt wird, und die Namen jeder einzelnen Seite dem Muster 'Seite X' folgen, werden die einzelnen Seiten jeder Ausgabe jedes Jahrgangs gleich heißen und die zuletzt heruntergeladene Seite die vorherigen dementsprechend überschreiben.

Um das zu vermeiden, kann neben der Ordnerstruktur auch der Name jeder einzelnen Datei sehr genau festgelegt werden. Alle Informationen über die Zugehörigkeit zu höheren Einheiten (Unternehmen, Zeitung, Jahrgang, Ausgabe) können optional im Dateinamen enthalten sein, außerdem noch die Seitenanzahl, die automatisch ermittelt wird, und die eindeutige Visual Library Speicher-ID der Seite.

Der Name einer Einzelseite wird einfach als String festgelegt, wobei Referenzen zu den Zugehörigkeitsebenen genutzt werden können, welche dann durch die konkrete Information ersetzt werden. Die anderen Bestandteile des Strings werden nicht verändert, zum Beispiel könnte man die Seiten mit 'Seite PAGE_NO' benennen, wobei PAGE_NO durch die konkrete Seitennummer ersetzt würde, sodass die Dateien dann "Seite 1", "Seite 2", usw. hießen.

Sollte man wie in B jedoch nur nach Zeitung und Format trennen, wäre es wahrscheinlich sinnvoll, die unterscheidenden Informationen wie Jahrgang oder Ausgabe in den Namen der Einzelseiten zu verwenden. Dann könnte der Variable page_name_format z.B. so aussehen: 'YEAR_NAME ISSUE_NAME Seite PAGE_NO'.

Die PDF-Dokumente einer ganzen Ausgabe werden der Einfachheit halber wie die Namen von Einzelseiten behandelt. PAGE_ID ist die eindeutige ID des PDFs. PAGE_NO wird als Umfang angegeben, beispielsweise 1-4.

Die einzelnen Bestandteile, die wir bei der Benennung von Ordnern und Dateien benutzt haben, können selbst ein Stück weit angepasst werden.

Für den Jahrgang wird aus dem MODS das Jahr extrahiert, auf dieses kann im Namen für den Jahrgang mit dem Substring '%Y' zugegriffen werden. (Erläutert wird dies hier: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes.) Dies ist auch der Defaultwert. Es wäre aber beispielsweise auch möglich, den Wert 'Jahrgang %Y' zu nutzen, dann würde, sofern die Information in der Ordnerstruktur und/oder für die Dateinamen verwendet wird, der Teil YEAR_NAME durch 'Jahrgang YYYY' ersetzt.

Analog dazu kann der Name der Ausgabe angepasst werden. Außerdem kann festgelegt werden, ob neben dem Erscheinungsdatum weitere (verfügbare) Informationen über die Ausgabe zum Namen hinzugefügt werden sollen, z.B. die laufende Nummer im Jahr oder Zusätze wie 'Vorabendblatt', die z.B. verschiedene Ausgaben am selben Tag differenzieren können.

Die Namen für das Zeitungsunternehmen und für die einzelnen Zeitungen werden automatisch aus den MODS-Informationen konstruiert, es ist allerdings auch möglich, eigene Namen zu verwenden. Für das Zeitungsunternehmen wird einfach ein String übergeben, für die Zeitungen ein Dictionary, in dem für jede Zeitungs-ID der Name festgelegt werden kann.

Zuletzt kann spezifiziert werden, hinter welche Namensteile zusätzlich die eindeutige Visual-Library-ID angehangen werden soll. Dies kann nützlich sein, um die einzelnen Einheiten (online) schnell wiederzufinden. Außerdem kann es in seltenen Fälle vorkommen, dass die METS-Informationen stellenweise ungenau sind, und z.B. einer Ausgabe fälschlicherweise dasselbe Datum wie einer anderen Ausgabe zugewiesen wird. Dann könnten die ansonsten gleichnamigen Seiten der zwei Ausgaben durch die angehangene VL-ID unterschieden werden und eine Überschreibung würde verhindert.

Für jede Strukturebene kann individuell entschieden werden, ob die ID angegangen werden soll. Sie wird angehangen für alle Ebenenen, die in der Liste enthalten sind.

Die Möglichkeiten, Namen für Ordner und Dateien festzulegen, sind also sehr vielfältig. Wahrscheinlich ist es sinnvoll, zunächst auszuprobieren, ob die Ressourcen tatsächlich mit den gewünschten Namen gespeichert werden, bevor der mitunter lange dauernde Download aller Ressourcen durchgeführt wird.

Falls Sie unter Windows arbeiten, sollten Sie außerdem beachten, dass die maximale Pfadlänge unter Standardeinstellungen 260 Zeichen beträgt. Mit diesem Skript kann es durchaus passieren, dass Sie diese Länge überschreiten, da Sie einerseits eine recht tief verzweigte Pfadstruktur erzeugen können und andererseits die in VL verwendeten Namen für Zeitungen sehr lang sein können. Dieses Problem ist in einer weiteren Version gelöst, die von der Eingabeeinforderung aus aufgerufen werden kann, und noch einige weitere zusätzliche Funktionalitäten umfasst.

Funktionsdefinitionen

Download