Scraping mit Cheerio: Wie man auf einfache Weise Daten von Webseiten sammelt
Raluca Penciuc am 21. Dezember 2022
Vorbei sind die Zeiten, in denen Sie die Daten, die Ihnen beim Anschub Ihrer Projekte helfen, manuell gesammelt und verarbeitet haben. Egal, ob es sich um eine E-Commerce-Website oder einen Algorithmus zur Lead-Generierung handelt, eines ist sicher: Der Prozess der Datenerfassung war mühsam und zeitaufwändig.
In diesem Artikel erfahren Sie, wie Cheerio Ihnen mit seinen umfangreichen Funktionen zum Parsen von Markup-Sprachen helfen kann, zunächst anhand einiger trivialer Beispiele und dann anhand eines realen Anwendungsfalls.
Einführung in Cheerio
"Aber was ist Cheerio?", werden Sie sich vielleicht fragen. Nun, um ein häufiges Missverständnis aufzuklären, werde ich damit beginnen, was Cheerio nicht ist: ein Browser.
Die Verwirrung mag daher rühren, dass Cheerio in einer Auszeichnungssprache geschriebene Dokumente analysiert und dann eine API anbietet, mit der Sie die resultierende Datenstruktur bearbeiten können. Aber im Gegensatz zu einem Browser wird Cheerio das Dokument nicht visuell darstellen, keine CSS-Dateien laden oder Javascript ausführen.
Im Grunde genommen besteht die Aufgabe von Cheerio darin, eine HTML- oder XML-Eingabe zu empfangen, die Zeichenkette zu parsen und die API zurückzugeben. Das macht es unglaublich schnell und einfach zu verwenden, daher seine Beliebtheit unter Node.js-Entwicklern.
Einrichten der Umgebung
Sehen wir uns nun einige praktische Beispiele dafür an, was Cheerio leisten kann. Als Erstes müssen Sie sicherstellen, dass Ihre Umgebung vollständig eingerichtet ist.
Es versteht sich von selbst, dass Sie Node.js auf Ihrem Rechner installiert haben müssen. Falls nicht, folgen Sie einfach den Anweisungen auf der offiziellen Website, je nach Ihrem Betriebssystem.
Stellen Sie sicher, dass Sie die Long Term Support-Version (LTS) herunterladen und vergessen Sie nicht den Node.js Package Manager (NPM). Sie können diese Befehle ausführen, um sicherzustellen, dass die Installation ordnungsgemäß durchgeführt wurde:
node -v
npm -v
Die Ausgabe sollte wie folgt aussehen:

