Zurück zum Blog
Leitfäden
Sorin-Gabriel Marica13. Juli 20219 Minuten Lesezeit

Extrahieren und Parsen von Webdaten mit Python und BeautifulSoup

Extrahieren und Parsen von Webdaten mit Python und BeautifulSoup

Ein Überblick über BeautifulSoup

BeautifulSoup ist, wie in der Dokumentation angegeben, eine Python-Bibliothek zum Auslesen von Daten aus HTML- und XML-Dateien. Sie können also Python verwenden, um den HTML-Inhalt einer Website zu extrahieren, und dann BeautifulSoup verwenden, um diesen HTML-Inhalt zu parsen, um nur die relevanten Informationen zu erhalten.

Der größte Vorteil von BeautifulSoup ist die einfache Syntax, die es bietet. Mit dieser Bibliothek können Sie im DOM-Baum navigieren, nach bestimmten Elementen suchen oder HTML-Inhalte ändern. All diese Vorteile machten sie zur beliebtesten Python-Bibliothek für das Parsen von HTML- und XML-Dokumenten.

Einrichtung

Um BeautifulSoup zu installieren, sollten Sie sich die Anleitung von hier ansehen, da die Installation je nach Rechner unterschiedlich ist. In diesem Artikel verwende ich ein Linux-System und muss nur den folgenden Befehl ausführen:

pip install beautifulsoup4

Wenn Sie python3 verwenden, müssen Sie die Bibliothek möglicherweise mit dem folgenden Befehl installieren:

pip3 installieren beautifulsoup4

Beachten Sie, dass auf meinem Rechner bereits python3 installiert ist. Wenn Sie neu in Python sind, finden Sie hier eine Anleitung zur Installation. Außerdem sollten Sie sich unseren ultimativen Leitfaden zum Erstellen eines Web Scrapers mit Python ansehen, um noch mehr Informationen zu diesem Thema zu erhalten.

Aufbau eines Scrapers mit BeautifulSoup

Wenn alles reibungslos geklappt hat, können wir jetzt mit der Erstellung unseres eigenen Scrapers beginnen. Für diesen Artikel habe ich mich entschieden, die 100 besten Filme aller Zeiten von RottenTomatoes abzurufen und alles sowohl im JSON- als auch im CSV-Format zu speichern.

Abrufen der Seitenquelle

Zum Aufwärmen und um sich mit BeautifulSoup vertraut zu machen, rufen wir zunächst den vollständigen HTML-Code der Seite ab und speichern ihn in einer neuen Datei namens "page.txt".

Wenn Sie den HTML-Quelltext einer Seite sehen möchten, können Sie das in Google Chrome tun, indem Sie STRG+U drücken. Dadurch wird eine neue Registerkarte geöffnet, und Sie sehen etwas wie dies:

Quelltextansicht einer Seite mit HTML- und Skript-Tags aus einer Filmübersichtsseite

Um die gleiche Quelle mit BeautifulSoup und Python zu erhalten, können wir den folgenden Code verwenden:

import requests
from bs4 import BeautifulSoup
 
scraped_url = 'https://www.rottentomatoes.com/top/bestofrt/'
page = requests.get(scraped_url)
 
soup = BeautifulSoup(page.content, 'html.parser')
 
file = open('page.txt', mode='w', encoding='utf-8')
file.write(soup.prettify())

In diesem Code wird eine Anfrage an die Seite RottenTomatoes gestellt und dann der gesamte Inhalt der Seite in ein BeautifulSoup-Objekt eingefügt. Die einzige Verwendung von BeautifulSoup in diesem Beispiel ist die abschließende Funktion "prettify()", die HTML-Code formatiert, um ihn besser lesbar zu machen.

To understand the function better, for this HTML code “<div><span>Test&lt;/span></div>”, prettify, will add the tabulations and transform it in this formatted code:

<div>

   <span>

       Test

   </span>

</div>

Das Endergebnis des Codes ist die Erstellung einer Datei namens page.txt, die den gesamten Seitenquelltext unseres Links enthält:

Notepad, das den Quellcode einer Seite mit JSON-LD-Listenelementen für eine Tabelle mit den beliebtesten Filmen anzeigt

Beachten Sie, dass dies der Seitenquelltext ist, bevor der Javascript-Code ausgeführt wird. Manchmal ändern Websites ihren Seiteninhalt dynamisch. In diesen Fällen sieht der Seitenquelltext anders aus als der tatsächliche Inhalt, der dem Benutzer angezeigt wird. Wenn Sie möchten, dass Ihr Scraper Javascript ausführt, lesen Sie unseren Leitfaden zur Erstellung eines Web-Scrapers mit Selenium, oder verwenden Sie WebScrapingAPI, unser Produkt, das diese Aufgabe für Sie übernimmt.

Abrufen der Webdaten

