Web Scraping mit HTTPX in Python

Entdecken Sie HTTPX, einen leistungsstarken Python-HTTP-Client für Web Scraping. Erfahren Sie mehr über Einrichtung, Funktionen, fortgeschrittene Techniken und den Vergleich mit Requests.
13 min read
web scraping with httpx and python blog image

In diesem Artikel erfahren Sie:

  • Was HTTP ist und welche Funktionen es bietet
  • Verwendung von HTTPX für Web Scraping in einem geführten Abschnitt
  • Erweiterte HTTPX-Funktionen für Web Scraping
  • Ein Vergleich zwischen HTTPX und HTTPX. Requests für automatisierte Requests

Dann legen wir mal los!

Was ist HTTPX?

HTTPX ist ein voll funktionsfähiger HTTP-Client für Python 3, der auf der Bibliothek retryablehttp aufbaut. Er ist darauf ausgelegt, auch bei einer hohen Anzahl von Threads zuverlässige Ergebnisse zu gewährleisten. HTTPX bietet sowohl synchrone als auch asynchrone APIs, mit Unterstützung für HTTP/1.1- und HTTP/2-Protokolle.

⚙️ Merkmale

  • Einfache und modulare Codebasis, die die Mitwirkung erleichtert.
  • Schnelle und vollständig konfigurierbare Flags zum Prüfen mehrerer Elemente.
  • Unterstützt verschiedene HTTP-basierte Prüfmethoden.
  • Intelligentes automatisches Fallback von HTTPS auf HTTP als Standard.
  • Akzeptiert Hosts, URLs und CIDR als Eingabe.
  • Unterstützt Proxys, benutzerdefinierte HTTP-Header, benutzerdefinierte Timeouts, Basisauthentifizierung und mehr.

👍 Vorteile

  • Verfügbar von der Kommandozeile mit httpx[cli].
  • Vollgepackt mit Funktionen, einschließlich Unterstützung für HTTP/2 und einer asynchronen API.
  • Dieses Projekt wird aktiv entwickelt …

👎 Nachteile

  • … mit häufigen Updates, die bei neuen Versionen zu grundlegenden Änderungen führen können.
  • Weniger beliebt als die Bibliothek requests

Scraping mit HTTPX: Schritt-für-Schritt-Anleitung

HTTPX ist ein HTTP-Client, d. h. er hilft Ihnen, den rohen HTML-Inhalt einer Seite abzurufen. Um dann Daten aus dem HTML zu parsen und zu extrahieren, benötigen Sie einen HTML-Parser wie BeautifulSoup.

Eigentlich ist HTTPX nicht irgendein HTTP-Client, sondern einer der besten Python-HTTP-Clients für Web Scraping.

Folgen Sie diesem Tutorial, um zu erfahren, wie man HTTPX für Web Scraping mit BeautifulSoup verwendet!

Warnung: Obwohl HTTPX nur in den frühen Phasen des Prozesses verwendet wird, führen wir Sie durch den vollständigen Arbeitsablauf. Wenn Sie an fortschrittlicheren HTTPX-Scraping-Techniken interessiert sind, können Sie zum nächsten Kapitel nach Schritt 3 übergehen.

Schritt Nr. 1: Projekteinrichtung

Stellen Sie sicher, dass Python 3+ auf Ihrem Computer installiert ist. Laden Sie es andernfalls von der offiziellen Website herunter und folgen Sie den Installationsanweisungen.

Verwenden Sie nun den folgenden Befehl, um ein Verzeichnis für Ihr HTTPX-Scraping-Projekt zu erstellen:

mkdir httpx-scraper

Navigieren Sie dorthin und initialisieren Sie eine virtuelle Umgebung darin:

cd httpx-scraper
python -m venv env

Öffnen Sie den Projektordner in Ihrer bevorzugten Python-IDE. Visual Studio Code mit der Python-Erweiterung oder PyCharm Community Edition reicht aus.

Erstellen Sie als Nächstes innerhalb des Projektordners eine scraper.py-Datei. Derzeit ist scraper.py ein leeres Python-Skript, aber es wird bald die Scraping-Logik enthalten.

Aktivieren Sie in Ihrem Terminal der IDE die virtuelle Umgebung. Führen Sie unter Linux oder macOS Folgendes aus:

./env/bin/activate

Entsprechend gilt für Windows:

env/Scripts/activate

