Skip to content
marians edited this page Apr 29, 2013 · 16 revisions

Scrape-A-RIS wird über die Kommandozeile ausgeführt. Hier wird ausführlich erklärt, wie das Programm aufgerufen werden kann und was die verschiedenen Optionen bewirken.

Vorbedingung 1: Arbeitsverzeichnis = Hauptverzeichnis

Für alle Aufrufe müssen wir uns als aufrufender Benutzer im Hauptverzeichnis von Scrape-A-RIS befinden. Das ist das Verzeichnis, in dem die Datei README.md, main.py und config.py zu finden sind.

Vorbedingung 2: Richtige Python-Umgebung gestartet?

Wer - wie in der Installationsanleitung empfohlen - eine virtualenv Umgebung für Scrape-A-RIS eingerichtet hat, muss diese zunächst starten, bevor er/sie die nachstehenden Kommandos ausführen kann.

Angenommen, Deine virtuelle Python-Umgebung ist im Ordner venv angelegt, dann lautet der Befehl zum Aktivieren dieser Umgebung:

$ source venv/bin/activate

Konvention: Das Dollar-Zeichen vor einer Befehlszeile gilt innerhalb dieser Anleitung nicht als Teil des Befehlsaufrufs.

Vorbedingung 3: Konfiguration ist angelegt

Du hast die Datei config_example.py zu config.py kopiert und diese Datei nach bestem Wissen und Gewissen angepasst? Gut.

Erster Test

Wenn alle Voraussetzungen erfüllt sind, solltest Du den folgenden Aufruf ausprobieren können:

$ python main.py

Hier sollte, wenn alles in Ordnung ist, gar nichts passieren. Das heißt, im Hintergrund passiert schon etwas. Zum Beispiel wird geguckt, ob Deine Konfigurationsdatei vorhanden ist, ob die Datenbank erreichbar ist und ob das RIS, das Du später scrapen willst, gefunden werden kann. Aber es wird - sofern alles funktioniert wie erwartet - nichts ausgegeben.

Um wenigstens ein kleines bisschen Rückmeldung zu bekommen, kannst Du den -v Parameter (für "verbose" = ausführlich) hinzufügen. Wichtig: Alle Parameter, die hier erläutert werden, müssen hinter dem Dateinamen main.py stehen.

$ python main.py -v
Found ASP template system

Mit der verbose-Option wird die Ausgabe von Informationen im Terminal aktiviert. Ohne verbose-Option sehen wir am Terminal nur Warnungen und Fehlermeldungen, falls solche auftreten.

Scrape-A-RIS erzeugt, wie Du durch Bearbeiten der Konfigurationsdatei schon gelernt hast, auch eine Logdatei. Darin bekommst Du, unabhängig von der verbose-Option, ausführlichere Infos.

In diesem Fall erzählt Scrape-A-RIS uns, welches Template-System das kontaktierte Ratsinformationssystem nutzt. Je nach dem, welches System im Einsatz ist, kann da entweder von "PHP" oder von "ASP" die Rede sein. das ist nur dann wichtig, wenn wir mal Hand anlegen müssen an die Mechanismen, mit denen Scrape-A-RIS die Daten aus den HTML-Seiten des RIS ausliest. Wenn Du Grund hast, anzunehmen, dass Scrape-A-RIS hier mit dem gefundenen System im Irrtum ist, haben wir ein Problem und mit großer Wahrscheinlichkeit eine Fehlerquelle.

Aber gehen wir mal davon aus, dass alles stimmt, und machen wir weiter.

Scrapen einer bestimmten Vorlage

Wir wagen uns weiter vor. Angenommen, wir wollen eine bestimmte Vorlage aus dem Mannheimer Ratsinformationssystem scrapen. Dafür haben wir http://buergerinfo.mannheim.de/buergerinfo/ als BASE_URL in die Konfiguration eingetragen.

Eine bestimmte Vorlage im Mannheimer System hat die URL http://buergerinfo.mannheim.de/buergerinfo/vo0050.asp?__kvonr=207157&voselect=6080. Damit probieren wir nun, ob wir tatsächlich bekommen, was wir wollen. Wir übergeben diese mit der Option --submissionurl. Damit der Befehl an der Kommandozeile korrekt ausgeführt werden kann, verwenden wir Anführungszeichen, denn die URL enthält das zeichen &, das sonst an der Kommandozeile eine bestimmte Funktion hat.

