Im letzten Tutorial haben Sie die Grundlagen der Beautiful Soup-Bibliothek gelernt. Neben der Navigation im DOM-Baum können Sie auch nach bestimmten Elementen suchen Klasse
oder Ich würde
. Sie können den DOM-Baum auch mit dieser Bibliothek ändern.
In diesem Lernprogramm lernen Sie verschiedene Methoden kennen, die Ihnen bei der Suche und den Änderungen helfen. Wir werden die gleiche Wikipedia-Seite über Python aus unserem letzten Tutorial besorgen.
Beautiful Soup bietet viele Methoden zum Durchsuchen des DOM-Baums. Diese Methoden sind sehr ähnlich und verwenden dieselben Filter wie Argumente. Daher ist es sinnvoll, die verschiedenen Filter richtig zu verstehen, bevor Sie sich mit den Methoden vertraut machen. Ich werde das gleiche verwenden finde alle()
Methode zur Erklärung des Unterschieds zwischen verschiedenen Filtern.
Der einfachste Filter, den Sie an eine Suchmethode übergeben können, ist eine Zeichenfolge. Beautiful Soup durchsucht dann das Dokument nach einem Tag, der genau mit der Zeichenfolge übereinstimmt.
für Überschriften in soup.find_all ('h2'): print (heading.text) # Inhalt # Historie [Bearbeiten] # Merkmale und Philosophie [Bearbeiten] # Syntax und Semantik [Bearbeiten] # Bibliotheken [Bearbeiten] # Entwicklungsumgebungen [Bearbeiten] #… und so weiter.
Sie können auch ein reguläres Ausdrucksobjekt an das übergeben finde alle()
Methode. Diesmal filtert Beautiful Soup die Baumstruktur, indem alle Tags mit einem bestimmten regulären Ausdruck abgeglichen werden.
importieren für die Überschrift in soup.find_all (re.compile ("^ h [1-6]")): print (Überschrift.name + "+ Überschrift.text.strip ()) # h1 Python (Programmiersprache) # h2 Inhalt # h2 Verlauf [edit] # h2 Merkmale und Philosophie [edit] # h2 Syntax und Semantik [edit] # h3 Einzug [edit] # h3 Anweisungen und Kontrollfluss [edit] #… und so weiter.
Der Code sucht nach allen Tags, die mit "h" beginnen und denen eine Ziffer von 1 bis 6 folgt. Mit anderen Worten, es werden alle Überschriften-Tags im Dokument gesucht.
Anstelle eines regulären Ausdrucks können Sie dasselbe Ergebnis erzielen, indem Sie eine Liste aller Tags übergeben, für die Beautiful Soup mit dem Dokument übereinstimmen soll.
für Überschrift in soup.find_all (["h1", "h2", "h3", "h4", "h5", "h6"])): print (Überschrift.name + "+ Überschrift.text.strip ())
Sie können auch passieren Wahr
als Parameter für die finde alle()
Methode. Der Code gibt dann alle Tags im Dokument zurück. Die folgende Ausgabe bedeutet, dass sich derzeit auf der Wikipedia-Seite 4.339 Tags befinden, die wir analysieren.
len (soup.find_all (True)) # 4339
Wenn Sie mit einem der oben genannten Filter immer noch nicht finden, wonach Sie suchen, können Sie Ihre eigene Funktion definieren, die ein Element als einziges Argument verwendet. Die Funktion muss auch zurückkehren Wahr
wenn es eine Übereinstimmung gibt und Falsch
Andernfalls. Je nachdem, was Sie benötigen, können Sie die Funktion so kompliziert gestalten, wie es für die Arbeit erforderlich ist. Hier ist ein sehr einfaches Beispiel:
def big_lists (tag): gibt len (tag.contents)> 20 und tag.name == 'ul' len (soup.find_all (big_lists)) # 13 zurück
Die obige Funktion durchläuft dieselbe Wikipedia-Python-Seite und sucht nach ungeordneten Listen mit mehr als 20 Kindern.
Eine der beliebtesten Methoden zum Durchsuchen des DOM ist finde alle()
. Es durchläuft alle Nachkommen des Tags und gibt eine Liste aller Nachkommen zurück, die Ihren Suchkriterien entsprechen. Diese Methode hat folgende Signatur:
find_all (name, attrs, rekursiv, string, limit, ** kwargs)
Das Name
Argument ist der Name des Tags, nach dem diese Funktion gesucht werden soll, während der Baum durchlaufen wird. Sie können einen String, eine Liste, einen regulären Ausdruck, eine Funktion oder den Wert angeben Wahr
als name.
Sie können die Elemente in der DOM-Struktur auch anhand verschiedener Attribute filtern Ich würde
, href
, usw. Sie können auch alle Elemente mit einem bestimmten Attribut erhalten, unabhängig von ihrem Wert Attribut = wahr
. Die Suche nach Elementen mit einer bestimmten Klasse unterscheidet sich von der Suche nach regulären Attributen. Schon seit Klasse
ist ein reserviertes Schlüsselwort in Python, Sie müssen das verwenden Klasse_
Schlüsselwortargument bei der Suche nach Elementen mit einer bestimmten Klasse.
Importiere len (soup.find_all (id = True)) # 425 len (soup.find_all (class_ = True)) # 1734 len (soup.find_all (class _ = "mw-headline")) # 20 len (soup.find_all.) (href = True)) # 1410 len (soup.find_all (href = re.compile ("python"))) # 102
Sie sehen, dass das Dokument 1.734 Tags mit einem hat Klasse
Attribut und 425 Tags mit einem Ich würde
Attribut. Wenn Sie nur die ersten Ergebnisse benötigen, können Sie der Methode eine Zahl als Wert von übergeben Grenze
. Wenn Sie diesen Wert übergeben, wird Beautiful Soup angewiesen, nach mehr Elementen zu suchen, sobald eine bestimmte Anzahl erreicht ist. Hier ist ein Beispiel:
soup.find_all (class _ = "mw-headline", limit = 4) # Geschichte # Merkmale und Philosophie # Syntax und Semantik # Vertiefung
Wenn Sie das verwenden finde alle()
Sie sagen Beautiful Soup, dass Sie alle Nachkommen eines bestimmten Tags durchsuchen müssen, um das zu finden, wonach Sie suchen. Manchmal möchten Sie ein Element nur in den direkten untergeordneten Elementen eines Tags suchen. Dies kann durch Weitergeben erreicht werden rekursiv = falsch
zum finde alle()
Methode.
len (soup.html.find_all ("meta")) # 6 len (soup.html.find_all ("meta", rekursiv = False)) # 0 len (soup.head.find_all ("meta", rekursiv = False) ) # 6
Wenn Sie nur ein Ergebnis für eine bestimmte Suchanfrage suchen, können Sie das verwenden finden()
Methode, um es zu finden, anstatt zu übergeben limit = 1
zu finde alle()
. Der einzige Unterschied zwischen den Ergebnissen dieser beiden Methoden ist der finde alle()
gibt eine Liste mit nur einem Element und zurück finden()
gibt nur das Ergebnis zurück.
soup.find_all ("h2", limit = 1) # [Inhalt
] soup.find ("h2") #Inhalt
Das finden()
und finde alle()
Diese Methoden durchsuchen alle Nachkommen eines bestimmten Tags, um nach einem Element zu suchen. Es gibt zehn weitere sehr ähnliche Methoden, die Sie verwenden können, um die DOM-Struktur in verschiedene Richtungen zu durchlaufen.
find_parents (name, attrs, string, limit, ** kwargs) find_parent (name, attrs, string, ** kwargs) find_next_siblings (name, attrs, string, limit, ** kwargs) find_next_sibling (name, attrs, string, ** kwargs) find_previous_siblings (name, attrs, string, limit, ** kwargs) find_previous_sibling (name, attrs, string, ** kwargs) find_all_next (name, attrs, string, limit, ** kwargs) find_next (name, attrs, string, ** kwargs) find_all_previous (name, attrs, string, limit, ** kwargs) find_previous (name, attrs, string, ** kwargs)
Das find_parent ()
und find_parents ()
Methoden durchlaufen den DOM-Baum nach oben, um das angegebene Element zu finden. Das find_next_sibling ()
und find_next_siblings ()
Methoden werden alle Geschwister des Elements durchlaufen, die nach dem aktuellen Element kommen. Ebenso die find_previous_sibling ()
und find_previous_siblings ()
Methoden werden alle Geschwister des Elements durchlaufen, die vor dem aktuellen Element liegen.
Das nächstes finden()
und find_all_next ()
Die Methoden durchlaufen alle Tags und Strings, die nach dem aktuellen Element stehen. Ebenso die find_previous ()
und find_all_previous ()
Methoden werden alle Tags und Strings durchlaufen, die vor dem aktuellen Element stehen.
Sie können auch mithilfe von CSS-Selektoren nach Elementen suchen wählen()
Methode. Hier einige Beispiele:
len (soup.select ("p a")) # 411 len (soup.select ("p> a")) # 291 soup.select ("h2: nth-of-type (1)") # [Inhalt
] len (soup.select ("p> a: nth des Typs (2)")) # 46 len (soup.select ("p> a: nth des Typs (10)")) # 6 len (soup.select ("[class * = section]")) # 80 len (soup.select ("[class $ = section]")) # 20
Sie können die DOM-Struktur nicht nur durchsuchen, um ein Element zu finden, sondern auch ändern. Ein Tag kann leicht umbenannt und seine Attribute geändert werden.
Heading_tag = Suppe.select ("h2: nth-of-type (2)") [0] Heading_tag.name = "h3" drucken (Heading_tag) #Feat… heading_tag ['class'] = 'headingChanged' drucken (heading_tag) #
Um mit dem letzten Beispiel fortzufahren, können Sie den Inhalt eines Tags durch eine angegebene Zeichenfolge ersetzen, indem Sie die
.Schnur
Attribut. Wenn Sie den Inhalt nicht ersetzen möchten, sondern am Ende des Tags etwas hinzufügen möchten, können Sie das verwendenanhängen ()
Methode.Wenn Sie etwas an einem bestimmten Ort in ein Tag einfügen möchten, können Sie das verwenden
einfügen()
Methode. Der erste Parameter für diese Methode ist die Position oder der Index, an der Sie den Inhalt einfügen möchten, und der zweite Parameter ist der Inhalt selbst. Sie können den gesamten Inhalt eines Tags mithilfe von entfernenklar()
Methode. Dadurch bleiben Sie nur noch mit dem Tag und seinen Attributen.heading_tag.string = "Features und Philosophie" drucken (heading_tag) #Merkmale und Philosophie
Heading_tag.append ("[Anhang dieses Teils].") print (Heading_tag) #Merkmale und Philosophie [Angefügter Teil].
print (Heading_tag.contents) # ['Features und Philosophie', '[Angehängt dieses Teil].'] Heading_tag.insert (1, 'Diesen Teil eingefügt') print (Heading_tag) #Funktionen und Philosophie Diesen Teil eingefügt [Anhang dieses Teils].
Heading_tag.clear () print (Heading_tag) #Am Anfang dieses Abschnitts haben Sie eine Überschrift der Ebene 2 aus dem Dokument ausgewählt und in eine Überschrift der Ebene 3 geändert. Wenn Sie denselben Selector erneut verwenden, wird jetzt die nächste Überschrift der zweiten Ebene angezeigt, die nach dem Original kam. Dies ist sinnvoll, da die ursprüngliche Überschrift keine Überschrift der zweiten Ebene mehr ist.
Die ursprüngliche Überschrift kann jetzt mit ausgewählt werden
h3: n-te des Typs (2)
. Wenn Sie ein Element oder ein Tag sowie den gesamten Inhalt vollständig aus der Baumstruktur entfernen möchten, können Sie das verwendenzersetzen()
Methode.soup.select ("h3: nth-of-type (2)") [0] # soup.select ("h3: nth-of-type (3)") [0] #Vertiefung… Soup.select ("h3: nth-of-type (2)") [0] .decompose () soup.select ("h3: nth-of-type (2)") [0] #
Vertiefung…
Wenn Sie die ursprüngliche Überschrift zerlegt oder entfernt haben, nimmt die Überschrift an der dritten Stelle ihren Platz ein.
Wenn Sie ein Tag und seinen Inhalt aus der Baumstruktur entfernen möchten, das Tag jedoch nicht vollständig löschen möchten, können Sie das verwenden
Extrakt()
Methode. Diese Methode gibt das extrahierte Tag zurück. Sie haben jetzt zwei verschiedene Bäume, die Sie analysieren können. Die Wurzel des neuen Baums ist das gerade extrahierte Tag.Heading_Tree = Suppe.select ("h3: nth-of-type (2)") [0] .extract () len (Heading_Tree.contents) # 2Sie können ein Tag innerhalb des Baums auch mit einem anderen Element Ihrer Wahl ersetzen
ersetzen mit()
Methode. Diese Methode gibt den Tag oder den String zurück, den sie ersetzt hat. Dies kann hilfreich sein, wenn Sie den ersetzten Inhalt an einer anderen Stelle im Dokument ablegen möchten.soup.h1 #Python (Programmiersprache)
bold_tag = soup.new_tag ("b") bold_tag.string = "Python" soup.h1.replace_with (bold_tag) print (soup.h1) # Keine print (soup.b) # PythonIn dem obigen Code wurde die Hauptüberschrift des Dokuments durch a ersetzt
b
Etikett. Das Dokument hat keineh1
tag, und deshalbDruck (Suppe.h1)
jetzt drucktKeiner
.Abschließende Gedanken
Nachdem Sie die beiden Tutorials dieser Serie gelesen haben, sollten Sie jetzt in der Lage sein, verschiedene Webseiten zu parsen und wichtige Daten aus dem Dokument zu extrahieren. Sie sollten auch in der Lage sein, die ursprüngliche Webseite abzurufen, sie an Ihre eigenen Bedürfnisse anzupassen und die geänderte Version lokal zu speichern.
Wenn Sie Fragen zu diesem Tutorial haben, teilen Sie mir dies bitte in den Kommentaren mit.