Nun zur IDE-Debatte: Für dieses Tutorial werde ich Visual Studio Code verwenden, da es ziemlich flexibel und einfach zu bedienen ist, aber Sie können jede IDE verwenden, die Sie bevorzugen.
Erstellen Sie einfach einen Ordner, in dem Ihr kleines Projekt gespeichert wird, und öffnen Sie ein Terminal. Führen Sie den folgenden Befehl aus, um ein Node.js-Projekt einzurichten:
npm init -y
Dadurch wird eine Standardversion der package.json-Datei erstellt, die jederzeit geändert werden kann.
Nächster Schritt: Ich werde TypeScript zusammen mit den Typdefinitionen für Node.js installieren:
npm install typescript @types/node -save-dev
Ich habe TypeScript in diesem Tutorial wegen seiner optionalen statischen Typisierung von JavaScript-Objekten gewählt, die den Code kugelsicherer macht, wenn es um Typfehler geht.
Dies ist derselbe Vorteil, der laut einer aktuellen CircleCI-Umfrage zu den beliebtesten Programmiersprachen die Popularität von JavaScript stetig erhöht hat.
Um die korrekte Installation des vorherigen Befehls zu überprüfen, können Sie diesen ausführen:
npx tsc --version
Jetzt werde ich die Konfigurationsdatei tsconfig.json im Stammverzeichnis des Projekts erstellen, die die Compiler-Optionen definieren soll. Wenn Sie diese Datei und ihre Eigenschaften besser verstehen wollen, hilft Ihnen die offizielle TypeScript-Dokumentation weiter.
Wenn nicht, kopieren Sie einfach den folgenden Text und fügen ihn ein:
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist"
},
"lib": ["es2015"]
}
Fast fertig! Jetzt müssen Sie noch Cheerio installieren (natürlich):
npm install cheerio
Zu guter Letzt erstellen Sie das Verzeichnis src , das die Codedateien enthalten wird. Apropos Codedatei: Erstellen Sie die Datei index.ts und legen Sie sie in das src-Verzeichnis .
Wie funktioniert Cheerio?
Perfekt! Jetzt kann es losgehen.
Im Moment werde ich einige grundlegende Cheerio-Funktionen anhand eines statischen HTML-Dokuments veranschaulichen. Kopieren Sie einfach den unten stehenden Inhalt und fügen Sie ihn in eine neue static.html-Datei in Ihrem Projekt ein:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Page Name - Static HTML Example</title>
</head>
<body>
<div class="page-heading">
<h1>Page Heading</h1>
</div>
<div class="page-container">
<div class="page-content">
<ul>
<li>
<a href="#">Item 1</a>
<p class="price">$100</p>
<p class="stock">12</p>
</li>
<li>
<a href="#">Item 2</a>
<p class="price">$200</p>
<p class="stock">422</p>
</li>
<li>
<a href="#">Item 3</a>
<p class="price">$150</p>
<p class="stock">5</p>
</li>
</ul>
</div>
</div>
<footer class="page-footer">
<p>Last Updated: Friday, September 23, 2022</p>
</footer>
</body>
</html>
Als Nächstes müssen Sie die HTML-Datei als Eingabe an Cheerio übergeben, das dann die resultierende API zurückgibt:
import fs from 'fs'
import * as cheerio from 'cheerio'
const staticHTML = fs.readFileSync('static.html')
const $ = cheerio.load(staticHTML)
Wenn Sie bei diesem Schritt eine Fehlermeldung erhalten, vergewissern Sie sich, dass die Eingabedatei ein gültiges HTML-Dokument enthält, denn ab Cheerio Version 1.0.0 wird auch dieses Kriterium überprüft.
Jetzt können Sie damit beginnen, mit den Möglichkeiten von Cheerio zu experimentieren. Das NPM-Paket ist bekannt für seine jQuery-ähnliche Syntax und die Verwendung von CSS-Selektoren zur Extraktion der gesuchten Knoten. Sie können die offizielle Dokumentation lesen, um einen besseren Eindruck zu bekommen.
Nehmen wir an, Sie möchten den Seitentitel extrahieren:
const title = $('title').text()
console.log("Statischer HTML-Seitentitel:", title)
Wir sollten das testen, oder? Sie verwenden Typescript, also müssen Sie den Code kompilieren, wodurch das dist-Verzeichnis erstellt wird, und dann die zugehörige index.js-Datei ausführen. Der Einfachheit halber werde ich das folgende Skript in der package.json-Datei definieren:
"scripts": {
"test": "npx tsc && node dist/index.js",
}
Auf diese Weise brauche ich nur noch zu laufen:
npm test ausführen
und das Skript wird beide Schritte, die ich gerade beschrieben habe, ausführen.
Okay, aber was ist, wenn der Selektor auf mehr als ein HTML-Element passt? Versuchen wir, den Namen und den Lagerwert der in der unsortierten Liste aufgeführten Elemente zu extrahieren:
const itemStocks = {}
$('li').each((index, element) => {
const name = $(element).find('a').text()
const stock = $(element).find('p.stock').text()
itemStocks[name] = stock
})
console.log("All items stock:", itemStocks)
Führen Sie nun das Verknüpfungsskript erneut aus, und die Ausgabe in Ihrem Terminal sollte wie folgt aussehen:
Static HTML page title: Page Name - Static HTML Example
All items stock: { 'Item 1': '12', 'Item 2': '422', 'Item 3': '5' }
Anwendungsfälle für Cheerio
Das war also im Grunde nur die Spitze des Eisbergs. Cheerio ist auch in der Lage, XML-Dokumente zu parsen, den Stil der HTML-Elemente zu extrahieren und sogar die Attribute der Knoten zu ändern.
Aber wie kann Cheerio in einem realen Anwendungsfall helfen?
Nehmen wir an, wir möchten einige Daten sammeln, um ein Modell für maschinelles Lernen für ein zukünftiges größeres Projekt zu trainieren. Normalerweise würde man bei Google nach Trainingsdateien suchen und sie herunterladen oder die API der Website nutzen.
Aber was tun Sie, wenn Sie einige relevante Dateien nicht finden können oder die Website, die Sie besuchen, keine API bereitstellt, eine Ratenbeschränkung für die Daten hat oder nicht die gesamten Daten anbietet, die Sie auf einer Seite sehen?
Genau hier kommt Web Scraping ins Spiel. Wenn Sie sich für weitere praktische Anwendungsfälle von Web Scraping interessieren, können Sie sich diesen gut geschriebenen Artikel in unserem Blog ansehen.
Zurück zu unserem Schaf. Nehmen wir für das Beispiel an, dass wir uns in genau dieser Situation befinden: Wir wollen Daten, und die Daten sind nirgends zu finden. Denken Sie daran, dass Cheerio weder die HTML-Extraktion noch das Laden von CSS oder die Ausführung von JS übernimmt.
In unserem Tutorial verwende ich also Puppeteer, um zur Website zu navigieren, den HTML-Code zu erfassen und ihn in einer Datei zu speichern. Dann wiederhole ich den Vorgang aus dem vorherigen Abschnitt.
Um genauer zu sein, möchte ich einige öffentliche Meinungen auf Reddit zu einem beliebten Trommelmodul sammeln und die Daten in einer einzigen Datei zentralisieren, die dann in ein potenzielles ML-Trainingsmodell eingespeist wird. Was als nächstes passiert, kann ebenfalls variieren: Stimmungsanalyse, Marktforschung und so weiter.