$ python main.py -v --submissionurl "http://buergerinfo.mannheim.de/buergerinfo/vo0050.asp?__kvonr=207157&voselect=6080"

Wenn alles stimmt, bekommen wir eine Ausgabe ähnlich wie diese hier:

Found ASP template system
Getting attachment 'V189_2013_V189_2013'
Getting attachment 'V189_2013_Anlagen_V189_2013'
Getting attachment 'V189_2013_Beschlussempfehlung_AUT_V189_2013'
New file version stored with _id 517eb90ec9791e8c06ef1800
Attachment V189_2013_V189_2013 inserted with _id 517eb90ec9791e8c06ef1803
New file version stored with _id 517eb90ec9791e8c06ef1804
Attachment V189_2013_Anlagen_V189_2013 inserted with _id 517eb90ec9791e8c06ef182b
New file version stored with _id 517eb90ec9791e8c06ef182c
Attachment V189_2013_Beschlussempfehlung_AUT_V189_2013 inserted with _id 517eb90ec9791e8c06ef182e
Submission 517eb90ec9791e8c06ef182f inserted as new
Submission 207157 stored with _id 517eb90ec9791e8c06ef182f

Das sagt uns, dass mehrere Dateianhänge (attchments) und eine Vorlage (submission) in der Datenbank gespeichert wurden. Die _id steht für den Schlüssel, mit dem diese in der Datenbank identifiziert werden.

Für den Aufruf mit der Vorlagen-URL gibt es übrigens auch eine kürzere Schreibweise. Um die Vorlage im Ratsinformationssystem zu identifizieren, steht in der URL der Parameter __kvonr, der Wert des Parameters ist 207157. Verwenden wir statt --submissionurl die Option --submissionid, können wir einfach nur diesen Wert als Parameter übergeben.

$ python main.py -v --submissionid 207157

Beide Aufrufe würden - erstmalig ausgeführt - das gleiche Ergebnis bringen. Nun, da wir die Vorlage mit der Nummer 207157 aber schon gescrapet haben, wird beim Aufruf folgendes ausgegeben:

Found ASP template system
Getting attachment 'V189_2013_V189_2013'
Getting attachment 'V189_2013_Anlagen_V189_2013'
Getting attachment 'V189_2013_Beschlussempfehlung_AUT_V189_2013'
Attachment V189_2013_V189_2013 is already in database with _id 517eb90ec9791e8c06ef1803
Attachment V189_2013_Anlagen_V189_2013 is already in database with _id 517eb90ec9791e8c06ef182b
Attachment V189_2013_Beschlussempfehlung_AUT_V189_2013 is already in database with _id 517eb90ec9791e8c06ef182e
Submission 517eb90ec9791e8c06ef182f updated

Scrape-A-RIS merkt also, dass die Inhalte schon in der Datenbank sind. In diesem Fall werden übrigens die vorhandenen mit den neu gescrapten Inhalten verglichen. Dateien werden nur ausgetauscht, wenn sich der Inhalt geändert hat.

Blick in die Datenbank

Was haben wir nun in der Datenbank? Wir gucken uns das über die MongoDB-Konsole in einem neuen Terminal-Fenster an.

Die MongoDB Konsole starten wir mit diesem Befehl (vorausgesetzt, MongoDB läuft auf localhost - wovon wir hier mal ausgehen):

$ mongo

In der Mongo-Konsole wechseln wir in unsere Scrape-A-RIS Datenbank. Wir gehen hier davon aus, dass Du in Deiner Konfiguration die Einstellung DB_NAME = 'scrapearis' belassen hast. Falls das nicht so ist, verwende hier den entsprechenden Datenbank-Namen.

> use scrapearis;
switched to db scrapearis

Hier ist ein Überblick aller collections in der Datenbank:

> show collections;
attachments
fs.chunks
fs.files
queue
sessions
submissions
system.indexes

Wie viele Vorlagen haben wir denn schon?

> db.submissions.find().count();
1

Aha, genau eine. Und wie sieht die genau aus?

