Diese Projekt wurde auf Basis von Python 2.7.12 geschrieben und verwendet die Bibilotheken, welche in requirements.txt aufgelistet sind. Alternativ können diese Packages auch mit pip install -r requirements.txt
installiert werden.
Wir haben zwei verschiedene Python Klassen definiert:
- eine Entry-Klasse, die ein Jobinserat repräsentiert. Diese Klassen abstrahieren die Schritte, welche wir benötigen, um von URL-Adressen zu aktuellen Auswertungen zu gelangen.
- eine Listen-Klasse, welche die Aufgaben an ihre Entries deligiert. Diese Klasse kann somit bequem aus unseren Enties eine csv-Datei generieren oder eignet sich auch die URL-Adressen abzufragen (siehe Das Anfragen der HTML-Daten) und für diese Adressen Entries zu generieren.
Für das Anfagen der HTML-Seiten verwenden wir die Bibilothek Requests und das Python Modul re. Requests ermöglicht es uns HTML-Code auf der Basis von URL-Adressen zu erhalten, während re uns das Nutzen regulärer Ausdrücke ermöglicht. Um die URL-Adressen von möglichst vielen Inseraten zu erhalten, fragen wir die Seiten nach dem Muster von https://www.jopago.com/jobs/search?page=1&pg=1 an. Falls wir auf dieser Seite keine weiteren Inserate finden, ändern wir den page parameter in der URL zu page=2 usw.
Um aus dem erhaltenen HTML-Code die URL für Jobinserate zu erhalten nutzen wir reguläre Ausdrücke. Uns interessieren URL, die
- die das href-Attribute eines Tags repräsentieren
- die mit /jobs/ beginnen, aber nicht mit /jobs/search. So sind wir in der Lage zu differenzieren, welche Links und zu aktuellen Inseraten führen und welche dazu dienen weitere Jobangebote zu erhalten
from lxml import html
tree = html.fromstring(html)
text = tree.xpath('//div[@class="job-body"]//text()')
Der Oben gezeigte Text würde grundsätzlich ausreichen, um den gesamten, reinen Text, der in dem div-Tag mit der Klasse joby-body und seinen Child-Nodes enthalten ist, zu extrahieren. Dieser Prozess hat allerdings den Nachteil, dass wir Informationen über die Struktur des Inhalts komplett verlieren. Wir können uns auch nicht simpel auf die Punktsetzung verlassen, um Sätze zu differenzieren. Eine Liste ist zum Beispiel von der Form:
<p><strong>Was wir Ihnen bieten:</strong></p>
<ul>
<li>Warenein- und Ausgangsbuchungen</li>
<li>Be- und Entladen mittels Gabelstapler</li>
<li>Pflege des Warenwirtschaftsystems</li>
<li>Lager- und Logistiktätigkeiten</li>
</ul>
Würden wir uns an den Punkten orientieren, wäre dies alles insgesamt ein einziger Satz. Solche Listen sind ein sehr beliebtes Mittel für Inserate und können nicht einfach vernachlässigt werden, da sie teilweise 50% eines Inserates ausmachen und wir daran interessiert sind, die Aktivität eines Inserates an dem Verhältnis zwischen Verben und Worten jedes Satzes auszumachen. Wir haben uns entschieden hinter jeden Satz, der in einem li-Element aufgelistet ist, künstlich einen Punkt hinzuzufügen. Um solche Spezialfälle fachgerecht zu behandeln, haben wir uns beschlossen rekursiv durch den HTML-Baum zu gehen. Man kann also sagen, dass wir versuchen die Sätze in unserem Inserat durch Punkte, welche wir gegebenfalls künstlich einfügen, zu trennen.
Abschließend noch ein paar Punkte, welche uns das Text-Scrapping erschwert haben:
- Die Erfahrung der Nutzer in HTML war ein Problem. Manche Nutzer haben keine li-Element verwendet, um Listen zu kreieren, sonder haben einzelne Punkte simpel durh - angedeutet.
- Generell die freie Schreibweise in solchen Inseraten war ein Problem. Als Beispiel haben Teilsätze wie Ihr Kontakt: Frau Schubert eine wichtige semantische Bedeutung, aber können grundsätzlich nicht als ein Satz eingeordnet werden.