1. Warum find und find_all verwenden?
Heute sprechen wir über zwei Hauptmethoden, die uns eine effektive und gezielte Extraktion von Elementen aus HTML-Dokumenten ermöglichen: find und find_all.
Bevor wir in den Code eintauchen, lass uns kurz darüber sprechen, warum diese Methoden überhaupt nötig sind. Stell dir eine Webseite vor wie eine riesige Bibliothek, in der jedes Wort und jeder Satz ein HTML-Element ist. Es fühlt sich an, als ob man den Geschmack von Eiscreme erraten müsste, ohne ihre Farbe zu kennen. Die Methoden find und find_all sind wie deine „Geschmacksdetektoren“, die dir helfen, gezielt nach der benötigten Information zu suchen.
find: Diese Methode ähnelt dem morgendlichen Ritual eines Programmierers, die erste Tasse Kaffee zu suchen – sie findet schnell und gibt das erste Element zurück, das den angegebenen Kriterien entspricht.find_all: Das ist ein geduldigerer und gründlicherer Ansatz, der eine Liste aller Elemente zurückgibt, die den Suchkriterien entsprechen. Ideal für Situationen, in denen du mehr Informationen benötigst (wie mehrere Tassen Kaffee im Laufe des Tages).
2. Nutzung von find
Die Methode find kann verwendet werden, wenn du schnell das erste passende Element extrahieren möchtest. Sie nimmt verschiedene Parameter an, wie beispielsweise Tag-Namen, Attribute und sogar Funktionen.
Signatur der Methode find
find(name=None, attrs={}, recursive=True, string=None, **kwargs)
Parameter der Methode find
- name: Der Name des Tags, den du finden möchtest. Dies kann jeder HTML-Tag sein, z. B.
div,p,h1,ausw. - attrs: Ein Wörterbuch mit Tag-Attributen. Zum Beispiel
{'class': 'example'}oder{'id': 'main'}. Dieser Parameter ermöglicht eine engere Eingrenzung der Suche. - recursive: Ein boolescher Parameter, der bestimmt, ob die Methode den Tag auf allen Ebenen der Verschachtelung durchsuchen soll. Standardmäßig ist
True, was bedeutet, dass die Suche durch alle Ebenen erfolgt. - string: Sucht nach Elementen mit einem bestimmten Text. Nützlich zur Filterung von Elementen anhand ihres Textinhalts.
- kwargs: Zusätzliche Argumente zur Attributsuche. Wenn du Argumente wie
class_angibst, werden sie alsattrs={'class': 'value'}interpretiert.
Beispiel
from bs4 import BeautifulSoup
html_doc = """
<html>
<head><title>Die Geschichte der Haselmaus</title></head>
<body>
<p class="title"><b>Die Geschichte der Haselmaus</b></p>
<p class="story">Es war einmal vor langer Zeit, da gab es drei kleine Schwestern; und ihre Namen waren
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> und
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
und sie lebten am Grund eines Brunnens.</p>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
first_link = soup.find('a') # Finde den ersten <a>-Tag
print(first_link) # Gibt aus: <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>
Wie du siehst, hat die Methode find den ersten <a>-Tag im Dokument gefunden, und wir können beruhigt weitersuchen, weil die benötigte Information gefunden wurde.
3. Nutzung von find_all
Die Methode find_all gibt eine Liste aller Elemente zurück, die den angegebenen Kriterien entsprechen. Das ist besonders nützlich, wenn du alle Tags eines bestimmten Typs oder alle Elemente mit einer bestimmten Klasse sammeln möchtest.
Signatur der Methode find_all
find_all(name=None, attrs={}, recursive=True, string=None, limit=None, **kwargs)
Parameter der Methode find_all
- name: Der Name des Tags, den du finden möchtest. Dies kann ein einzelner Tag-Name sein (
div,a,pusw.) oder eine Liste von Tags, z. B.["div", "p"]. - attrs: Ein Wörterbuch zur Filterung von Tags anhand ihrer Attribute, z. B.
{'class': 'example'}. - recursive: Gibt an, ob die Suche rekursiv durchgeführt wird, also auch verschachtelte Tags einschließt. Standardmäßig auf
Truegesetzt. - string: Sucht nach Tags, die den angegebenen Text enthalten.
- limit: Gibt die maximale Anzahl der zurückgegebenen Ergebnisse an. Wenn angegeben, gibt die Methode höchstens
limit-Elemente zurück. - kwargs: Zusätzliche Argumente zur Attributfilterung von Tags.
Beispiel für die Nutzung von find_all
Wenn find wie das schnelle Finden des benötigten Buches im Regal ist, dann ist find_all ein detaillierterer Ansatz, als ob du alle Überschriften der Kapitel durchgehst, um sie zu verstehen.
all_links = soup.find_all('a') # Finde alle <a>-Tags
for link in all_links:
print(link.get('href')) # Gibt die Links aus: http://example.com/elsie, http://example.com/lacie, http://example.com/tillie
In diesem Beispiel finden wir alle <a>-Tags und extrahieren dann die Links aus jedem von ihnen. Nützlich, wenn du alle Links auf einer Seite sammeln möchtest.
Wichtig! Die Methoden find() und find_all() können nicht nur bei einem soup-Objekt aufgerufen werden, sondern auch bei jedem Kind-Element, das durch Funktionen wie find(), select() usw. zurückgegeben wird.
4. Nutzung von Attributen zur Filterung von Elementen
Jetzt, da wir unseren Datenhunger im Griff haben, ist es an der Zeit, spezifischer zu werden. Die Methoden find und find_all ermöglichen eine Filterung von Elementen basierend auf Attributen. Das ist wie das Einstellen eines Filters an einer Kaffeemaschine, um genau das Getränk zu erhalten, das dir schmeckt.
link_with_id = soup.find('a', id='link2') # Finde <a> mit id='link2'
print(link_with_id.text) # Gibt aus: Lacie
Mit dem Parameter id haben wir schnell das benötigte Element gefunden. Ähnlich können auch andere Attribute wie class verwendet werden.
links_with_class = soup.find_all('a', class_='sister') # Finde alle <a>-Tags mit class='sister'
for link in links_with_class:
print(link.get('id')) # Gibt aus: link1, link2, link3
5. Vergleich von find und find_all: Wann welches verwenden?
Jetzt, da du beide Methoden kennst, fragst du dich vielleicht: „Wann soll ich find und wann find_all verwenden?“ Ganz einfach. Wenn du sicher bist, dass es auf der Seite nur ein benötigtes Element gibt oder nur das erste gefundene Element für dich interessant ist, wähle find. Wenn du jedoch alle Elemente sammeln möchtest, die den Kriterien entsprechen, und es viele sein könnten, dann ist find_all die bessere Wahl.
| Parameter | find |
find_all |
|---|---|---|
| Rückgabewert | Das erste gefundene Element (oder None, wenn nicht gefunden) |
Liste der gefundenen Elemente (oder leere Liste) |
| Zweck | Wenn nur ein Element benötigt wird | Wenn alle passenden Elemente gesammelt werden sollen |
Parameter limit |
Wird nicht angewendet | Unterstützt: Gibt die maximale Anzahl zurück |
Beispielvergleich: Wenn du alle h2-Überschriften auf einer Seite erhalten möchtest, verwende find_all. Aber wenn du nur die erste h2-Überschrift möchtest, reicht find.
# Erhalte alle h2-Überschriften auf der Seite
all_h2_tags = soup.find_all("h2")
# Erhalte nur die erste h2-Überschrift
first_h2_tag = soup.find("h2")
6. Praktische Aufgabe
Jetzt, da du die Theorie kennst, lass uns sie in der Praxis anwenden. Wir werden ein kleines Skript erstellen, das die Titel und Links von Blog-Artikeln extrahiert. Dazu verwenden wir find_all, um alle Überschriften und Links zu finden, wobei wir davon ausgehen, dass sie sich in einem <h2>-Tag mit der Klasse post-title befinden.
blog_html = """
<html>
<body>
<h2 class="post-title"><a href="http://example.com/post1">Erster Beitrag</a></h2>
<h2 class="post-title"><a href="http://example.com/post2">Zweiter Beitrag</a></h2>
<h2 class="post-title"><a href="http://example.com/post3">Dritter Beitrag</a></h2>
</body>
</html>
"""
blog_soup = BeautifulSoup(blog_html, 'html.parser')
post_titles = blog_soup.find_all('h2', class_='post-title')
for post in post_titles:
title = post.text
link = post.find('a')['href']
print(f"Title: {title}, Link: {link}")
Wenn alles richtig gemacht wurde, siehst du:
Title: Erster Beitrag, Link: http://example.com/post1
Title: Zweiter Beitrag, Link: http://example.com/post2
Title: Dritter Beitrag, Link: http://example.com/post3
Beachte, dass die Methode find() im obigen Beispiel bei einem post-Objekt aufgerufen wird. So kannst du Kind-Element(e) eines bereits gefundenen Elements durchsuchen.
7. Typische Fehler
Beim Arbeiten mit find und find_all treten oft Fehler auf. Zum Beispiel gibt find None zurück, wenn ein Element nicht gefunden wird, was zu einem AttributeError führen kann. Deshalb solltest du das Ergebnis immer überprüfen, bevor du es verwendest.
Auch Probleme mit falschen Attributen sind häufig. Zum Beispiel, wenn ein Attribut mit einem Schreibfehler angegeben wird, findet die Methode nichts. Daher empfehle ich, immer die korrekte Schreibweise der Attribute im HTML-Code zu überprüfen.
GO TO FULL VERSION