Wenn Sie sich die Quelle der vorherigen Seite ansehen, werden Sie sehen, dass Sie die Namen der Filme und ihre Bewertung finden können. Zum Glück für uns lädt RottenTomatoes die Filmliste nicht dynamisch, so dass wir die benötigten Informationen abrufen können.

Zunächst untersuchen wir die Seite und sehen, wie der HTML-Code strukturiert ist. Klicken Sie dazu mit der rechten Maustaste auf einen Filmtitel und wählen Sie die Option "Element inspizieren". Das folgende Fenster sollte sich öffnen:

Die Browser-Entwicklertools markieren eine Tabellenzeile und einen Film-Link auf einer Seite von Rotten Tomatoes

I used the red line to highlight the useful information from this image. You can see that the page displays the top movies in a table and that there are four cells on each table row (<tr> element).

Die erste Zelle enthält die Position des Films, die zweite enthält Informationen über die Bewertungen (Element mit der Klasse tMeterScore ), die dritte enthält den Titel des Films und die letzte Zelle gibt die Anzahl der Bewertungen an.

Mit dem Wissen um diese Struktur können wir nun beginnen, die benötigten Informationen zu extrahieren.

import requests
from bs4 import BeautifulSoup
 
links_base = 'https://www.rottentomatoes.com'
scraped_url = 'https://www.rottentomatoes.com/top/bestofrt/'
page = requests.get(scraped_url)
 
soup = BeautifulSoup(page.content, 'html.parser')
 
table = soup.find("table", class_="table") # We extract just the table code from the entire page
rows = table.findAll("tr") # This will extract each table row, in an array
 
movies = []
 
for index, row in enumerate(rows):
    if index > 0: # We skip the first row since this row only contains the column names
        link = row.find("a") # We get the link from the table row
        rating = row.find(class_="tMeterScore") # We get the element with the class tMeterScore from the table row
        movies.append({
            "link": links_base + link.get('href'), # The href attribute of the link
            "title": link.string.strip(), # The strip function removes blank spaces at the beginning and the end of a string
            "rating": rating.string.strip().replace("&nbsp;", ""), # We remove &nbsp; from the string and the blank spaces
        })
        
print(movies)

Wenn Sie diesen Code ausführen, sollten Sie ein Ergebnis wie dieses erhalten:

Terminalausgabe mit gesammelten Filmtiteln, Links und Bewertungen im JSON-Format

In diesem Beispiel wird der Tabelleninhalt extrahiert und eine Schleife durch die Tabellenzeilen gezogen. Da die erste Zeile nur die Spaltennamen enthält, wird sie übersprungen.

On the rest of the rows, we continue the process by extracting the anchor (<a>) element and the span element with the class “tMeterScore”. Having them, we can now retrieve the information needed.

Der Titel des Films befindet sich im Anker-Element, der Link ist das Attribut "href" des Ankers und die Bewertung befindet sich im span-Element mit der Klasse "tMeterScore". Wir erstellen einfach ein neues Wörterbuch für jede Zeile und fügen es an unsere Filmliste an.

Speichern der Webdaten

Bis jetzt hat der Scraper die Daten abgerufen und formatiert, aber wir haben sie nur im Terminal angezeigt. Alternativ können wir die Informationen auf unserem Computer als JSON oder als CSV speichern. Der vollständige Code des Scrapers (einschließlich der Erstellung einer lokalen Datei) lautet:

import requests
from bs4 import BeautifulSoup
import csv
import json
 
links_base = 'https://www.rottentomatoes.com'
scraped_url = 'https://www.rottentomatoes.com/top/bestofrt/'
page = requests.get(scraped_url)
 
soup = BeautifulSoup(page.content, 'html.parser')
 
table = soup.find("table", class_="table") # We extract just the table code from the entire page
rows = table.findAll("tr") # This will extract each table row from the table, in an array
 
movies = []
 
for index, row in enumerate(rows):
    if index > 0: # We skip the first row since this row only contains the column names
        link = row.find("a") # We get the link from the table row
        rating = row.find(class_="tMeterScore") # We get the element with the class tMeterScore from the table row
        movies.append({
            "link": links_base + link.get('href'), # The href attribute of the link
            "title": link.string.strip(), # The strip function removes blank spaces at the beginning and the end of a string
            "rating": rating.string.strip().replace("&nbsp;", ""), # We remove &nbsp; from the string and the blank spaces
        })
        
file = open('movies.json', mode='w', encoding='utf-8')
file.write(json.dumps(movies))
 
writer = csv.writer(open("movies.csv", 'w'))
for movie in movies:
    writer.writerow(movie.values())

Kratzen Sie noch weiter

Jetzt, wo Sie alle Informationen haben, können Sie sich weiter mit dem Scraping beschäftigen. Denken Sie daran, dass jeder Film einen Link hat. Sie können mit dem Scrapen der Filmseiten fortfahren und noch mehr Informationen über sie extrahieren.

