Die Struktur einer HTML-Tabelle verstehen
HTML-Tabellen sind ein leistungsstarkes Werkzeug, um strukturierte tabellarische Daten zu markieren und sie so darzustellen, dass sie für Benutzer leicht lesbar und verständlich sind. Tabellen bestehen aus Daten, die in Zeilen und Spalten organisiert sind, und HTML bietet verschiedene Elemente zur Definition und Strukturierung dieser Daten. Eine Tabelle muss mindestens die folgenden Elemente enthalten: <table>, <tr> (Tabellenzeile) und <td> (Tabellendaten). Für zusätzliche Struktur und semantischen Wert können Tabellen auch das Element <th> (Tabellenkopf) sowie die Elemente <thead>, <tbody> und <tfoot> enthalten.
Lassen Sie uns die Tags anhand eines kleinen Beispiels näher betrachten.
Beachten Sie, wie die zweite Tabelle eine spezifischere Syntax verwendet
Das Tag <thead> wendet eine fette Schriftart auf die Zellen „Fruit“ und „Color“ in der zweiten Tabelle an. Abgesehen davon können Sie sehen, wie beide Syntaxen dieselbe Organisation der Daten erreichen.
Beim Scraping von Tabellen aus dem Web ist es wichtig zu beachten, dass Sie auf Tabellen stoßen können, die mit unterschiedlichem Grad an semantischer Spezifität geschrieben sind. Mit anderen Worten: Einige Tabellen enthalten möglicherweise detailliertere und beschreibendere HTML-Tags, während andere eine einfachere und weniger beschreibende Syntax verwenden.
HTML-Tabellen mit Node.js und cheerio scrapen
Willkommen zum spannenden Teil! Wir haben die Struktur und den Zweck von HTML-Tabellen kennengelernt, und nun ist es an der Zeit, dieses Wissen in die Praxis umzusetzen. Unser Ziel für dieses Tutorial ist die Tabelle der meistverkauften Künstler aller Zeiten, die auf https://chartmasters.org/best-selling-artists-of-all-time/ zu finden ist. Wir beginnen damit, unsere Arbeitsumgebung einzurichten und die erforderlichen Bibliotheken zu installieren. Anschließend erkunden wir unsere Zielwebsite und entwickeln einige Selektoren, um die in der Tabelle enthaltenen Daten zu extrahieren. Danach schreiben wir den Code, um die Daten tatsächlich zu scrapen, und schließlich exportieren wir sie in verschiedene Formate wie CSV und JSON.
Einrichten der Arbeitsumgebung
Okay, lassen Sie uns mit unserem brandneuen Projekt beginnen! Bevor Sie loslegen, stellen Sie sicher, dass Sie Node.js installiert haben. Sie können es unter https://nodejs.org/en/ herunterladen.
Öffne nun deinen bevorzugten Code-Editor, öffne dein Projektverzeichnis und führe (im Terminal) folgenden Befehl aus:
npm init -y
Dadurch wird ein neues Projekt initialisiert und eine Standarddatei „package.json“ erstellt.
{
"name": "html_table_scraper", // the name of your project folder
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Der Einfachheit halber werden wir unsere Module mit „require“ importieren. Wenn du Module jedoch mit der Anweisung „import“ importieren möchtest, füge Folgendes zu deiner Datei „package.json“ hinzu:
"type": "module",
// this will enable you to use the import statement
// ex: import * as cheerio from 'cheerio';
Die Option „main“: „index.js“ gibt den Namen der Datei an, die den Einstiegspunkt unseres Programms darstellt. Nachdem dies geklärt ist, kannst du nun eine leere index.js-Datei erstellen.
Wir werden die cheerio-Bibliothek verwenden, um den HTML-Code unserer Zielwebsite zu parsen. Du kannst sie mit folgendem Befehl installieren:
npm install cheerio
Öffne nun die Datei index.js und binde sie als Modul ein:
const cheerio = require('cheerio');
Die grundlegende Arbeitsumgebung ist eingerichtet. Im nächsten Kapitel werden wir die Struktur der Tabelle „best-selling-artists-of-all-time“ untersuchen.
Testen der Zielseite mit DevTools
Durch die Untersuchung der Registerkarte „Elemente“ in den Entwicklertools können wir wertvolle Informationen über die Struktur der Tabelle gewinnen:
Die Tabelle ist im Format <thead>, <tbody> gespeichert.
Allen Tabellenelementen sind beschreibende IDs, Klassen und Rollen zugewiesen.
Im Kontext eines Browsers haben Sie direkten Zugriff auf den HTML-Code einer Webseite. Das bedeutet, dass Sie JavaScript-Funktionen wie getElementsByTagName oder querySelector verwenden können, um Daten aus dem HTML-Code zu extrahieren.
Vor diesem Hintergrund können wir die Entwickler-Tools-Konsole nutzen, um einige Selektoren zu testen.
Lassen Sie uns die Kopfzeilennamen mithilfe des Attributs role="columnheader" extrahieren
Extrahieren wir nun die Daten aus der ersten Zeile mithilfe der Attribute role="cell" und role="row":
Wie Sie sehen können:
Wir können „[role=columnheader]“ verwenden, um alle Kopfzeilenelemente auszuwählen.
Wir können „tbody [role=row]“ verwenden, um alle Zeilenelemente auszuwählen.
Für jede Zeile können wir „[role=cell]“ verwenden, um ihre Zellen auszuwählen.
Zu beachten ist, dass die PIC-Zelle ein Bild enthält und wir eine spezielle Regel schreiben sollten, um deren URL zu extrahieren.
Implementierung eines HTML-Tabellen-Scrapers
Nun ist es an der Zeit, die Dinge mithilfe von Node.js und cheerio etwas fortgeschrittener zu gestalten.
Um den HTML-Code einer Website in einem Node.js-Projekt abzurufen, musst du eine Fetch-Anfrage an die Website senden. Dies gibt den HTML-Code als String zurück, was bedeutet, dass du keine JavaScript-DOM-Funktionen zum Extrahieren von Daten verwenden kannst. Hier kommt cheerio ins Spiel. Cheerio ist eine Bibliothek, mit der du den HTML-String so parsen und bearbeiten kannst, als befändest du dich im Kontext eines Browsers. Das bedeutet, dass du vertraute CSS-Selektoren verwenden kannst, um Daten aus dem HTML zu extrahieren, genau wie du es in einem Browser tun würdest.
Es ist auch wichtig zu beachten, dass sich der von einer Fetch-Anfrage zurückgegebene HTML-Code von dem HTML-Code unterscheiden kann, den du im Browser siehst. Das liegt daran, dass der Browser JavaScript ausführt, das den angezeigten HTML-Code verändern kann. Bei einer Fetch-Anfrage erhältst du lediglich den rohen HTML-Code, ohne jegliche JavaScript-Änderungen.
Nur zu Testzwecken senden wir eine Fetch-Anfrage an unsere Zielwebsite und schreiben den resultierenden HTML-Code in eine lokale Datei:
//index.js
const fs = require('fs');
(async () => {
const response = await fetch('https://chartmasters.org/best-selling-artists-of-all-time/');
const raw_html = await response.text();
fs.writeFileSync('raw-best-selling-artists-of-all-time.html', raw_html);
})();
// it will write the raw html to raw-best-selling-artists-of-all-time.html
// try it with other websites: https://randomwordgenerator.com/
Sie können dies mit folgendem Befehl ausführen:
node index.js
Und Sie erhalten:
Die Tabellenstruktur bleibt unverändert. Das bedeutet, dass die Selektoren, die wir im vorherigen Kapitel gefunden haben, weiterhin relevant sind.
Ok, fahren wir nun mit dem eigentlichen Code fort:
Nachdem du die Fetch-Anfrage an https://chartmasters.org/best-selling-artists-of-all-time/ gestellt hast, musst du den Roh-HTML-Code in cheerio laden:
const cheerio = require('cheerio');
(async () => {
const response = await fetch('https://chartmasters.org/best-selling-artists-of-all-time/');
const raw_html = await response.text();
const $ = cheerio.load(raw_html);
})();
Nachdem cheerio geladen ist, schauen wir uns an, wie wir die Kopfzeilen extrahieren können:
const headers = $("[role=columnheader]")
const header_names = []
headers.each((index, el) => {
header_names.push($(el).text())
})
//header_names
[
'#',
'PIC',
'Artist',
'Total CSPC',
'Studio Albums Sales',
'Other LPs Sales',
'Physical Singles Sales',
'Digital Singles Sales',
'Sales Update',
'Streams EAS (Update)'
]
Und die erste Zeile:
const first_row = $("tbody [role=row]")[0]
const first_row_cells = $(first_row).find('[role=cell]')
const first_row_data = []
first_row_cells.each((index, f_r_c) => {
const image = $(f_r_c).find('img').attr('src')
if(image) {
first_row_data.push(image)
}
else {
first_row_data.push($(f_r_c).text())
}
})
//first_row_data
[
'1',
'https://i.scdn.co/image/ab6761610000f178e9348cc01ff5d55971b22433',
'The Beatles',
'421,300,000',
'160,650,000',
'203,392,000',
'116,080,000',
'35,230,000',
'03/01/17',
'17,150,000 (01/03/23)'
]
Erinnerst du dich daran, als wir die HTML-Tabelle mit JavaScript in der Konsole der Browser-Entwicklertools ausgelesen haben? An dieser Stelle haben wir dieselbe Funktionalität nachgebildet, die wir dort implementiert haben, allerdings im Kontext des Node.js-Projekts. Du kannst dir das letzte Kapitel noch einmal ansehen und die vielen Ähnlichkeiten zwischen den beiden Implementierungen feststellen.
Schreiben wir nun den Code um, um alle Zeilen zu scrapen:
const rows = $("tbody [role=row]")
const rows_data = []
rows.each((index, row) => {
const row_cell_data = []
const cells = $(row).find('[role=cell]')
cells.each((index, cell) => {
const image = $(cell).find('img').attr('src')
if(image) {
row_cell_data.push(image)
}
else {
row_cell_data.push($(cell).text())
}
})
rows_data.push(row_cell_data)
})
//rows_data
[
[
'1',
'https://i.scdn.co/image/ab6761610000f178e9348cc01ff5d55971b22433',
'The Beatles',
'421,300,000',
'160,650,000',
'203,392,000',
'116,080,000',
'35,230,000',
'03/01/17',
'17,150,000 (01/03/23)'
],
[
'2',
'https://i.scdn.co/image/ab6761610000f178a2a0b9e3448c1e702de9dc90',
'Michael Jackson',
'336,084,000',
'182,600,000',
'101,997,000',
'79,350,000',
'79,930,000',
'09/27/17',
'15,692,000 (01/06/23)'
],
...
]
Nachdem wir nun die Daten erhalten haben, schauen wir uns an, wie wir sie exportieren können.
Exportieren der Daten
Nachdem Sie die Daten, die Sie auslesen möchten, erfolgreich erhalten haben, ist es wichtig zu überlegen, wie Sie die Informationen speichern möchten. Die beliebtesten Optionen sind .json und .csv. Wählen Sie das Format, das Ihren spezifischen Bedürfnissen und Anforderungen am besten entspricht.
Exportieren der Daten nach JSON
Wenn Sie die Daten in das .json-Format exportieren möchten, sollten Sie die Daten zunächst in einem JavaScript-Objekt bündeln, das dem .json-Format entspricht.
Wir haben ein Array mit Kopfzeilennamen (header_names) und ein weiteres Array (rows_data, ein Array von Arrays), das die Zeilendaten enthält. Das .json-Format speichert Informationen in Schlüssel-Wert-Paaren. Wir müssen unsere Daten so bündeln, dass sie dieser Regel folgen:
[ // this is what we need to obtain
{
'#': '1',
PIC: 'https://i.scdn.co/image/ab6761610000f178e9348cc01ff5d55971b22433',
Artist: 'The Beatles',
'Total CSPC': '421,300,000',
'Studio Albums Sales': '160,650,000',
'Other LPs Sales': '203,392,000',
'Physical Singles Sales': '116,080,000',
'Digital Singles Sales': '35,230,000',
'Sales Update': '03/01/17',
'Streams EAS (Update)': '17,150,000 (01/03/23)'
},
{
'#': '2',
PIC: 'https://i.scdn.co/image/ab6761610000f178a2a0b9e3448c1e702de9dc90',
Artist: 'Michael Jackson',
'Total CSPC': '336,084,000',
'Studio Albums Sales': '182,600,000',
'Other LPs Sales': '101,997,000',
'Physical Singles Sales': '79,350,000',
'Digital Singles Sales': '79,930,000',
'Sales Update': '09/27/17',
'Streams EAS (Update)': '15,692,000 (01/06/23)'
}
...
]
So können Sie dies erreichen:
// go through each row
const table_data = rows_data.map(row => {
// create a new object
const obj = {};
// forEach element in header_names
header_names.forEach((header_name, i) => {
// add a key-value pair to the object where the key is the current header name and the value is the value at the same index in the row
obj[header_name] = row[i];
});
// return the object
return obj;
});
Nun können Sie die Funktion JSON.stringify() verwenden, um das JavaScript-Objekt in eine JSON-Zeichenkette zu konvertieren und diese anschließend in eine Datei zu schreiben.
const fs = require('fs');
const table_data_json_string = JSON.stringify(table_data, null, 2)
fs.writeFile('table_data.json', table_data_json_string, (err) => {
if (err) throw err;
console.log('The file has been saved as table_data.json!');
})Exportieren der Daten als CSV
Das .csv-Format steht für „comma separated values“ (durch Kommas getrennte Werte). Wenn Sie Ihre Tabelle als .csv speichern möchten, müssen Sie sie in einem Format schreiben, das in etwa so aussieht:
id,name,age // the table headers followed by the rows
1,Alice,20
2,Bob,25
3,Charlie,30
Unsere Tabellendaten bestehen aus einem Array mit Spaltennamen (header_names) und einem weiteren Array (rows_data, ein Array von Arrays), das die Zeilendaten enthält. So kannst du diese Daten in eine CSV-Datei schreiben:
let csv_string = header_names.join(',') + '\n'; // add the headers
// forEach row in rows_data
rows_data.forEach(row => {
// add the row to the CSV string
csv_string += row.join(',') + '\n';
});
// write the string to a file
fs.writeFile('table_data.csv', csv_string, (err) => {
if (err) throw err;
console.log('The file has been saved as table_data.csv!');
});Vermeiden Sie Blockierungen
Ist es Ihnen schon einmal passiert, dass Sie versucht haben, eine Website zu scrapen, und dann festgestellt haben, dass die Seite, von der Sie Informationen extrahieren wollten, nicht vollständig geladen wurde? Das kann frustrierend sein, besonders wenn Sie wissen, dass die Website JavaScript verwendet, um ihre Inhalte zu generieren. Wir haben nicht die Möglichkeit, JavaScript wie ein normaler Browser auszuführen, was zu unvollständigen Daten führen kann oder sogar dazu, dass Sie von der Website gesperrt werden, weil Sie in kurzer Zeit zu viele Anfragen gestellt haben.
Eine Lösung für dieses Problem ist WebScrapingApi. Mit unserem Dienst können Sie einfach Anfragen an unsere API senden, und diese übernimmt alle komplexen Aufgaben für Sie. Sie führt JavaScript aus, wechselt Proxys und bewältigt sogar CAPTCHAs.
So können Sie eine einfache Fetch-Anfrage an eine <target_url> stellen und die Antwort in eine Datei schreiben:
const fs = require('fs');
(async () => {
const result = await fetch('https://api.webscrapingapi.com/v1?' + new URLSearchParams({
api_key: '<api_key>',
url: '<target_url>',
render_js: 1,
proxy_type: 'residential',
}))
const html = await result.text();
fs.writeFileSync('wsa_test.html', html);
})();
Sie können einen kostenlosen API_KEY erhalten, indem Sie ein neues Konto unter https://www.webscrapingapi.com/ erstellen
Durch die Angabe des Parameters render_js=1 aktivieren Sie die Funktion von WebScrapingAPI, über einen Headless-Browser auf die Ziel-Webseite zuzugreifen. Dadurch können JavaScript-Seitenelemente gerendert werden, bevor das endgültige Scraping-Ergebnis an Sie zurückgesendet wird.
Unter https://docs.webscrapingapi.com/webscrapingapi/advanced-api-features/proxies kannst du die Funktionen unserer rotierenden Proxys entdecken.
Fazit
In diesem Artikel haben wir die Leistungsfähigkeit des Web-Scrapings von HTML-Tabellen mit JavaScript kennengelernt und erfahren, wie es uns helfen kann, wertvolle Daten aus Websites zu extrahieren. Wir haben die Struktur von HTML-Tabellen untersucht und gelernt, wie man die cheerio-Bibliothek in Kombination mit Node.js nutzt, um Daten daraus einfach zu scrapen. Außerdem haben wir uns verschiedene Möglichkeiten zum Exportieren der Daten angesehen, darunter die Formate CSV und JSON. Wenn Sie die in diesem Artikel beschriebenen Schritte befolgen, sollten Sie nun über eine solide Grundlage für das Scraping von HTML-Tabellen auf jeder beliebigen Website verfügen.
Egal, ob Sie ein erfahrener Profi sind oder gerade erst mit Ihrem ersten Scraping-Projekt beginnen – WebScrapingAPI steht Ihnen bei jedem Schritt zur Seite. Unser Team beantwortet gerne alle Ihre Fragen und berät Sie bei Ihren Projekten. Wenn Sie also einmal nicht weiterkommen oder einfach nur Hilfe benötigen, zögern Sie nicht, uns zu kontaktieren.