Fantastisch! Sie sind nun vollständig eingerichtet.

Schritt Nr. 2: Installation der Scraping-Bibliotheken

Installieren Sie in einer aktivierten virtuellen Umgebung HTTPX und BeautifulSoup mit dem folgenden Befehl:

pip install httpx beautifulsoup4

Dadurch werden sowohl httpx als auch beautifulsoup4 zu den Abhängigkeiten Ihres Projekts hinzugefügt.

Importieren Sie sie in Ihr scraper.py-Skript:

import httpx
from bs4 import BeautifulSoup

Großartig! Sie können nun zum nächsten Schritt in Ihrem Scraping-Workflow übergehen.

Schritt Nr. 3: Abrufen des HTML der Zielseite

In diesem Beispiel ist die Zielseite die Website „Quotes to Scrape“:

Die Homepage von Quotes to Scrape

Verwenden Sie HTTPX, um den HTML-Code der Homepage mit der Methode get() abzurufen:

# Make an HTTP GET request to the target page
response = httpx.get("http://quotes.toscrape.com")

Hinter den Kulissen stellt HTTPX eine HTTP-GET-Request an den Server, der mit dem HTML-Code der Seite antwortet. Sie können auf den HTML-Inhalt mit dem Attribut response.text zugreifen:

html = response.text
print(html)

Damit wird der unbearbeitete HTML-Inhalt der Seite gedruckt:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Quotes to Scrape</title>
    <link rel="stylesheet" href="/static/bootstrap.min.css">
    <link rel="stylesheet" href="/static/main.css">
</head>
<body>
    <!-- omitted for brevity... -->
</body>
</html>

Großartig! Es ist an der Zeit, diesen Inhalt zu parsen und die benötigten Daten zu extrahieren.

Schritt Nr. 4: Parsen des HTML

Übergeben Sie den HTML-Inhalt an den BeautifulSoup-Constructor, um ihn zu parsen:

# Parse the HTML content using
BeautifulSoup soup = BeautifulSoup(html, "html.parser")

html.parser ist der Standard-HTML-Parser von Python, der zum Parsen des Inhalts verwendet wird.

Die Variable soup enthält nun das geparste HTML und stellt die Methoden zur Extraktion der benötigten Daten bereit.

HTTPX hat seine Aufgabe, den HTML-Code abzurufen, erfüllt, und nun beginnt die traditionelle Phase des Daten-Parsings mit BeautifulSoup. Weitere Informationen finden Sie in unserem Tutorial zum BeautifulSoup Web Scraping.

Schritt Nr. 5: Daten daraus scrapen

Mit den folgenden Codezeilen können Sie Zitatdaten von der Seite scrapen:

# Where to store the scraped data
quotes = []

# Extract all quotes from the page
quote_elements = soup.find_all("div", class_="quote")

# Loop through quotes and extract text, author, and tags
for quote_element in quote_elements:
    text = quote_element.find("span", class_="text").get_text().get_text().replace("“", "").replace("”", "")
    author = quote_element.find("small", class_="author")
    tags = [tag.get_text() for tag in quote_element.find_all("a", class_="tag")]

    # Store the scraped data
    quotes.append({
        "text": text,
        "author": author,
        "tags": tags
    })

Dieses Snippet definiert eine Liste mit den Namen Quotes (Zitate), um die gescrapten Daten zu speichern. Es wählt dann alle HTML-Elemente des Zitats aus und durchläuft sie, um den Zitattext, den -autor und die -Tags zu extrahieren. Jedes extrahierte Zitat wird als Wörterbuch in der Liste Quotes (Zitate) gespeichert, wodurch die Daten für die weitere Verwendung oder den Export organisiert werden.

Ja! Scraping-Logik implementiert.

Schritt Nr. 6: Export der gescrapten Daten

Verwenden Sie die folgende Logik, um die gescrapten Daten in eine CSV-Datei zu exportieren:

# Specify the file name for export
with open("quotes.csv", mode="w", newline="", encoding="utf-8") as file:
    writer = csv.DictWriter(file, fieldnames=["text", "author", "tags"])

    # Write the header row
    writer.writeheader()

    # Write the scraped quotes data
    writer.writerows(quotes)