Anfrage für das HTML
Schauen wir uns an, wie dieser Anwendungsfall in Code umgesetzt werden kann. Zunächst müssen Sie das NPM-Paket von Puppeteer installieren:
npm Puppeteer installieren
Ich werde auch eine neue Datei reddit.ts erstellen, um das Projekt besser zu organisieren, und ein neues Skript in der package.json-Datei definieren:
"scripts": {
"test": "npx tsc && node dist/index.js",
"parse": "npx tsc && node dist/reddit.js"
},
Um das HTML-Dokument zu erhalten, werde ich eine Funktion definieren, die wie folgt aussieht:
import fs from 'fs'
import puppeteer from 'puppeteer'
import * as cheerio from 'cheerio'
async function getContent(url: string): Promise<void> {
// Open the browser and a new tab
const browser = await puppeteer.launch()
const page = await browser.newPage()
// Navigate to the URL and write the content to file
await page.goto(url)
const pageContent = await page.content()
fs.writeFileSync("reddit.html", pageContent)
// Close the browser
await browser.close()
console.log("Got the HTML. Check the reddit.html file.")
}
Um dies schnell zu testen, fügen Sie einen Einstiegspunkt in Ihren Code ein und rufen die Funktion auf:
async function main() {
const targetURL = 'https://old.reddit.com/r/Drumming/comments/r3tidc/yamaha_ead10/'
await getContent(targetURL)
}
main()
.then(() => {console.log("All done!")})
.catch(e => {console.log("Unexpected error occurred:", e.message)})
Die Datei reddit.html sollte in Ihrem Projektbaum erscheinen, die das gewünschte HTML-Dokument enthält.
Wo sind meine Knotenpunkte?
Jetzt kommt ein etwas schwierigerer Teil: Sie müssen die Knoten identifizieren, die für unseren Anwendungsfall von Interesse sind. Gehen Sie zurück zu Ihrem Browser (dem echten) und navigieren Sie zu der Ziel-URL. Fahren Sie mit dem Mauszeiger über den Abschnitt mit den Kommentaren, klicken Sie mit der rechten Maustaste und wählen Sie dann die Option "Inspect".
Die Registerkarte Entwicklertools öffnet sich und zeigt Ihnen genau das HTML-Dokument, das Sie zuvor auf Ihrem Computer gespeichert haben.

