Einrichtung der Umgebung
Bevor wir beginnen, stellen wir sicher, dass wir über die erforderlichen Tools verfügen.
Laden Sie zunächst Node.js von der offiziellen Website herunter und installieren Sie es, wobei Sie darauf achten sollten, die Long-Term-Support-Version (LTS) zu verwenden. Dadurch wird automatisch auch der Node Package Manager (NPM) installiert, den wir zur Installation weiterer Abhängigkeiten nutzen werden.
Für dieses Tutorial verwenden wir Visual Studio Code als unsere integrierte Entwicklungsumgebung (IDE), aber Sie können jede andere IDE Ihrer Wahl verwenden. Erstellen Sie einen neuen Ordner für Ihr Projekt, öffnen Sie das Terminal und führen Sie den folgenden Befehl aus, um ein neues Node.js-Projekt einzurichten:
npm init -y
Dadurch wird eine Datei namens package.json in Ihrem Projektverzeichnis erstellt, in der Informationen zu Ihrem Projekt und dessen Abhängigkeiten gespeichert werden.
Als Nächstes müssen wir TypeScript und die Typdefinitionen für Node.js installieren. TypeScript bietet optionale statische Typisierung, die hilft, Fehler im Code zu vermeiden. Führen Sie dazu im Terminal folgenden Befehl aus:
npm install typescript @types/node --save-dev
Sie können die Installation überprüfen, indem Sie Folgendes ausführen:
npx tsc --version
TypeScript verwendet eine Konfigurationsdatei namens tsconfig.json, um Compiler-Optionen und andere Einstellungen zu speichern. Um diese Datei in Ihrem Projekt zu erstellen, führen Sie den folgenden Befehl aus:
npx tsc -init
Stellen Sie sicher, dass der Wert für „outDir“ auf „dist“ gesetzt ist. Auf diese Weise trennen wir die TypeScript-Dateien von den kompilierten Dateien. Weitere Informationen zu dieser Datei und ihren Eigenschaften finden Sie in der offiziellen TypeScript-Dokumentation.
Erstellen Sie nun in Ihrem Projekt ein Verzeichnis „src“ und eine neue Datei „index.ts“. Hier werden wir den Scraping-Code ablegen. Um TypeScript-Code auszuführen, müssen Sie ihn zunächst kompilieren. Damit wir diesen zusätzlichen Schritt nicht vergessen, können wir einen benutzerdefinierten Befehl verwenden.
Öffne die Datei „package.json“ und bearbeite den Abschnitt „scripts“ wie folgt:
"scripts": {
"test": "npx tsc && node dist/index.js"
}
Auf diese Weise müssen Sie beim Ausführen des Skripts lediglich „npm run test“ in Ihr Terminal eingeben.
Um schließlich die Daten von der Website zu scrapen, verwenden wir Puppeteer, eine Headless-Browser-Bibliothek für Node.js, mit der Sie einen Webbrowser steuern und programmgesteuert mit Websites interagieren können. Um sie zu installieren, führen Sie diesen Befehl im Terminal aus:
npm install puppeteer
Dies ist sehr empfehlenswert, wenn du die Vollständigkeit deiner Daten sicherstellen möchtest, da viele Websites heutzutage dynamisch generierte Inhalte enthalten. Wenn du neugierig bist, kannst du dir vor dem Fortfahren die Puppeteer-Dokumentation ansehen, um einen umfassenden Überblick über die Möglichkeiten zu erhalten.
Speicherort der Daten
Nachdem Sie nun Ihre Umgebung eingerichtet haben, können wir uns mit der Datenextraktion befassen. Für diesen Artikel habe ich mich entschieden, die Seite eines irischen Restaurants aus Dublin zu scrapen: https://www.yelp.ie/biz/the-boxty-house-dublin?osq=Restaurants.
Wir werden die folgenden Daten extrahieren:
- den Namen des Restaurants;
- die Bewertung des Restaurants;
- die Anzahl der Bewertungen des Restaurants;
- die Website des Unternehmens;
- die Telefonnummer des Unternehmens;
- die Anschriften des Restaurants.
All diese Informationen sind im folgenden Screenshot hervorgehoben:
Wenn Sie die Entwicklertools für jedes dieser Elemente öffnen, können Sie die CSS-Selektoren erkennen, die wir zum Auffinden der HTML-Elemente verwenden werden. Wenn Sie noch nicht so vertraut mit der Funktionsweise von CSS-Selektoren sind, können Sie gerne diesen Leitfaden für Anfänger zu Rate ziehen.
Extrahieren der Daten
Bevor wir unser Skript schreiben, überprüfen wir, ob die Installation von Puppeteer erfolgreich war:
import puppeteer from 'puppeteer';
async function scrapeYelpData(yelp_url: string): Promise<void> {
// Launch Puppeteer
const browser = await puppeteer.launch({
headless: false,
args: ['--start-maximized'],
defaultViewport: null
})
// Create a new page
const page = await browser.newPage()
// Navigate to the target URL
await page.goto(yelp_url)
// Close the browser
await browser.close()
}
scrapeYelpData("https://www.yelp.ie/biz/the-boxty-house-dublin?osq=Restaurants")
Hier öffnen wir ein Browserfenster, erstellen eine neue Seite, navigieren zu unserer Ziel-URL und schließen den Browser. Der Einfachheit und zur visuellen Fehlerbehebung halber öffne ich das Browserfenster im maximierten Modus im Nicht-Headless-Modus.
Schauen wir uns nun die Struktur der Website an:
Es scheint, dass Yelp eine etwas komplizierte Seitenstruktur aufweist, da die Klassennamen zufällig generiert werden und nur sehr wenige Elemente eindeutige Attributwerte haben.
Aber keine Sorge, wir können bei der Lösung kreativ werden. Um den Namen des Restaurants zu ermitteln, zielen wir zunächst auf das einzige „h1“-Element auf der Seite ab.
// Extract restaurant name
const restaurant_name = await page.evaluate(() => {
const name = document.querySelector('h1')
return name ? name.textContent : ''
})
console.log(restaurant_name)
Um nun die Restaurantbewertung zu erhalten, kannst du feststellen, dass neben den Sternsymbolen der explizite Wert im Attribut „aria-label“ vorhanden ist. Also zielen wir auf das „div“-Element ab, dessen „aria-label“-Attribut mit der Zeichenfolge „star rating“ endet.
// Extract restaurant rating
const restaurant_rating = await page.evaluate(() => {
const rating = document.querySelector('div[aria-label$="star rating"]')
return rating ? rating.getAttribute('aria-label') : ''
})
console.log(restaurant_rating)
Und schließlich (für diesen speziellen HTML-Abschnitt) sehen wir, dass wir die Anzahl der Bewertungen ganz einfach ermitteln können, indem wir das hervorgehobene Anker-Element ansprechen.
// Extract restaurant reviews
const restaurant_reviews = await page.evaluate(() => {
const reviews = document.querySelector('a[href="#reviews"]')
return reviews ? reviews.textContent : ''
})
console.log(restaurant_reviews)
Kinderleicht. Werfen wir einen Blick auf das Widget mit den Unternehmensinformationen:
Leider können wir uns in dieser Situation nicht auf CSS-Selektoren verlassen. Glücklicherweise können wir eine andere Methode nutzen, um die HTML-Elemente zu finden: XPath. Wenn du noch nicht so vertraut mit der Funktionsweise von CSS-Selektoren bist, schau dir gerne diesen Leitfaden für Anfänger an.
Um die Website des Restaurants zu extrahieren, wenden wir folgende Logik an:
Suchen Sie das „p“-Element, dessen Textinhalt „Business website“ lautet;
Suchen Sie das folgende Geschwisterelement
Suchen Sie das Anker-Element und dessen „href“-Attribut.
// Extract restaurant website
const restaurant_website_element = await page.$x("//p[contains(text(), 'Business website')]/following-sibling::p/a/@href")
const restaurant_website = await page.evaluate(
element => element.nodeValue,
restaurant_website_element[0]
)
console.log(restaurant_website)
Für die Telefonnummer und die Adresse können wir nun genau derselben Logik folgen, mit zwei Ausnahmen:
- Bei der Telefonnummer stoppen wir das nachfolgende Geschwisterelement und extrahieren dessen „textContent“-Eigenschaft;
- Für die Adresse zielen wir auf das nachfolgende Geschwisterelement des übergeordneten Elements ab.
// Extract restaurant phone number
const restaurant_phone_element = await page.$x("//p[contains(text(), 'Phone number')]/following-sibling::p")
const restaurant_phone = await page.evaluate(
element => element.textContent,
restaurant_phone_element[0]
)
console.log(restaurant_phone)
// Extract restaurant address
const restaurant_address_element = await page.$x("//a[contains(text(), 'Get Directions')]/parent::p/following-sibling::p")
const restaurant_address = await page.evaluate(
element => element.textContent,
restaurant_address_element[0]
)
console.log(restaurant_address)
Das Endergebnis sollte wie folgt aussehen:
The Boxty House
4.5 star rating
948 reviews
/biz_redir?url=http%3A%2F%2Fwww.boxtyhouse.ie%2F&cachebuster=1673542348&website_link_type=website&src_bizid=EoMjdtjMgm3sTv7dwmfHsg&s=16fbda8bbdc467c9f3896a2dcab12f2387c27793c70f0b739f349828e3eeecc3
(01) 677 2762
20-21 Temple Bar Dublin 2Umgehung der Bot-Erkennung
Auch wenn das Scraping von Yelp auf den ersten Blick einfach erscheint, kann der Prozess mit zunehmender Projektgröße komplexer und anspruchsvoller werden. Die Website setzt verschiedene Techniken ein, um automatisierten Traffic zu erkennen und zu verhindern, sodass Ihr skalierter Scraper zunehmend blockiert wird.
Yelp sammelt zahlreiche Browserdaten, um einen eindeutigen Fingerabdruck zu generieren und Ihnen zuzuordnen. Dazu gehören unter anderem:
- Eigenschaften des Navigator-Objekts (deviceMemory, hardwareConcurrency, platform, userAgent, webdriver usw.)
- Zeit- und Leistungsprüfungen
- Service Worker
- Prüfungen der Bildschirmabmessungen
- und vieles mehr
Eine Möglichkeit, diese Herausforderungen zu bewältigen und weiterhin in großem Umfang zu scrapen, ist die Verwendung einer Scraping-API. Solche Dienste bieten eine einfache und zuverlässige Möglichkeit, auf Daten von Websites wie yelp.com zuzugreifen, ohne dass Sie einen eigenen Scraper erstellen und warten müssen.
WebScrapingAPI ist ein Beispiel für ein solches Produkt. Sein Proxy-Rotationsmechanismus umgeht CAPTCHAs vollständig, und seine erweiterte Wissensdatenbank ermöglicht es, die Browserdaten zu randomisieren, sodass sie wie von einem echten Nutzer stammen.
Die Einrichtung ist schnell und einfach. Sie müssen lediglich ein Konto registrieren, um Ihren API-Schlüssel zu erhalten. Dieser ist über Ihr Dashboard zugänglich und dient zur Authentifizierung der von Ihnen gesendeten Anfragen.
Da Sie Ihre Node.js-Umgebung bereits eingerichtet haben, können wir das entsprechende SDK nutzen. Führen Sie den folgenden Befehl aus, um es zu Ihren Projektabhängigkeiten hinzuzufügen:
npm install webscrapingapi
Jetzt müssen wir nur noch eine GET-Anfrage senden, um das HTML-Dokument der Website zu erhalten. Beachte, dass dies nicht die einzige Möglichkeit ist, auf die API zuzugreifen.
import webScrapingApiClient from 'webscrapingapi';
const client = new webScrapingApiClient("YOUR_API_KEY");
async function exampleUsage() {
const api_params = {
'render_js': 1,
'proxy_type': 'residential',
}
const URL = "https://www.yelp.ie/biz/the-boxty-house-dublin?osq=Restaurants"
const response = await client.get(URL, api_params)
if (response.success) {
console.log(response.response.data)
} else {
console.log(response.error.response.data)
}
}
exampleUsage();
Durch Aktivieren des Parameters „render_js“ senden wir die Anfrage über einen Headless-Browser, genau wie du es zuvor in diesem Tutorial getan hast.
Nachdem Sie das HTML-Dokument erhalten haben, können Sie eine andere Bibliothek wie Cheerio verwenden, um die gewünschten Daten zu extrahieren. Noch nie davon gehört? Schauen Sie sich diesen Leitfaden an, der Ihnen den Einstieg erleichtert!
Fazit
Dieser Artikel hat Ihnen eine umfassende Anleitung vorgestellt, wie Sie mit TypeScript und Puppeteer Web-Scraping auf Yelp durchführen können. Wir haben den Prozess der Einrichtung der Umgebung, das Auffinden und Extrahieren von Daten sowie die Gründe dafür durchgesprochen, warum die Verwendung eines professionellen Scrapers eine bessere Lösung ist als die Erstellung eines eigenen.
Die von Yelp gescrapten Daten können für verschiedene Zwecke genutzt werden, beispielsweise zur Erkennung von Markttrends, zur Analyse der Kundenstimmung, zur Beobachtung von Wettbewerbern, zur Erstellung gezielter Marketingkampagnen und vieles mehr.
Insgesamt kann das Web-Scraping von Yelp.com ein wertvolles Hilfsmittel für alle sein, die sich einen Wettbewerbsvorteil auf ihrem lokalen Markt verschaffen möchten, und dieser Leitfaden bietet einen hervorragenden Ausgangspunkt dafür.