> db.submissions.findOne();
{
	"_id" : ObjectId("517eb90ec9791e8c06ef182f"),
	"attachments" : [
		DBRef("attachments", ObjectId("517eb90ec9791e8c06ef1803")),
		DBRef("attachments", ObjectId("517eb90ec9791e8c06ef182b")),
		DBRef("attachments", ObjectId("517eb90ec9791e8c06ef182e"))
	],
	"date" : ISODate("2013-04-02T00:00:00Z"),
	"identifier" : "V189/2013",
	"last_modified" : ISODate("2013-04-29T18:20:16.014Z"),
	"numeric_id" : 207157,
	"original_url" : "http://buergerinfo.mannheim.de/buergerinfo/vo0050.asp?__kvonr=207157",
	"rs" : "082220000000",
	"subject" : "Konversion und Freiraumentwicklung in Mannheim",
	"title" : "Konversion und Freiraumentwicklung in Mannheim",
	"type" : "Beschlussvorlage"
}

Das ist also alles, was wir über diese Vorlage wissen. Wie man sieht, sind drei Dateianhänge (attachments) darin verlinkt. Wir können in den DBRef-Einträgen sehen, welche IDs die verlinkten Anhänge haben.

Hinweis: Die von MongoDB erzeugte ObjectIds sehen bei Dir übrigens in jedem Fall anders aus. Wenn Du beispielhaft die Daten eines Dateianhangs anzeigen möchtest, musst Du eine der tatsächlichen ObjectIds aus Deiner Datenbank verwenden.

So können wir das erste verlinkte Attachment abrufen:

> db.attachments.findOne(ObjectId("517eb90ec9791e8c06ef1803"));
{
	"_id" : ObjectId("517eb90ec9791e8c06ef1803"),
	"mimetype" : "application/pdf",
	"sha1" : "520313a7ee8cf904d291eb546f8ba28258505b9c",
	"name" : "V189_2013",
	"rs" : "082220000000",
	"filename" : "V189_2013_V189_2013.pdf",
	"last_modified" : ISODate("2013-04-29T18:21:33.639Z"),
	"file" : DBRef("fs.files", ObjectId("517eb90ec9791e8c06ef1800")),
	"identifier" : "V189_2013_V189_2013",
	"size" : 309184
}

Jetzt haben wir uns schon mal vergewissert, dass die Daten auch tatsächlich in der Datenbank ankommen. Und wir wissen, wie wir uns bei Bedarf Dateianhänge und Vorlagen "ansehen" können.

Also, wieder zurück in unser anderes Terminal-Fenster. Weiter mit Scrapen.

Scrapen einer bestimmten Sitzung

Analog zum Scrapen nur einer bestimmten Vorlage können wir eine bestimmte Sitzung, mit den dazu gehörenden Vorlagen, scrapen. Auch hier gibt es zwei Möglichkeiten für den Aufruf, die beide das gleiche bewirken:

$ python main.py -v --sessionurl "http://buergerinfo.mannheim.de/buergerinfo/to0040.asp?__ksinr=6080"

und

$ python main.py -v --sessionid 6080

Wer tatsächlich zuvor wie beschrieben die Vorlage mit der Nummer 207157 gescrapet hat, könnte nun diese Ausgabe erhalten:

Found ASP template system
Getting attachment 'AUT_2013_0236_Sitzung_Gesamteinladung_Druckexemplar_nur_oeffenli'
New file version stored with _id 517ebe4dc9791e8d56421620
Attachment AUT_2013_0236_Sitzung_Gesamteinladung_Druckexemplar_nur_oeffenli inserted with _id 517ebe4dc9791e8d56421622
Submission 517ebe4dc9791e8d56421623 inserted as new
Submission 517ebe4dc9791e8d56421624 inserted as new
Submission 517ebe4dc9791e8d56421625 inserted as new
Submission 517eb90ec9791e8c06ef182f updated
Submission 517ebe4dc9791e8d56421626 inserted as new
Submission 517ebe4dc9791e8d56421627 inserted as new
Submission 517ebe4dc9791e8d56421628 inserted as new
Submission 517ebe4dc9791e8d56421629 inserted as new
Submission 517ebe4dc9791e8d5642162a inserted as new
Submission 517ebe4dc9791e8d5642162b inserted as new
Submission 517ebe4dc9791e8d5642162c inserted as new
Session 517ebe4dc9791e8d5642162d inserted as new