Dieses Snippet öffnet eine Datei namens quotes.csv im Schreibmodus, definiert Spaltenüberschriften (TextAutorTags), schreibt die Überschriften in die Datei und schreibt dann jedes Wörterbuch aus der Liste Quotes (Zitate) in die CSV-Datei. Der csv.DictWriter übernimmt die Formatierung, sodass strukturierte Daten einfach gespeichert werden können.

Denken Sie daran, csv aus der Python-Standard-Bibliothek zu importieren:

import csv

Schritt Nr. 7: Das Ganze zusammensetzen

Ihr endgültiges HTTPX-Web-Scraping-Skript wird Folgendes enthalten:

import httpx
from bs4 import BeautifulSoup
import csv

# Make an HTTP GET request to the target page
response = httpx.get("http://quotes.toscrape.com")

# Access the HTML of the target page
html = response.text

# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(html, "html.parser")

# Where to store the scraped data
quotes = []

# Extract all quotes from the page
quote_elements = soup.find_all("div", class_="quote")

# Loop through quotes and extract text, author, and tags
for quote_element in quote_elements:
    text = quote_element.find("span", class_="text").get_text().replace("“", "").replace("”", "")
    author = quote_element.find("small", class_="author").get_text()
    tags = [tag.get_text() for tag in quote_element.find_all("a", class_="tag")]

    # Store the scraped data
    quotes.append({
        "text": text,
        "author": author,
        "tags": tags
    })

# Specify the file name for export
with open("quotes.csv", mode="w", newline="", encoding="utf-8") as file:
    writer = csv.DictWriter(file, fieldnames=["text", "author", "tags"])

    # Write the header row
    writer.writeheader()

    # Write the scraped quotes data
    writer.writerows(quotes)

Führen Sie es aus mit:

python scraper.py

Oder, unter Linux/macOS:

python3 scraper.py

Eine quotes.csv-Datei wird im Stammordner Ihres Projekts erscheinen. Öffnen Sie sie und Sie werden Folgendes sehen:

Die CSV-Datei mit den gescrapten Daten

Und voilà! Sie haben gerade gelernt, wie man Web Scraping mit HTTPX und BeautifulSoup durchführt.

HTTPX-Web-Scraping – Erweiterte Funktionen und Techniken

Nachdem Sie nun wissen, wie Sie HTTPX für Web Scraping in einem einfachen Szenario einsetzen können, sind Sie bereit, es bei komplexeren Anwendungsfällen in Aktion zu sehen.

In den folgenden Beispielen ist die Zielwebsite der HTTPBin.io /anything-Endpunkt. Dies ist eine spezielle API, die die IP-Adresse, Header und andere vom Aufrufer gesendete Informationen zurückgibt.

Beherrschen Sie HTTPX für Web Scraping!

Benutzerdefinierte Header festlegen

HTTPX ermöglicht Ihnen, benutzerdefinierte Header festzulegen, dank des Arguments headers :

import httpx

# Custom headers for the request
headers = {
    "accept": "application/json",
    "accept-language": "en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7,es-US;q=0.6,es;q=0.5,it-IT;q=0.4,it;q=0.3"
}

# Make a GET request with custom headers
response = httpx.get("https://httpbin.io/anything", headers=headers)
# Handle the response...

Einrichtung eines benutzerdefinierten User-Agent

User-Agent ist einer der wichtigsten HTTP-Header für Web Scraping. Standardmäßig verwendet HTTPX den folgenden User-Agent:

python-httpx/<VERSION>

Dieser Wert kann leicht verraten, dass Ihre Requests automatisiert sind, was zu einer Blockierung durch die Zielwebsite führen könnte.

Um das zu vermeiden, können Sie einen eigenen User-Agent festlegen, um einen echten Browser zu imitieren, etwa so:

import httpx

# Define a custom User-Agent
headers = {
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
}

# Make a GET request with the custom User-Agent
response = httpx.get("https://httpbin.io/anything", headers=headers)
# Handle the response...

Entdecken Sie die besten User-Agents für Web Scraping!

Cookies setzen

Genau wie HTTP-Header können Sie in HTTPX mit dem Argument cookies Cookies setzen:

import httpx

# Define cookies as a dictionary
cookies = {
    "session_id": "3126hdsab161hdabg47adgb",
    "user_preferences": "dark_mode=true"
}

# Make a GET request with custom cookies
response = httpx.get("https://httpbin.io/anything", cookies=cookies)
# Handle the response...

So können Sie die für Ihre Web-Scraping-Requests erforderlichen Sitzungsdaten einbeziehen.