Um nur die Kommentare zu extrahieren, müssen Sie die eindeutigen Selektoren für diesen Abschnitt der Seite identifizieren. Wie Sie sehen können, befindet sich die gesamte Liste der Kommentare in einem div-Container mit der Klasse sitetable nestedlisting.
Bei genauerer Betrachtung hat jeder einzelne Kommentar ein Formularelement als übergeordnetes Element mit der Klasse usertext warn-on-unload. Unten sehen Sie dann, dass der Text jedes Kommentars auf mehrere p-Elemente verteilt ist.
Parsen und Speichern der Daten
Schauen wir uns an, wie das im Code funktioniert:
function parseComments(): void {
// Load the HTML document
const staticHTML = fs.readFileSync('reddit.html')
const $ = cheerio.load(staticHTML)
// Get the comments section
const commentsSection = $('div.sitetable.nestedlisting')
// Iterate each comment
const comments = []
$(commentsSection).find('form.usertext.warn-on-unload').each((index, comment) => {
let commentText = ""
// Iterate each comment section and concatenate them
$(comment).find('p').each((index, piece) => {
commentText += $(piece).text() + '\n'
})
comments.push(commentText)
})
// Write the results to external file
fs.writeFileSync("comments.json", JSON.stringify({comments}))
}
Gut, und jetzt aktualisieren wir den Einstiegspunkt mit der neu definierten Funktion und sehen, wie dieser Code zusammenarbeitet:
async function main() {
const targetURL = 'https://old.reddit.com/r/Drumming/comments/r3tidc/yamaha_ead10/'
await getContent(targetURL)
parseComments()
}
main()
.then(() => {console.log("All done. Check the comments.csv file.")})
.catch(e => {console.log("Unexpected error occurred:", e.message)})
Führen Sie den Code mit dem zuvor definierten Skript aus:
npm ausführen parse
Es dauert etwa 5 bis 10 Sekunden, bis sich der Headless-Browser öffnet und zu unserer Ziel-URL navigiert. Wenn Sie noch neugieriger sind, können Sie Zeitstempel am Anfang und am Ende jeder unserer Funktionen hinzufügen, um zu sehen, wie schnell Cheerio ist.
Die Datei comments.json sollte unser Endergebnis sein:

Dieser Anwendungsfall kann leicht erweitert werden, um die Anzahl der "Upvotes" und "Downvotes" für jeden Kommentar zu analysieren, oder um die verschachtelten Antworten der Kommentare zu erhalten. Die Möglichkeiten sind endlos.
Zum Mitnehmen
Vielen Dank, dass Sie es bis zum Ende dieses Tutorials geschafft haben. Ich hoffe, Sie haben verstanden, wie unverzichtbar Cheerio für den Prozess der Datenextraktion ist und wie Sie es schnell in Ihr nächstes Scraping-Projekt integrieren können.
Wir verwenden Cheerio auch in unserem Produkt, WebScrapingAPI. Wenn Sie jemals mit den vielen Herausforderungen beim Web-Scraping (IP-Sperren, Bot-Erkennung usw.) konfrontiert werden, sollten Sie Cheerio einmal ausprobieren.
Nachrichten und Aktualisierungen
Bleiben Sie auf dem Laufenden mit den neuesten Web Scraping-Anleitungen und Nachrichten, indem Sie unseren Newsletter abonnieren.
We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Ähnliche Artikel

Starten Sie mit WebScrapingAPI, der ultimativen Web-Scraping-Lösung! Sammeln Sie Echtzeitdaten, umgehen Sie Anti-Bot-Systeme und genießen Sie professionellen Support.


Erfahren Sie, wie Sie mit Hilfe von Datenparsing, HTML-Parsing-Bibliotheken und schema.org-Metadaten effizient Daten für Web-Scraping und Datenanalysen extrahieren und organisieren können.


Entdecken Sie 3 Möglichkeiten, wie Sie mit Puppeteer Dateien herunterladen und einen Web Scraper erstellen können, der genau das tut.
