XML/HTML-Beispiele

HTML

Python verfügt über zahlreiche Bibliotheken zum Lesen und Schreiben von Daten in den allgegenwärtigen HTML- und XML-Formaten. Beispiele sind lxml, Beautiful Soup und html5lib. Während lxml im Allgemeinen vergleichsweise viel schneller ist, können die anderen Bibliotheken besser mit fehlerhaften HTML- oder XML-Dateien umgehen.

pandas hat eine eingebaute Funktion, read_html, die Bibliotheken wie lxml, html5lib und Beautiful Soup verwendet, um automatisch Tabellen aus HTML-Dateien als DataFrame-Objekte zu parsen. Diese müssen zusätzlich installiert werden. Mit Spack könnt ihr lxml, BeautifulSoup und html5lib in eurem Kernel bereitstellen:

$ spack env activate python-311
$ spack install py-lxml py-beautifulsoup4~html5lib~lxml py-html5lib

Alternativ könnt ihr BeautifulSoup auch mit anderen Paketmanagern installieren, z.B.

$ uv add lxml beautifulsoup4 html5lib

Um zu zeigen, wie das funktioniert, verwende ich eine HTML-Datei der Wikipedia, die einen Überblick über verschiedene Serialisierungsformate gibt.

[1]:
import pandas as pd


tables = pd.read_html(
    "https://docs.python.org/3/library/xml.dom.html",
)

Die Funktion pandas.read_html hat eine Reihe von Optionen, aber standardmäßig sucht sie nach allen Tabellendaten, die in <table>-Tags enthalten sind, und versucht, diese zu analysieren. Das Ergebnis ist eine Liste von DataFrame-Objekten:

[2]:
len(tables)
[2]:
3
[3]:
xml_idl = tables[2]

xml_idl.head()
[3]:
IDL Type Python Type
0 boolean bool or int
1 int int
2 long int int
3 unsigned int int
4 DOMString str or bytes

Von hier aus können wir einige Datenbereinigungen und -analysen vornehmen, wie z.B. die Anzahl der verschiedenen Schema-IDL:

[4]:
xml_idl["Python Type"].value_counts()
[4]:
Python Type
int             3
bool or int     1
str or bytes    1
Name: count, dtype: int64

XML

pandas hat eine Funktion read_xml, wodurch das Lesen von XML-Dateien sehr einfach wird:

[5]:
pd.read_xml("books.xml")
[5]:
id title language author license date
0 1 Python basics en Veit Schiele BSD-3-Clause 2021-10-28
1 2 Jupyter Tutorial en Veit Schiele BSD-3-Clause 2019-06-27
2 3 Jupyter Tutorial de Veit Schiele BSD-3-Clause 2020-10-26
3 4 PyViz Tutorial en Veit Schiele BSD-3-Clause 2020-04-13

lxml

Alternativ kann auch zunächst lxml.objectify zum Parsen von XML-Dateien verwendet werden. Dabei erhalten wir mit getroot einen Verweis auf den Wurzelknoten der XML-Datei:

[6]:
from pathlib import Path

from lxml import objectify


parsed = objectify.parse(Path.open("books.xml"))
root = parsed.getroot()
[7]:
books = []

for element in root.book:
    data = {}
    for child in element.getchildren():
        data[child.tag] = child.pyval
    books.append(data)
[8]:
pd.DataFrame(books)
[8]:
title language author license date
0 Python basics en Veit Schiele BSD-3-Clause 2021-10-28
1 Jupyter Tutorial en Veit Schiele BSD-3-Clause 2019-06-27
2 Jupyter Tutorial de Veit Schiele BSD-3-Clause 2020-10-26
3 PyViz Tutorial en Veit Schiele BSD-3-Clause 2020-04-13