Proxy-Integration

Sie können Ihre HTTPX-Requests über einen Proxy leiten, um Ihre Identität zu schützen und IP-Sperren zu vermeiden, während Sie Web Scraping durchführen. Dies ist durch die Verwendung des Arguments proxies möglich:

import httpx

# Replace with the URL of your proxy server
proxy = "<YOUR_PROXY_URL>"

# Make a GET request through a proxy server
response = httpx.get("https://httpbin.io/anything", proxy=proxy)
# Handle the response...

Weitere Informationen finden Sie in unserer Anleitung zur  Verwendung von HTTPX mit einem Proxy.

Fehlerbehandlung

Standardmäßig löst HTTPX nur bei Verbindungs- oder Netzwerkproblemen Fehler aus. Um Ausnahmen auch für HTTP-Responses mit 4xx– und 5xx-Statuscodes auszulösen, verwenden Sie die Methode raise_for_status() wie unten:

import httpx

try:
    response = httpx.get("https://httpbin.io/anything")
    # Raise an exception for 4xx and 5xx responses
    response.raise_for_status()
    # Handle the response...
except httpx.HTTPStatusError as e:
    # Handle HTTP status errors
    print(f"HTTP error occurred: {e}")
except httpx.RequestError as e:
    # Handle connection or network errors
    print(f"Request error occurred: {e}")

Sitzungsbehandlung

Bei der Verwendung der Top-Level-API in HTTPX wird für jede einzelne Request eine neue Verbindung aufgebaut. Mit anderen Worten: TCP-Verbindungen werden nicht wiederverwendet. Wenn die Anzahl der Requests an einen Host steigt, wird dieser Ansatz ineffizient.

Im Gegensatz dazu ermöglicht die Verwendung einer httpx.Client-Instanz HTTP-Verbindungspooling. Dies bedeutet, dass mehrere Requests an denselben Host eine bestehende TCP-Verbindung wiederverwenden können, anstatt für jede Request eine neue zu erstellen.

Die Vorteile der Verwendung eines Clients gegenüber der Top-Level-API sind:

  • Geringere Latenzzeit bei Requests (Vermeidung von wiederholter Datenflusskontrolle)
  • Geringere CPU-Nutzung und weniger Round-Trips
  • Geringere Netzwerküberlastung

Zusätzlich unterstützen Client-Instanzen die Sitzungsbehandlung mit Funktionen, die in der Top-Level-API nicht verfügbar sind, einschließlich:

  • Cookie-Persistenz über Requests hinweg.
  • Anwendung der Konfiguration auf alle ausgehenden Requests.
  • Senden von Requests über HTTP-Proxys.

Der empfohlene Weg zur Verwendung eines Clients in HTTPX ist mit einem Kontext-Manager (mit Anweisung):

import httpx

with httpx.Client() as client:
    # Make an HTTP request using the client
    response = client.get("https://httpbin.io/anything")

    # Extract the JSON response data and print it
    response_data = response.json()
    print(response_data)

Alternativ können Sie den Client manuell verwalten und den Verbindungspool explizit mit client.close() schließen:

import httpx

client = httpx.Client()
try:
    # Make an HTTP request using the client
    response = client.get("https://httpbin.io/anything")

    # Extract the JSON response data and print it
    response_data = response.json()
    print(response_data)
except:
  # Handle the error...
  pass
finally:
  # Close the client connections and release resources
  client.close()

Hinweis: Wenn Sie mit der Bibliothek requests vertraut sind, dient httpx.Client() einem ähnlichen Zweck wie requests.Session().

Asynchrone API

Standardmäßig stellt HTTPX eine synchrone Standard-API zur Verfügung. Gleichzeitig bietet es auch einen asynchronen Client für Fälle, in denen dieser benötigt wird. Wenn Sie mit asyncio arbeiten, ist die Verwendung eines asynchronen Clients für das effiziente Senden ausgehender HTTP-Requests unerlässlich.

Asynchrone Programmierung ist ein Parallelitätsmodell, das deutlich effizienter ist als Multithreading. Sie bietet erhebliche Leistungsverbesserungen und unterstützt langlebige Netzwerkverbindungen wie WebSockets. Das macht sie zu einem Schlüsselfaktor bei der Beschleunigung von Web Scraping.