Es werden also einige weitere Vorlagen und eine Sitzung zur Datenbank hinzugefügt. Nur eine hatten wir schon, denn die Sitzung verweist auf Vorlage 207157, die wir uns vorher schon besorgt haben.

Gieriges Scrapen mit der Queue

Wer beim letzten Beispiel genau hingesehen hat, hat vielleicht eins bemerkt: Beim Scrapen der Sitzung werden zwar die Anlagen zur Sitzung und ganze 11 Vorlagen gescrapet, nicht aber die Anhänge zu den Vorlagen.

Das liegt daran, dass Srape-A-RIS ausgehend von einer bestimmten Sitzung immer nur genau einen Schritt "in die Tiefe" geht, also nur zu den direkt verlinkten Vorlagen. Die Anhänge zu den Vorlagen sind in der Sichtweise von Scrape-A-RIS aber schon zwei Schritte weiter.

Wir können Scrape-A-RIS sagen, dass wir auch die verknüpften Sitzungen und Vorlagen abholen wollen. Hierzu dient die Option -q bzw. --queue. Es kann übrigens entweder die lange oder kurze Schreibweise verwendet werden, beides tut das selbe. Der Aufruf sieht dann zum Beispiel so aus:

$ python main.py -v --sessionid 6080 -q

Der Name Queue für diese Funktion kommt daher, dass alle verlinkten Vorlagen und Sitzungen in diesem Modus in eine Warteschlange gelegt werden. Diese Warteschlange/Queue wird dann abgearbeitet, und zwar zuerst alle gefundenen Sitzungen und dann alle gefundenen Vorlagen.

Scrapen aller Sitzungen eines Zeitraums

Für das Scrapen größerer Zeiträume stehen die zwei Kommandozeilen-Parameter --start und --end zur Verfügung. Damit kann ein Zeitraum von einem Anfangsmonat bis zu einem Endmonat definiert werden, der dann gescrapet wird. Das Datumsformat muss dabei JJJJ-MM sein.

So könnten wir beispielsweise die Monate Juli, August und September 2012 in einem Aufruf erfassen:

$ python main.py -v --start 2012-07 --end 2012-09

Bei Verwendung der Start- und End-Option ist übrigens die Queue-Funktion implizit aktiviert. Das bedeutet, dass zunächst alle Sitzungen im angegebenen Zeitraum erfasst werden. Danach werden die Vorlagen, die in diesen Sitzungen beraten werden/wurden erfasst und mitsamt den Dateianhängen geladen.

Wiederaufnahme nach Abbruch

Sollte ein Aufruf von Scrape-A-RIS mit aktivierter Queue unterbrochen worden sein, kann der Scrape-Vorgang fortgesetzt werden. Dazu wird Scrape-A-RIS nach dem Abbruch so aufgerufen:

$ python main.py -v --queue

So werden alle noch in der Queue befindlichen Aufträge abgearbeitet.

Hierbei gilt eine Ausnahme: Der letzte aktive Job vor dem Abbruch gilt als "in Arbeit" und wird daher nicht erneut zugewiesen. Das ist ein offenes Issue (#19).

Alternative Konfigurationsdatei

Falls Du mehr als nur eine Konfigurationsdatei im Hauptverzeichnis vorhalten möchtest, z.B. weil Du mehrere Ratsinformationssysteme mit einer Installation von Scrape-A-RIS scrapen möchtest, geht das auch.

Nehmen wir an, Du möchtest, dass Scrape-A-RIS die Konfigurationsdatei config_immekeppeln.py nutzt. Das geht mit der Option --config bzw. -c:

$ python main.py -c config_immekeppeln

Beachte, dass hier die Endung .py am Dateinamen entfällt.

Von vorn beginnen (Datenbank löschen)

Achtung: Hier kannst Du Dir sehr weh tun! Überleg Dir also gut, ob Du das willst. Wenn Du diesen Befehl in die Konsole eingibst, wird Deine Datenbank (mit allen Dateianhängen darin) ohne Nachfrage gelöscht.

$ python main.py --erase