Einführung zu Web Scraping#
Das Web Scraping einer Online-Ressource sollte gut geplant werden - auch, um unnötige wiederholte Anfragen an die Website und den daraus resultierenden Traffic auf dem Server möglichst gering zu halten. Die Planung sollte dabei die folgenden Schritte umfassen:
Mit der Struktur und den Elementen der Website und dem HTML-Code vertraut machen (Browser-Tools, etc)
Elemente identifizieren, die extrahiert werden sollen (HTML-Elemente, Identifier, Attribute, etc)
Testweises lokales parsen des HTML-Codes und Extrahieren der gewünschten Infos (z.b. mit parsel und requests)
Planen des automatisierten Web Scraping Vorgangs mit scrapy
Erstellen und Testen der benötigten Python-Module für scrapy
Durchlauf des automatisierten Web Scraping und Auswerten der Daten
Grundlagen zum Parsen von HTML mit parsel#
Für das testweise lokale parsen einer Website bietet sich die Bibliothek parsel an. Scrapy nutzt parsel, daher verhalten sich die Selektoren zur Auswahl und Extraktion von Informationen ähnlich.
# Import des Selector-Moduls von parsel
from parsel import Selector
# Import und Initialisierung von bia-bob
from bia_bob import bob
# API Key wird aus condas Umgebungsvariable gelesen
bob.initialize(endpoint='blablador', model='alias-fast')
Wir arbeiten zunächst an folgendem HTML Inhalt, gespeichert in der Variable text
.
text = """
<html>
<body>
<h1>Hello, Parsel!</h1>
<ul>
<li><a href="http://example.com">Link 1</a></li>
<li><a href="http://scrapy.org">Link 2</a></li>
</ul>
<script type="application/json">{"a": ["b", "c"]}</script>
</body>
</html>
"""
# HTML Inhalt in parsels Selector laden
selector = Selector(text=text)
Um Elemente und deren Inhalt aus strukturierten Datenformaten zu extrahieren, stellt parsel entsprechende Selektoren (Selectors) bereit:
CSS
XPath
Siehe dazu auch folgende Online-Ressourcen:
parsel User Guide Using selectors
w3school CSS Tutorial und CSS References
w3schools XPath Tutorial
devhints XPath Cheatsheet
# Selection via CSS
selector.css('h1::text').get()
'Hello, Parsel!'
# Selection via XPath
selector.xpath('//h1/text()').re(r'\w+')
['Hello', 'Parsel']
Mit JMESPath integriert parsel auch eine Abfragesprache für JSON, siehe JMESPath Dokumentation.
selector.css('script::text').jmespath("a").get()
'b'
selector.css('script::text').jmespath("a").getall()
['b', 'c']
Auch hier können wir bei Bedarf wieder unseren KI-Assistenten um Rat fragen.
%%bob
Analysiere den Inhalt der HTML in {text}.
Gib mir Code, um daraus mithilfe der Bibliothek parsel den Text-Inhalt des zweiten <li> Elements zu extrahieren.
Use the parsel
library to extract the content of the second <li>
element. Here is the code to achieve that:
# Inhalt des zweiten <li> Elements extrahieren
second_li_content = selector.xpath('//ul/li[2]/a/text()').get()
print(second_li_content)
Link 2
Parsen einer Website mit requests und parsel#
Nun nutzen wir die Bibliothek requests, um mittels einer GET Anfrage den HTML-Inhalt der Website zu erhalten. Diese HTML können wir dann lokal parsen, um die gwünschten Informationen zu extrahieren.
Für unsere Übung nutzen wir die Website https://quotes.toscrape.com/. Ziel ist die Extraktion der Zitate - hier jeweils den Text und den Namen der AutorInnen. Machen wir uns zunächst mit dem Inhalt der Website vertraut. Hierfür rufen wir die Website im Browser auf und werfen mit den Browser-Tools einen Blick auf die zugrundeliegende Struktur.
Wenn wir uns mit der Struktur der Website vertraut gemacht haben, können wir einen GET Request stellen, um den HTML-Inhalt zu erhalten
# Import von requests for HTTP Methoden
import requests
# GET Request an Website
response = requests.get('https://quotes.toscrape.com/')
# Ausgabe der ersten 500 Zeichen des HTML Inhaltes der Response
print(response.text[:500])
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Quotes to Scrape</title>
<link rel="stylesheet" href="/static/bootstrap.min.css">
<link rel="stylesheet" href="/static/main.css">
</head>
<body>
<div class="container">
<div class="row header-box">
<div class="col-md-8">
<h1>
<a href="/" style="text-decoration: none">Quotes to Scrape</a>
</h1>
</div>
<div cla
# HTML Inhalt in parsels Selector laden
selector = Selector(text=response.text)
Jetzt bist du dran. Extrahiere für jedes Zitat im HTML-Inhalt den Text und den Namen der AutorIn. Speichere das Ergebnis als eine Liste von Tupeln ab…[(Text, AutorIn), (Text, AutorIn), ...]
.
Hierfür bietet sich der folgende Ablauf an:
Identifikation der Zitat-Elemente im HTML und deren Attribute
Sammeln aller Zitat-Elemente in einer Liste
Iteration über die Zitat-Elemente und Extraktion der gewünschten Informationen
Du kannst natürlich auch unseren KI-Assistenten um Rat fragen.
# Liste zum Sammeln der extrahierten Informationen
quotes = []
# TODO