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-38
$ spack install py-lxml@4.6.3%gcc@11.2.0 py-beautifulsoup4@4.10.0%gcc@11.2.0~html5lib~lxml py-html5lib@1.1%gcc@11.2.0

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

$ pipenv install 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://en.wikipedia.org/wiki/Comparison_of_data-serialization_formats')

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]:
formats = tables[0]

formats.head()
[3]:
Name Creator-maintainer Based on Standardized?[definition needed] Specification Binary? Human-readable? Supports references?e Schema-IDL? Standard APIs Supports zero-copy operations
0 Apache Avro Apache Software Foundation NaN No Apache Avro™ Specification Yes Partialg NaN Built-in C, C#, C++, Java, PHP, Python, Ruby NaN
1 Apache Parquet Apache Software Foundation NaN No Apache Parquet Yes No No NaN Java, Python, C++ No
2 ASN.1 ISO, IEC, ITU-T NaN Yes ISO/IEC 8824 / ITU-T X.680 (syntax) and ISO/IE... BER, DER, PER, OER, or custom via ECN XER, JER, GSER, or custom via ECN Yesf Built-in NaN OER
3 Bencode Bram Cohen (creator)BitTorrent, Inc. (maintainer) NaN De facto as BEP Part of BitTorrent protocol specification Except numbers and delimiters, being ASCII No No No No No
4 Binn Bernardo Ramos JSON (loosely) No Binn Specification Yes No No No No Yes

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

[4]:
formats['Schema-IDL?'].value_counts()
[4]:
No                                                                                        17
Built-in                                                                                   4
Yes                                                                                        4
CDDL                                                                                       1
Partial(Signature strings)                                                                 1
XML Schema                                                                                 1
XML schema                                                                                 1
Ion schema                                                                                 1
Partial(JSON Schema Proposal, ASN.1 with JER, Kwalify, Rx, Itemscript Schema), JSON-LD     1
Schema WD                                                                                  1
?                                                                                          1
Partial(JSON Schema Proposal, other JSON schemas/IDLs)                                     1
WSDL, XML schema                                                                           1
XML schema, RELAX NG                                                                       1
Partial(Kwalify, Rx, built-in language type-defs)                                          1
Schema-IDL?                                                                                1
Name: Schema-IDL?, 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 lxml import objectify

parsed = objectify.parse(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