Um asynchrone Requests in HTTPX zu stellen, benötigen Sie einen AsyncClient. Initialisieren und verwenden Sie ihn, um eine GET-Requests, wie unten gezeigt, zu machen:

import httpx
import asyncio

async def fetch_data():
    async with httpx.AsyncClient() as client:
        # Make an async HTTP request
        response = await client.get("https://httpbin.io/anything")

        # Extract the JSON response data and print it
        response_data = response.json()
        print(response_data)

# Run the async function
asyncio.run(fetch_data())

Die Anweisung with (mit) stellt sicher, dass der Client automatisch geschlossen wird, wenn der Block endet. Wenn Sie den Client manuell verwalten, können Sie ihn alternativ mit await client.close()explizit schließen.

Denken Sie daran, dass alle HTTPX-Request-Methoden (get()post(), etc.) asynchron sind, wenn sie einen AsyncClient verwenden. Daher müssen Sie await hinzufügen, bevor Sie sie aufrufen, um eine Response zu erhalten.

Wiederholung fehlgeschlagener Requests

Netzwerkinstabilitäten während des Web Scraping können zu Verbindungsausfällen oder Timeouts führen. HTTPX vereinfacht die Handhabung solcher Probleme über seine Interface HTTPTransport . Dieser Mechanismus wiederholt Requests, wenn ein httpx.ConnectError oder httpx.ConnectTimeout auftritt.

Das folgende Beispiel zeigt, wie ein Transport so konfiguriert werden kann, dass Requests bis zu 3 Mal wiederholt werden:

import httpx

# Configure transport with retry capability on connection errors or timeouts
transport = httpx.HTTPTransport(retries=3)

# Use the transport with an HTTPX client
with httpx.Client(transport=transport) as client:
    # Make a GET request
    response = client.get("https://httpbin.io/anything")
    # Handle the response...

Beachten Sie, dass nur verbindungsbezogene Fehler einen erneuten Versuch auslösen. Zur Behandlung von Lese-/Schreibfehlern oder bestimmten HTTP-Statuscodes müssen Sie eine eigene Wiederholungslogik mit Bibliotheken wie tenacity implementieren.

HTTPX vs. Requests für Web Scraping

Hier ist eine zusammenfassende Tabelle zum Vergleich von HTTPX und Requests für Web Scraping:

Funktion HTTPX Requests
GitHub-Sterne 8.000 52.400
Async-Unterstützung ✔️
Verbindungspooling ✔️ ✔️
HTTP/2-Unterstützung ✔️
User-Agent-Anpassung ✔️ ✔️
Proxy-Unterstützung ✔️ ✔️
Cookie-Handhabung ✔️ ✔️
Timeouts Anpassbar für Anschluss und Lesen Anpassbar für Anschluss und Lesen
Wiederholungsmechanismus Verfügbar über Transporte Verfügbar über HTTPAdapters
Leistung Hoch Medium
Community-Unterstützung und -Beliebtheit Wachsend Groß

Fazit

In diesem Artikel haben Sie die Bibliothek httpx für Web Scraping kennengelernt. Sie haben verstanden, was sie ist, was sie bietet und welche Vorteile sie hat. HTTPX ist eine schnelle und zuverlässige Option für HTTP-Requests bei der Online-Datenerhebung.

Das Problem besteht darin, dass automatisierte HTTP-Requests Ihre öffentliche IP-Adresse preisgeben, wodurch Ihre Identität und Ihr Standort aufgedeckt werden können. Das gefährdet Ihre Privatsphäre. Um Ihre Sicherheit und Privatsphäre zu verbessern, ist eine der effektivsten Methoden die Verwendung eines Proxy-Servers, um Ihre IP-Adresse zu verbergen.

Bright Data kontrolliert die besten Proxy-Server der Welt und betreut Fortune-500-Unternehmen und mehr als 20.000 Kunden. Das Angebot umfasst eine breite Palette von Proxy-Arten:

  • Rechenzentrums-Proxys – über 770.000 Rechenzentrums-IPs.
  • Privatanwender-Proxys – über 72 Millionen Privatanwender-IPs in mehr als 195 Ländern.
  • ISP-Proxys – über 700.000 ISP-IPs.
  • Mobile Proxys – über 7 Millionen mobile IPs.

Erstellen Sie noch heute ein kostenloses Bright Data-Konto und testen Sie unsere Scraping-Lösungen und Proxys!

Keine Kreditkarte erforderlich