Heim BlogWeb-Scraping So scrapen Sie dynamische Inhalte auf Websites mit über 1 Million URLs

So scrapen Sie dynamische Inhalte auf Websites mit über 1 Million URLs

von Kadek

TL;DR: Wie erhält man dynamische Daten?

So können Sie dynamische Inhalte mit ScraperAPI und Selenium scrapen. Diese Ansätze verarbeiten JavaScript, unendliches Scrollen und komplexe Benutzerinteraktionen und stellen sicher, dass Sie alle Daten erhalten, die Sie benötigen.

Python und ScraperAPI

import requests
from bs4 import BeautifulSoup

API_KEY = 'your_scraperapi_key'
url = 'https://www.booking.com/searchresults.html?ss=New+York'

payload = {
    'url': url,
}

headers = {
    'x-sapi-api_key': API_KEY,
    'x-sapi-render': 'true',
    'x-sapi-instruction_set': '({"type": "loop", "for": 5, "instructions": ({"type": "scroll", "direction": "y", "value": "bottom" }, { "type": "wait", "value": 5 }) })'
}

response = requests.get('https://api.scraperapi.com', params=payload, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
listings = soup.find_all('div', attrs={'data-testid': 'property-card'})

print(f"Found {len(listings)} hotel listings on Booking.com")

Python und Selenium

from seleniumwire import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
from bs4 import BeautifulSoup

API_KEY = 'your_scraperapi_key'

proxy_options = {
    'proxy': {
        'http': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',        
        'https': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
        'no_proxy': 'localhost,127.0.0.1'
    }
}

driver = webdriver.Chrome(seleniumwire_options=proxy_options)
url = 'https://www.booking.com/searchresults.html?ss=New+York'
driver.get(url)

last_height = driver.execute_script("return document.body.scrollHeight")
while True:
    driver.find_element(By.TAG_NAME, 'body').send_keys(Keys.END)
    time.sleep(10)
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
listings = soup.find_all('div', attrs={'data-testid': 'property-card'})

print(f"Found {len(listings)} hotel listings on Booking.com")

Lesen Sie weiter, um mehr über diese Methoden und den jeweiligen Einsatzzweck für Ihre Web-Scraping-Projekte zu erfahren.

Häufige Fehler beim Scraping dynamischer Inhalte und wie man sie vermeidet

Das Scraping dynamischer Inhalte von Websites kann eine Herausforderung sein. Wenn Sie jedoch häufige Fallstricke verstehen und vermeiden, kann der Vorgang viel reibungsloser ablaufen. Im Folgenden finden Sie vier kritische Fallstricke, auf die Sie achten sollten:

1. AJAX-Anfragen ignorieren

Die Herausforderung:
Viele Websites verwenden AJAX-Anfragen (Asynchronous JavaScript and XML), um Inhalte asynchron zu laden, ohne die gesamte Seite zu aktualisieren. Das bedeutet, dass die benötigten Daten möglicherweise trotzdem separat über AJAX-Aufrufe abgerufen werden, selbst wenn das Haupt-HTML vollständig geladen ist. Wenn Ihr Scraper diese Anfragen nicht berücksichtigt, könnten Ihnen wichtige Daten entgehen.

So vermeiden Sie es:
Untersuchen Sie die Netzwerkaktivität in den Entwicklertools Ihres Browsers, um AJAX-Anfragen zu identifizieren, die beim Erscheinen neuer Inhalte auftreten. Sobald diese Anfragen identifiziert sind, replizieren Sie sie direkt in Ihrem Scraper, um sicherzustellen, dass Sie alle dynamisch geladenen Daten erfassen.

import requests

# Example of handling an AJAX request
ajax_url = 'https://www.example.com/ajax_endpoint'
response = requests.get(ajax_url)
data = response.json()  # Assuming the response is in JSON format
print(data)

Bewährte Methode:
Achten Sie beim Scrapen von Websites immer auf AJAX-Anfragen. Wenn der benötigte Inhalt über AJAX geladen wird, replizieren Sie diese Anfragen in Ihrem Scraper, um die Daten direkt abzurufen.

Ressource: Wir haben diese Strategie verwendet, um öffentliche Stellenangebote von LinkedIn zu scrapen.

2. Fehler bei der Seitennummerierung

Die Herausforderung:
Viele Websites, insbesondere E-Commerce-Sites oder Verzeichnisse, verteilen ihre Inhalte auf mehrere Seiten. Wenn Ihr Scraper nur Daten von der ersten Seite sammelt, könnten Ihnen erhebliche Datenmengen entgehen.

So vermeiden Sie es:
Implementieren Sie in Ihrem Scraper eine Logik zur Handhabung der Seitennummerierung, indem Sie die Schaltfläche „Weiter“ erkennen und befolgen oder URLs für nachfolgende Seiten erstellen. Dadurch wird sichergestellt, dass Ihr Scraper Daten von allen Seiten sammelt, nicht nur von der ersten.

import requests

for page in range(1, 11):  # Adjust the range based on the number of pages
    url = f'https://www.example.com/search?page={page}'
    response = requests.get(url)
    # Process each page's results here
    print(f'Page {page} data: {response.text}')

Bewährte Methode:
Beziehen Sie in Ihre Scraping-Logik immer die Seitennummerierung ein, um eine umfassende Datenerfassung auf allen Seiten sicherzustellen.

Ressource: Lesen Sie unseren Leitfaden zum Umgang mit der Paginierung für Web Scraping.

3. Handhabung der JavaScript-Ausführung und komplexer Interaktionen mit ScraperAPI

Die Herausforderung:
Viele Websites verwenden heute JavaScript, um Inhalte dynamisch zu laden und komplexe Interaktionen wie das Senden von Formularen, endloses Scrollen und Klicken auf Schaltflächen zu verarbeiten. Wenn Ihr Scraper nur das ursprüngliche HTML abruft, ohne diese Skripte oder Interaktionen auszuführen, könnten Ihnen wichtige Daten entgehen.

So vermeiden Sie es:
Die Rendering-Funktion von ScraperAPI ermöglicht Ihnen in Kombination mit dem leistungsstarken Render Instruction Set die Verarbeitung von JavaScript und die Automatisierung von Seiteninteraktionen. Das bedeutet, dass Sie Benutzeraktionen wie die Eingabe eines Suchbegriffs, das Klicken auf eine Schaltfläche oder das Scrollen durch Inhalte simulieren können – und das alles innerhalb Ihres Scraping-Workflows.

So verwenden Sie den Render-Befehlssatz

Der Render-Befehlssatz ist ein JSON-Objekt, das Sie als Teil der Anforderungsheader an ScraperAPI senden. Dieser Befehlssatz teilt dem Browser genau mit, welche Aktionen während der Seitendarstellung ausgeführt werden sollen – z. B. das Ausfüllen eines Formulars, das Klicken auf eine Schaltfläche oder das Warten auf das Laden bestimmter Inhalte. Diese Anweisungen ermöglichen die Automatisierung komplexer Benutzerinteraktionen auf dynamischen Webseiten, ohne dass Sie auf Ihrem Computer Headless-Browser verwenden müssen.

Beispiel: Scraping mit und ohne Rendering und Interaktionsanweisungen

Sehen wir uns ein Beispiel für die Verwendung von ScraperAPI zur Automatisierung einer Suche auf Wikipedia an. Ziel ist es, die Eingabe des Suchbegriffs „Cowboystiefel“ in die Suchleiste, das Klicken auf die Suchschaltfläche und das anschließende Warten auf das Laden der Ergebnisse zu simulieren.

Notiz: Um diese Snippets auszuführen, erstellen Sie ein kostenloses ScraperAPI-Konto und ersetzen Sie 'YOUR_API_KEY' mit Ihrem API-Schlüssel.

Ohne Rendering und Anleitung:

import requests

url = 'https://api.scraperapi.com/'
headers = {
    'x-sapi-api_key': 'YOUR_API_KEY',
    'x-sapi-instruction_set': '({"type": "input", "selector": {"type": "css", "value": "#searchInput"}, "value": "cowboy boots"}, {"type": "click", "selector": {"type": "css", "value": "#search-form button(type=\\"submit\\\")"}}, {"type": "wait_for_selector", "selector": {"type": "css", "value": "#content"}})'
}
payload = {
    'url': 'https://www.wikipedia.org'
}
response = requests.get(url, params=payload, headers=headers)
print(response.text)

In diesem Code senden wir eine Anfrage an ScraperAPI, um die Wikipedia-Homepage zu scrapen. Die Header enthalten den API-Schlüssel und den Render-Befehlssatz. Beachten Sie jedoch, dass die x-sapi-render Header fehlt.

Während die Anweisungen zum Eingeben von „Cowboystiefeln“ und Klicken auf die Suchschaltfläche gesendet werden, wird das zum Rendern der Suchergebnisse erforderliche JavaScript nicht ausgeführt. Das erwartete Ergebnis ist, dass die Suchaktion nicht abgeschlossen wird und das zurückgegebene HTML wahrscheinlich nicht die Suchergebnisse enthält.

Mit aktiviertem Rendering und Anweisungen:

import requests

url = 'https://api.scraperapi.com/'
headers = {
    'x-sapi-api_key': 'YOUR_API_KEY',
    'x-sapi-render': 'true',
    'x-sapi-instruction_set': '({"type": "input", "selector": {"type": "css", "value": "#searchInput"}, "value": "cowboy boots"}, {"type": "click", "selector": {"type": "css", "value": "#search-form button(type=\\"submit\\\")"}}, {"type": "wait_for_selector", "selector": {"type": "css", "value": "#content"}})'
}
payload = {
    'url': 'https://www.wikipedia.org'
}
response = requests.get(url, params=payload, headers=headers)
print(response.text)

Wir haben hinzugefügt: x-sapi-render: 'true' Header in dieser Version. Dies weist ScraperAPI an, das JavaScript auf der Seite vollständig darzustellen und sicherzustellen, dass die Sucheingabe, die Klickaktion und das anschließende Laden der Suchergebnisse alle so ausgeführt werden, als würde ein Benutzer direkt mit dem Browser interagieren.

Das erwartete Ergebnis ist, dass das zurückgegebene HTML die Suchergebnisse für „Cowboystiefel“ enthält, was die erfolgreiche Ausführung des JavaScript widerspiegelt.

Bewährte Methode:
Wenn Sie Websites scrapen, die JavaScript zum Laden von Inhalten benötigen oder Benutzerinteraktionen erfordern, schließen Sie immer das x-sapi-render: 'true' Header. Dadurch wird sichergestellt, dass sowohl die JavaScript-Ausführung als auch die Interaktionen, die Sie im Render-Befehlssatz definieren, effektiv ausgeführt werden, sodass Sie alle relevanten Daten erfassen können.

Weitere Informationen zur Verwendung des Render-Befehlssatzes und zusätzliche Beispiele finden Sie in der ScraperAPI-Dokumentation.

Dynamischen Inhalt mit ScraperAPI scrapen (Bester Ansatz)

In diesem Abschnitt zeige ich Ihnen, wie Sie mit ScraperAPI dynamische Hotelsuchergebnisse von Booking.com scrapen.

Booking.com ist ein perfektes Beispiel für eine Website, die Inhalte dynamisch lädt, wie Hotellisten, Preise und Verfügbarkeit. Ich werde Sie durch den Prozess führen und Ihnen zeigen, wie ScraperAPI diese Herausforderungen bewältigt, damit Sie alle Daten erfassen können, die Sie benötigen.

Schritt 1: Einrichten des Scraping-Projekts

Um mit dem Scraping von Hotelsuchergebnissen von Booking.com zu beginnen, müssen Sie Ihre Umgebung für die Verwendung von ScraperAPI mit Python einrichten.

  1. Registrieren Sie sich für ScraperAPI: Wenn Sie es noch nicht getan haben, melden Sie sich für ScraperAPI an und erhalten Sie Ihren kostenlosen API-Schlüssel.
  2. Installieren Sie die Requests-Bibliothek: Installieren Sie die requests Bibliothek in Python, um HTTP-Anfragen zu stellen. Führen Sie den folgenden Befehl aus:

Schritt 2: Importieren Sie die erforderlichen Bibliotheken

Zuerst müssen Sie die erforderlichen Bibliotheken importieren.

Öffnen Sie Ihr Python-Skript und fügen Sie die folgenden Zeilen hinzu:

import requests
from bs4 import BeautifulSoup

Diese Bibliotheken sind wichtig: requests hilft Ihnen beim Senden von HTTP-Anfragen, während BeautifulSoup ermöglicht Ihnen, Daten aus dem von ScraperAPI zurückgegebenen HTML-Inhalt zu analysieren und zu extrahieren.

Schritt 3: Richten Sie Ihren ScraperAPI-Schlüssel ein

Definieren Sie als Nächstes Ihren ScraperAPI-Schlüssel. Mit diesem Schlüssel können Sie auf die Funktionen von ScraperAPI zugreifen:

# Your ScraperAPI key
api_key = 'YOUR_API_KEY'

Stellen Sie sicher, dass Sie den Platzhalter durch Ihren tatsächlichen API-Schlüssel ersetzen. Dies ist für die Authentifizierung Ihrer Anfragen und die Verwendung der Dienste von ScraperAPI wichtig.

Schritt 4: Definieren Sie die URL für das Scraping

Geben Sie nun die URL der Seite an, die Sie scrapen möchten. Für dieses Tutorial scrapen wir Hotelsuchergebnisse von Booking.com:

# The URL for a Booking.com hotel search query (e.g., hotels in New York)
url = 'https://www.booking.com/searchresults.html?ss=New+York'

Sie können diese URL anpassen, um verschiedene Standorte anzusprechen, indem Sie den Abfrageparameter ändern (z. B. ss=New+York). Diese Flexibilität ermöglicht es Ihnen, Daten für verschiedene Städte zu scrapen.

Schritt 4: Richten Sie die Nutzlast für ScraperAPI ein

Als nächstes richten Sie die payload Wörterbuch, das an ScraperAPI gesendet wird – innerhalb dieser Nutzlast senden Sie die URL, die Sie scrapen möchten.

# Set up the parameters for ScraperAPI
payload = {
    'url': url
}

Schritt 5: Konfigurieren Sie die Header für die Anforderung

Konfigurieren Sie nun die Header für Ihre Anfrage an ScraperAPI:

  • Der x-sapi-api_key enthält Ihren ScraperAPI-Schlüssel zur Authentifizierung
  • Der x-sapi-render ermöglicht JS-Rendering
  • Der x-sapi-instruction_set Der Header enthält detaillierte Anweisungen und weist ScraperAPI an, die Seite fünfmal nach unten zu scrollen und dabei jedes Mal fünf Sekunden anzuhalten. Dadurch wird sichergestellt, dass der gesamte dynamisch geladene Inhalt erfasst wird.

Diese Header geben an, wie ScraperAPI Ihre Anfrage verarbeitet:

headers = {
    'x-sapi-api_key': api_key,
    'x-sapi-render': 'true',
    'x-sapi-instruction_set': '({"type": "loop", "for": 5, "instructions": ({"type": "scroll", "direction": "y", "value": "bottom" }, { "type": "wait", "value": 5 }) })'
}

Schritt 6: Stellen Sie die Anfrage an ScraperAPI

Wenn alles eingerichtet ist, ist es an der Zeit, die Anfrage an ScraperAPI zu senden. Nach dem Senden der Anfrage verarbeitet ScraperAPI die Seite gemäß Ihren Anweisungen und gibt das vollständig gerenderte HTML zurück, das zum Scrapen bereit ist.

# Make the request to ScraperAPI
response = requests.get('http://api.scraperapi.com', params=payload, headers=headers)

Schritt 7: Den HTML-Inhalt analysieren

Sobald Sie die Antwort haben, müssen Sie den HTML-Inhalt analysieren. Verwenden Sie dazu BeautifulSoup:

soup = BeautifulSoup(response.text, 'html.parser')

Dieser Schritt konvertiert den HTML-Text in ein BeautifulSoup-Objekt, sodass Sie einfach navigieren und die spezifischen Daten extrahieren können, die Sie interessieren, z. B. Hotellisten.

Schritt 8: Hoteleinträge extrahieren

Nachdem das HTML analysiert wurde, können Sie die Hotellisten extrahieren. So geht's:

listings = soup.find_all('div', attrs={'data-testid': 'property-card'})

Dies findet alle div Elemente mit dem Attribut data-testid eingestellt auf property-carddas Hoteleinträge auf Booking.com identifiziert. Hier können Sie Details wie Hotelnamen, Preise und Bewertungen extrahieren.

Schritt 9: Drucken Sie die Ergebnisse

Schauen wir uns zum Schluss an, was wir haben. Drucken Sie die Anzahl der gefundenen Hoteleinträge aus:

print(f"Found {len(listings)} hotel listings on Booking.com")

Dadurch wird die Gesamtzahl der Einträge ausgegeben. Dies bestätigt, dass Ihr Scraping-Vorgang funktioniert hat, und zeigt Ihnen, wie viele Hotels gefunden wurden.

Scraping dynamischer Webseiten mit Python und Selenium

Selenium bietet eine weitere leistungsstarke Methode, insbesondere wenn Sie eine präzise Kontrolle über Browseraktionen benötigen.

In diesem Abschnitt führe ich Sie durch das Scraping derselben Seite mit Hotelsuchergebnissen von Booking.com mithilfe von SeleniumWire. Selenium Wire erweitert die Fähigkeiten von Selenium, indem es Unterstützung für die Erfassung von Anfragen und Antworten hinzufügt und eine robuste Proxy-Integration bietet – und ist somit perfekt für die Verwendung mit ScraperAPI geeignet.

Schritt 1: Einrichten des Scraping-Projekts

Um mit Selenium zu beginnen, müssen Sie Ihre Umgebung einrichten:

  • Installieren Sie Selenium: Installieren Sie zunächst SeleniumWire mit pip:
pip install selenium-wire
  • Laden Sie einen WebDriver herunter: Selenium benötigt einen WebDriver zur Steuerung des Browsers. Wenn Sie Chrome verwenden, laden Sie ChromeDriver hier herunter.
  • Installieren Sie BeautifulSoup: Sie benötigen außerdem BeautifulSoup zum Parsen von HTML:
pip install beautifulsoup4

Schritt 2: Importieren Sie die erforderlichen Bibliotheken

Importieren Sie als Nächstes die für dieses Projekt erforderlichen Bibliotheken.

from seleniumwire import webdriver  # Use selenium-wire's webdriver for proxy support
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
from bs4 import BeautifulSoup

Schritt 3: ScraperAPI im Proxy-Modus einrichten

Integrieren Sie ScraperAPI mit Selenium als Proxy, um die Ausfallsicherheit Ihres Scrapers zu verbessern. Die Verwendung von ScaperAPI als Proxy hilft beim Rotieren von IP-Adressen und beim Verwalten von CAPTCHAs, wodurch Ihr Scraping effizienter und zuverlässiger wird.

API_KEY = 'YOUR_API_KEY' 

proxy_options = { 'proxy': { 'http': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001', 'https': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001', 'no_proxy': 'localhost,127.0.0.1' # Bypass the proxy for local addresses } } 

driver = webdriver.Chrome(seleniumwire_options=proxy_options)

Schritt 4: Navigieren Sie zur Booking.com-Seite

Nachdem der WebDriver eingerichtet ist, können Sie nun zur Suchergebnisseite von Booking.com navigieren:

url = 'https://www.booking.com/searchresults.html?ss=New+York'
driver.get(url)

Schritt 5: Dynamische Inhalte mit Selenium verarbeiten

Booking.com lädt zusätzlichen Inhalt, wenn Sie auf der Seite nach unten scrollen. Um alle Hoteleinträge zu erfassen, müssen Sie wiederholt zum Ende der Seite scrollen, bis kein neuer Inhalt mehr geladen wird.

# Scroll to the bottom of the page to load more content
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
    driver.find_element(By.TAG_NAME, 'body').send_keys(Keys.END)
    time.sleep(10)  # Wait for the page to load
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:  # Check if the bottom has been reached
        break
    last_height = new_height

Diese Schleife scrollt die Seite nach unten und wartet, bis zusätzlicher Inhalt geladen ist. Der Scrollvorgang wird fortgesetzt, bis kein neuer Inhalt mehr angezeigt wird. Dadurch wird sichergestellt, dass alle dynamischen Daten erfasst werden.

Schritt 6: Extrahieren und Analysieren des HTML-Inhalts

Sobald die Seite vollständig geladen ist und kein neuer Inhalt angezeigt wird, rufen Sie den HTML-Inhalt ab und analysieren Sie ihn mit BeautifulSoup:

html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')

listings = soup.find_all('div', attrs={'data-testid': 'property-card'})

Dadurch wird das komplette HTML der Seite erfasst und alle Hoteleinträge extrahiert.

Schritt 7: Drucken Sie die Ergebnisse

Drucken Sie abschließend die Anzahl der auf der Seite gefundenen Hoteleinträge aus:

print(f"Found {len(listings)} hotel listings on Booking.com")

Diese Ausgabe bestätigt, wie viele Hoteleinträge Ihr Skript erfolgreich durchsucht hat.

Warum Selenium Wire mit ScraperAPI verwenden?

Selenium Wire bietet gegenüber dem Standard-Selenium erweiterte Funktionen, insbesondere bei der Verarbeitung von Netzwerkanforderungen und Proxy-Konfigurationen. Durch die Kombination von Selenium Wire mit ScraperAPI erhalten Sie:

  • IP-Rotation und Anonymität: ScraperAPI verwaltet die IP-Rotation und verringert so das Risiko einer Blockierung.
  • CAPTCHA-Handhabung: ScraperAPI kann CAPTCHAs automatisch lösen und ermöglicht so unterbrechungsfreies Scraping.
  • Verbesserte Kontrolle: Selenium Wire bietet Ihnen eine detaillierte Kontrolle über Netzwerkanforderungen und erleichtert so die Fehlerbehebung und Optimierung Ihres Scrapings.

Zusammen bilden diese Tools ein robustes Setup für das Scraping selbst der dynamischsten und komplexesten Websites.

Related Posts

Hinterlasse einen Kommentar