So arbeiten Sie mit Webdaten mithilfe von Requests und Beautiful Soup in Python 3
Einführung
Das Web bietet uns mehr Daten, als wir lesen und verstehen können, weshalb wir oft versuchen, diese Informationen programmatisch zu bearbeiten, um sie zu verstehen. Manchmal werden uns diese Daten von Website-Erstellern über .csv-Dateien oder durch eine API (Application Programming Interface) zur Verfügung gestellt. In anderen Fällen müssen wir den Text selbst aus dem Web sammeln.
Dieses Tutorial wird erklären, wie man mit den Python-Paketen Requests und Beautiful Soup arbeitet, um Daten von Webseiten zu nutzen. Das Requests-Modul ermöglicht es Ihnen, Ihre Python-Programme mit Webdiensten zu integrieren, während das Beautiful Soup-Modul entwickelt wurde, um das Screen-Scraping schnell durchzuführen. Mithilfe der interaktiven Python-Konsole und dieser beiden Bibliotheken werden wir durchgehen, wie man eine Webseite erfasst und mit den dort verfügbaren Textinformationen arbeitet.
Voraussetzungen
Um dieses Tutorial abzuschließen, benötigen Sie eine Entwicklungsumgebung für Python 3. Sie können die entsprechende Anleitung für Ihr Betriebssystem aus der Reihe "Wie man eine lokale Programmierumgebung für Python 3 installiert und einrichtet" oder "Wie man Python 3 installiert und eine Programmierumgebung auf einem Ubuntu 20.04-Server einrichtet" folgen, um alles zu konfigurieren, was Sie benötigen.
Zusätzlich sollten Sie mit Folgendem vertraut sein:
- Die Python-interaktive Konsole
- Module in Python 3 importieren
- HTML-Struktur und Tagging
Mit Ihrer eingerichteten Entwicklungsumgebung und diesen Python-Programmierkonzepten im Hinterkopf, lassen Sie uns mit Requests und Beautiful Soup arbeiten.
Anforderungen installieren
Lass uns beginnen, indem wir unsere Python 3-Programmierumgebung aktivieren. Stelle sicher, dass du im Verzeichnis bist, in dem sich deine Umgebung befindet, und führe den folgenden Befehl aus:
- . my_env/bin/activate
Um mit Webseiten zu arbeiten, müssen wir die Seite anfordern. Die Requests-Bibliothek ermöglicht es Ihnen, HTTP in Ihren Python-Programmen auf eine menschenlesbare Weise zu verwenden.
Mit unserer aktivierten Programmierumgebung werden wir Requests mit pip installieren:
- pip install requests
Während die Requests-Bibliothek installiert wird, erhalten Sie die folgende Ausgabe:
Collecting requests
Downloading requests-2.26.0-py2.py3-none-any.whl (88kB)
100% |████████████████████████████████| 92kB 3.1MB/s
...
Installing collected packages: chardet, urllib3, certifi, idna, requests
Successfully installed certifi-2017.4.17 chardet-3.0.4 idna-2.5 requests-2.26.0 urllib3-1.21.1
Wenn Requests zuvor installiert war, hätten Sie von Ihrem Terminalfenster eine ähnliche Rückmeldung erhalten:
Requirement already satisfied
...
Mit Requests, das in unserer Programmierumgebung installiert ist, können wir mit der Installation des nächsten Moduls fortfahren.
Beautiful Soup installieren
Genau wie bei Requests werden wir Beautiful Soup mit pip installieren. Die aktuelle Version von Beautiful Soup 4 kann mit dem folgenden Befehl installiert werden:
- pip install beautifulsoup4
Sobald Sie diesen Befehl ausführen, sollten Sie eine Ausgabe sehen, die ähnlich aussieht wie die folgende:
Collecting beautifulsoup4
Downloading beautifulsoup4-4.10.0-py3-none-any.whl (97 kB)
|████████████████████████████████| 97 kB 6.8 MB/s
Collecting soupsieve>1.2
Downloading soupsieve-2.3.1-py3-none-any.whl (37 kB)
Installing collected packages: soupsieve, beautifulsoup4
Successfully installed beautifulsoup4-4.10.0 soupsieve-2.3.1
Jetzt, da sowohl Beautiful Soup als auch Requests installiert sind, können wir uns damit befassen, wie man mit den Bibliotheken arbeitet, um Webseiten zu scrapen.
Eine Webseite mit Requests sammeln
Mit den beiden Python-Bibliotheken, die wir jetzt installiert haben, können wir uns damit vertraut machen, eine einfache Webseite Schritt für Schritt zu durchlaufen.
Lass uns zuerst in die Python-Interaktive Konsole wechseln:
- python
Von hier aus werden wir das Requests-Modul importieren, damit wir eine Beispiel-Webseite abrufen können:
- import requests
-
Wir werden die URL (unten) der Beispiel-Webseite, mockturtle.html, der Variablen url zuweisen:
- url = 'https://assets.linux-console.net/articles/eng_python/beautiful-soup/mockturtle.html'
-
Als nächstes können wir das Ergebnis einer Anfrage dieser Seite der Variablen page mit der Methode request.get() zuweisen. Wir übergeben die URL der Seite (die der Variablen url zugewiesen wurde) an diese Methode.
- page = requests.get(url)
-
Die Variable page wird einem Response-Objekt zugewiesen:
>>> page
<Response [200]>
>>>
Das obige Response-Objekt zeigt uns die status_code-Eigenschaft in eckigen Klammern (in diesem Fall 200). Diese Eigenschaft kann explizit aufgerufen werden:
>>> page.status_code
200
>>>
Der zurückgegebene Code 200 sagt uns, dass die Seite erfolgreich heruntergeladen wurde. Codes, die mit der Zahl 2 beginnen, weisen im Allgemeinen auf Erfolg hin, während Codes, die mit 4 oder 5 beginnen, darauf hindeuten, dass ein Fehler aufgetreten ist. Weitere Informationen zu HTTP-Statuscodes finden Sie in den Status Code Definitions des W3C.
Um mit Webdaten zu arbeiten, möchten wir den textbasierten Inhalt von Webdateien abrufen. Wir können den Inhalt der Serverantwort mit page.text (oder page.content, wenn wir die Antwort in Bytes abrufen möchten) lesen.
- page.text
Sobald wir ENTER drücken, erhalten wir die folgende Ausgabe:
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\n<html lang="en-US"
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n<head>\n <meta
http-equiv="content-type" content="text/html; charset=us-ascii" />\n\n <title>Turtle
Soup</title>\n</head>\n\n<body>\n <h1>Turtle Soup</h1>\n\n <p class="verse"
id="first">Beautiful Soup, so rich and green,<br />\n Waiting in a hot tureen!<br />\n Who for
such dainties would not stoop?<br />\n Soup of the evening, beautiful Soup!<br />\n Soup of
the evening, beautiful Soup!<br /></p>\n\n <p class="chorus" id="second">Beau--ootiful
Soo--oop!<br />\n Beau--ootiful Soo--oop!<br />\n Soo--oop of the e--e--evening,<br />\n
Beautiful, beautiful Soup!<br /></p>\n\n <p class="verse" id="third">Beautiful Soup! Who cares
for fish,<br />\n Game or any other dish?<br />\n Who would not give all else for two<br />\n
Pennyworth only of Beautiful Soup?<br />\n Pennyworth only of beautiful Soup?<br /></p>\n\n
<p class="chorus" id="fourth">Beau--ootiful Soo--oop!<br />\n Beau--ootiful Soo--oop!<br />\n
Soo--oop of the e--e--evening,<br />\n Beautiful, beauti--FUL SOUP!<br
/></p>\n</body>\n</html>\n'
>>>
Hier sehen wir, dass der gesamte Text der Seite ausgedruckt wurde, mit all seinen HTML-Tags. Allerdings ist es schwer zu lesen, da es nicht viel Platz gibt.
Im nächsten Abschnitt können wir das Beautiful Soup-Modul nutzen, um mit diesen Textdaten auf eine für Menschen freundlichere Weise zu arbeiten.
Durch eine Seite mit Beautiful Soup navigieren
Die Beautiful Soup-Bibliothek erstellt einen Parsebaum aus analysierten HTML- und XML-Dokumenten (einschließlich Dokumenten mit nicht geschlossenen Tags oder "Tag-Suppe" sowie anderem fehlerhaften Markup). Diese Funktionalität macht den Text der Webseite lesbarer als das, was wir aus dem Requests-Modul gesehen haben.
Zuerst importieren wir Beautiful Soup in die Python-Konsole:
- from bs4 import BeautifulSoup
-
Als Nächstes werden wir das page.text Dokument durch das Modul laufen lassen, um uns ein BeautifulSoup Objekt zu geben - das ist ein Parse-Baum von dieser geparsten Seite, den wir erhalten, indem wir Pythons integrierten html.parser über das HTML laufen lassen. Das konstruierte Objekt repräsentiert das mockturtle.html Dokument als eine geschachtelte Datenstruktur. Dies wird der Variable soup zugewiesen.
- soup = BeautifulSoup(page.text, 'html.parser')
-
Um den Inhalt der Seite im Terminal anzuzeigen, können wir ihn mit der prettify() Methode ausgeben, um den Beautiful Soup Parse-Baum in einen schön formatierten Unicode-String umzuwandeln.
- print(soup.prettify())
Dadurch wird jedes HTML-Tag in seiner eigenen Zeile dargestellt:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<title>
Turtle Soup
</title>
</head>
<body>
<h1>
Turtle Soup
</h1>
<p class="verse" id="first">
Beautiful Soup, so rich and green,
<br/>
Waiting in a hot tureen!
<br/>
Who for such dainties would not stoop?
<br/>
Soup of the evening, beautiful Soup!
...
</html>
In der obigen Ausgabe können wir sehen, dass es pro Zeile ein Tag gibt und auch, dass die Tags aufgrund des von Beautiful Soup verwendeten Baumschemas verschachtelt sind.
Instanzen eines Tags finden
Wir können ein einzelnes Tag von einer Seite extrahieren, indem wir die find_all-Methode von Beautiful Soup verwenden. Dies gibt alle Instanzen eines bestimmten Tags innerhalb eines Dokuments zurück.
- soup.find_all('p')
Die Ausführung dieser Methode auf unserem Objekt gibt den vollständigen Text des Songs zusammen mit den relevanten <p>-Tags und allen Tags zurück, die sich innerhalb des angeforderten Tags befinden, zu denen hier auch die Zeilenumbruch-Tags <br/> gehören:
[<p class="verse" id="first">Beautiful Soup, so rich and green,<br/>
Waiting in a hot tureen!<br/>
Who for such dainties would not stoop?<br/>
Soup of the evening, beautiful Soup!<br/>
Soup of the evening, beautiful Soup!<br/></p>, <p class="chorus" id="second">Beau--ootiful Soo--oop!<br/>
...
Beau--ootiful Soo--oop!<br/>
Soo--oop of the e--e--evening,<br/>
Beautiful, beauti--FUL SOUP!<br/></p>]
Sie werden in der obigen Ausgabe feststellen, dass die Daten in eckigen Klammern [ ] enthalten sind. Das bedeutet, dass es sich um einen Python-Liste-Datentyp handelt.
Da es sich um eine Liste handelt, können wir ein bestimmtes Element darin aufrufen (zum Beispiel das dritte <p>-Element) und die Methode get_text() verwenden, um den gesamten Text aus diesem Tag zu extrahieren:
- soup.find_all('p')[2].get_text()
Die Ausgabe, die wir erhalten, wird in diesem Fall das sein, was im dritten <p>-Element steht:
'Beautiful Soup! Who cares for fish,\n Game or any other dish?\n Who would not give all else for two\n Pennyworth only of Beautiful Soup?\n Pennyworth only of beautiful Soup?'
Beachten Sie, dass \n Zeilenumbrüche ebenfalls in der oben zurückgegebenen Zeichenfolge angezeigt werden.
Tags nach Klasse und ID finden
HTML-Elemente, die auf CSS-Selektoren wie Klassen und IDs verweisen, können beim Arbeiten mit Webdaten mit Beautiful Soup hilfreich sein. Wir können bestimmte Klassen und IDs anvisieren, indem wir die Methode find_all() verwenden und die Klassen- und ID-Strings als Argumente übergeben.
Zuerst werden wir alle Instanzen der Klasse chorus finden. In Beautiful Soup werden wir den String für die Klasse dem Schlüsselwort-Argument class_ zuweisen:
- soup.find_all(class_='chorus')
Wenn wir die obige Zeile ausführen, erhalten wir die folgende Liste als Ausgabe:
[<p class="chorus" id="second">Beau--ootiful Soo--oop!<br/>
Beau--ootiful Soo--oop!<br/>
Soo--oop of the e--e--evening,<br/>
Beautiful, beautiful Soup!<br/></p>, <p class="chorus" id="fourth">Beau--ootiful Soo--oop!<br/>
Beau--ootiful Soo--oop!<br/>
Soo--oop of the e--e--evening,<br/>
Beautiful, beauti--FUL SOUP!<br/></p>]
Die beiden <p>-Tag-Bereiche mit der Klasse chorus wurden im Terminal ausgegeben.
Wir können auch angeben, dass wir nur nach der Klasse chorus innerhalb von <p>-Tags suchen möchten, falls sie für mehr als ein Tag verwendet wird:
- soup.find_all('p', class_='chorus')
Das Ausführen der oben stehenden Zeile wird die gleiche Ausgabe wie zuvor erzeugen.
Wir können auch Beautiful Soup verwenden, um IDs zu zielen, die mit HTML-Tags verbunden sind. In diesem Fall weisen wir dem Schlüsselwortargument id den String 'third' zu:
- soup.find_all(id='third')
Sobald wir die oben stehende Zeile ausführen, erhalten wir die folgende Ausgabe:
[<p class="verse" id="third">Beautiful Soup! Who cares for fish,<br/>
Game or any other dish?<br/>
Who would not give all else for two<br/>
Pennyworth only of Beautiful Soup?<br/>
Pennyworth only of beautiful Soup?<br/></p>]
Der mit dem <p>-Tag mit der ID third verbundene Text wird zusammen mit den relevanten Tags im Terminal ausgegeben.
Schlussfolgerung
Dieses Tutorial hat Sie durch das Abrufen einer Webseite mit dem Requests-Modul in Python geführt und Ihnen einige erste Schritte beim Scraping der Textdaten dieser Webseite gezeigt, um ein Verständnis für Beautiful Soup zu gewinnen.
Von hier aus können Sie ein Web-Scraping-Programm erstellen, das eine CSV-Datei aus Daten, die von der Website gesammelt wurden, erstellt, indem Sie das Tutorial "Wie man Webseiten mit Beautiful Soup und Python 3 durchsucht" befolgen.