BeautifulSoup

[1]:
import requests


url = "https://de.wikipedia.org/wiki/Liste_der_Stra%C3%9Fen_und_Pl%C3%A4tze_in_Berlin-Mitte"
r = requests.get(url)
  1. Installieren:

    Mit Spack könnt ihr BeautifulSoup in eurem Kernel bereitstellen:

    $ spack env activate python-38
    $ spack install py-beautifulsoup4@4.10.0%gcc@11.2.0~html5lib~lxml
    

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

    $ pipenv install beautifulsoup4
    
  1. Mit r.content können wir uns das HTML der Seite ausgeben lassen.

  1. Als nächstes müssen wir diesen String mit BeautifulSoup in eine Python-Darstellung der Seite zerlegen:

[2]:
from bs4 import BeautifulSoup


soup = BeautifulSoup(r.content, "html.parser")
  1. Um den Code zu strukturieren, erstellen wir eine neue Funktion get_dom (Document Object Model), die den gesamten vorhergehenden Code einschließt:

[3]:
def get_dom(url):
    r = request.get(url)
    r.raise_for_status()
    return BeautifulSoup(r.content, "html.parser")

Das Herausfiltern einzelner Elemente kann z.B. über CSS-Selektoren erfolgen. Diese können in einer Website ermittelt werden, indem ihr z.B. in Firefox mit der rechten Maustaste auf eine der Tabellenzellen in der ersten Spalte der Tabelle klickt. Im sich nun öffnenden Inspector könnt ihr das Element erneut mit der rechten Maustaste anklicken und dann Copy → CSS Selector auswählen. In der Zwischenablage befindet sich dann z.B. table.wikitable:nth-child(13) > tbody:nth-child(2) > tr:nth-child(1). Diesen CSS-Selector bereinigen wir nun, da wir weder nach dem 13. Kindelement der Tabelle table.wikitable noch dem 2. Kindelement in tbody filtern wollen sondern nur nach der 1. Spalte innerhalb von tbody.

Schließlich lassen wir uns mit limit=3 in diesem Notebook exemplarisch nur die ersten drei Ergebnisse anzeigen:

[4]:
links = soup.select(
    "table.wikitable > tbody > tr > td:nth-child(1) > a", limit=3
)

print(links)
[<a href="/wiki/Ackerstra%C3%9Fe_(Berlin)" title="Ackerstraße (Berlin)">Ackerstraße</a>, <a href="/wiki/Alexanderplatz" title="Alexanderplatz">Alexanderplatz</a>, <a href="/wiki/Almstadtstra%C3%9Fe" title="Almstadtstraße">Almstadtstraße</a>]

Wir wollen jedoch nicht den gesamten HTML-Link, sondern nur dessen Textinnhalt:

[5]:
for content in links:
    print(content.text)
Ackerstraße
Alexanderplatz
Almstadtstraße