Wenn Sie sich zum Beispiel die Filmseite It Happened One Night (1934) ansehen, können Sie sehen, dass Sie immer noch hilfreiche Informationen wie die Zuschauerzahl, die Filmdauer, das Genre usw. abrufen können.

Allerdings sehen all diese Anfragen in einem kurzen Zeitraum sehr ungewöhnlich aus und könnten zu CAPTCHA-Validierungen oder sogar IP-Sperren führen. Um dies zu vermeiden, sollten Sie rotierende Proxys verwenden, damit der gesendete Verkehr natürlich aussieht und von mehreren IPs kommt.

Weitere Merkmale von BeautifulSoup

Während unser RottenTomatoes Scraper vollständig ist, hat BeautifulSoup noch viel zu bieten. Wann immer Sie an einem Projekt arbeiten, sollten Sie den Link zur Dokumentation offen halten, damit Sie schnell nach einer Lösung suchen können, wenn Sie nicht weiterkommen.

BeautifulSoup ermöglicht zum Beispiel die Navigation im DOM-Baum der Seite:

from bs4 import BeautifulSoup
 
soup = BeautifulSoup("<head><title>Title</title></head><body><div><p>Some text <span>Span</span></p></div></body>", 'html.parser')
 
print(soup.head.title) # Will print "<title>Title</title>"
print(soup.body.div.p.span) # Will print "<span>Span</span>"

Diese Funktion kann Ihnen helfen, wenn Sie ein Element auswählen müssen, das nicht durch seine Attribute identifiziert werden kann. In diesem Fall ist die einzige Möglichkeit, es zu finden, die Struktur des DOM.

Eine weitere coole Sache an BeautifulSoup ist, dass Sie den Seitenquelltext ändern können:

from bs4 import BeautifulSoup
 
soup = BeautifulSoup("<head><title>Title</title></head><body><div><p>Some text <span>Span</span></p></div></body>", 'html.parser')
 
soup.head.title.string = "New Title"
print(soup)
# The line above will print "<head><title>New Title</title></head><body><div><p>Some text <span>Span</span></p></div></body>"

Dies kann von unschätzbarem Wert sein, wenn Sie einen Dienst einrichten wollen, der es den Benutzern ermöglicht, ihre Seiten zu optimieren. Sie können das Skript zum Beispiel verwenden, um eine Website zu scrapen, das CSS zu erhalten, es zu verkleinern und es im HTML-Quelltext zu ersetzen. Die Möglichkeiten sind endlos!

Immer schlau kratzen

Ich möchte, dass Sie sich Folgendes merken: Python und Beautifulsoup für Web Scraping zu verwenden, ist eine ausgezeichnete Idee. Es macht den Prozess im Vergleich zu anderen Programmiersprachen viel einfacher.

Der Scraper, den wir gebaut haben, um die am besten bewerteten Filme aller Zeiten von RottenTomatoes abzurufen, kann in nur wenigen Minuten programmiert werden, und Sie können ihn sogar zusammen mit dem IMDB-Scraper aus unserem ultimativen Leitfaden für Scraping mit PHP verwenden.

Einige Websites sind jedoch für Scraper leichter zugänglich als andere. Während das Projekt aus diesem Artikel einfach und unterhaltsam ist, sind manche alles andere als das. Manchmal tun Websites alles in ihrer Macht Stehende, um zu verhindern, dass ihre Inhalte abgegriffen werden.

In bestimmten Situationen ist die einzige Möglichkeit, Inhalte zu scrapen, die Maskierung Ihrer Arbeit mit mehreren IPs und einem echten Browser. Für diese Art von Situation haben wir WebScrapingAPI entwickelt, eine leistungsstarke Lösung, die rotierende Proxys und Javascript-Rendering bietet und es Ihnen ermöglicht, jede beliebige Website mit einem Minimum an Kopfschmerzen zu scrapen!

Verlassen Sie sich nicht nur auf mein Wort, sondern probieren Sie es selbst aus! Sie können Ihre kostenlose Testversion gleich jetzt starten und 5000 API-Aufrufe erhalten, ohne sensible Daten wie Ihre Kreditkartendetails herausgeben zu müssen.

Über den Autor
Sorin-Gabriel Marica, Full-Stack-Entwickler bei WebScrapingAPI
Sorin-Gabriel MaricaFull-Stack-Entwickler

Sorin Marica ist Full-Stack- und DevOps-Entwickler bei WebScrapingAPI, wo er Produktfunktionen entwickelt und die Infrastruktur wartet, die für den reibungslosen Betrieb der Plattform sorgt.

Los geht’s

Sind Sie bereit, Ihre Datenerfassung zu erweitern?

Schließen Sie sich den über 2.000 Unternehmen an, die WebScrapingAPI nutzen, um Webdaten im Unternehmensmaßstab ohne zusätzlichen Infrastrukturaufwand zu extrahieren.