In diesem Leitfaden erkunden wir Folgendes:
- Was AIOHTTP ist und welche wichtigen Funktionen es bietet
- Einen Schritt-für-Schritt-Abschnitt zur Verwendung von AIOHTTP für Web Scraping
- Fortgeschrittene Techniken für Web Scraping mit AIOHTTP
- Ein Vergleich zwischen AIOHTTP und Requests für die Handhabung automatisierter Requests
Dann legen wir mal los!
Was ist AIOHTTP?
AIOHTTP ist ein asynchrones Client-/Server-HTTP-Framework, das auf Pythons asyncio
aufbaut. Im Gegensatz zu herkömmlichen HTTP-Clients verwendet AIOHTTP Client-Sitzungen, um Verbindungen über mehrere Requests hinweg aufrechtzuerhalten. Das macht es zu einer effizienten Wahl für sitzungsbasierte Aufgaben mit hoher Parallelität.
⚙️ Merkmale
- Unterstützt sowohl die Client- als auch die Serverseite des HTTP-Protokolls.
- Bietet nativen Support für WebSockets (sowohl Client als auch Server).
- Bietet Middleware und steckbares Routing für Webserver.
- Verarbeitet das Streaming großer Daten effizient.
- Umfasst die Persistenz von Client-Sitzungen, ermöglicht die Wiederverwendung von Verbindungen und reduziert den Overhead bei mehreren Requests.
Scraping mit AIOHTTP: Schritt-für-Schritt-Anleitung
Im Zusammenhang mit Web Scraping ist AIOHTTP lediglich ein HTTP-Client, der den rohen HTML-Inhalt einer Seite abruft. Zum Parsen und Extrahieren von Daten aus diesem HTML benötigen Sie dann einen HTML-Parser wie BeautifulSoup.
In diesem Abschnitt erfahren Sie, wie Sie AIOHTTP für Web Scraping mit BeautifulSoup verwenden!
Warnung: Obwohl AIOHTTP hauptsächlich in der Anfangsphase des Prozesses verwendet wird, werden wir Sie durch den gesamten Scraping-Workflow führen. Wenn Sie an fortschrittlicheren AIOHTTP-Web-Scraping-Techniken interessiert sind, können Sie zum nächsten Kapitel nach Schritt 3 übergehen.
Schritt Nr. 1: Einrichtung Ihres Scraping-Projekts
Stellen Sie sicher, dass Python 3+ auf Ihrem Computer installiert ist. Falls nicht, laden Sie es von der offiziellen Website herunter und folgen Sie den Installationsanweisungen.
Erstellen Sie dann mit diesem Befehl ein Verzeichnis für Ihr AIOHTTP-Scraping-Projekt:
mkdir aiohttp-scraper
Navigieren Sie in dieses Verzeichnis und richten Sie eine virtuelle Umgebung ein:
cd aiohttp-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 sind beides gültige Auswahlmöglichkeiten.
Erstellen Sie nun innerhalb des Projektordners eine scraper.py
-Datei. Zunächst wird sie leer sein, aber Sie werden bald die Scraping-Logik hinzufügen.
Aktivieren Sie in Ihrem Terminal der IDE die virtuelle Umgebung. Unter Linux oder macOS verwenden Sie:
./env/bin/activate
Äquivalent, unter Windows, führen Sie Folgendes aus:
env/Scripts/activate
Großartig! Sie sind fertig und können loslegen.
Schritt Nr. 2: Einrichtung der Scraping-Bibliotheken
Wenn die virtuelle Umgebung aktiviert ist, installieren Sie AIOHTTP und BeautifulSoup mit dem folgenden Befehl:
pip install aiohttp beautifulsoup4
Dadurch wird aiohttp
und beautifulsoup4
zu den Abhängigkeiten Ihres Projekts hinzugefügt.
Importieren Sie sie in Ihr scraper.py
-Skript:
import asyncio
import aiohttp
from bs4 import BeautifulSoup
Beachten Sie, dass aiohttp
die asyncio
benötigt, um zu funktionieren.
Fügen Sie nun den folgenden async
-Funktionsablauf in Ihre scrper.py
-Datei ein:
async def scrape_quotes():
# Scraping logic...
# Run the asynchronous function
asyncio.run(scrape_quotes())
scrape_quotes()
definiert eine asynchrone Funktion, bei der Ihre Scraping-Logik gleichzeitig und ohne Blockierung ausgeführt wird. Schließlich startet asyncio.run(scrape_quotes())
und führt die asynchrone Funktion aus.
Fantastisch! Sie können mit dem nächsten Schritt in Ihrem Scraping-Workflow fortfahren.
Schritt Nr. 3: Holen Sie sich den HTML-Code der Zielseite
In diesem Beispiel sehen Sie, wie Sie Daten von der Website „Quotes to Scrape“ scrapen:
Mit Bibliotheken wie Requests oder AIOHTTP würden Sie einfach eine GET-Request stellen und direkt den HTML-Inhalt der Seite erhalten. AIOHTTP folgt jedoch einem anderen Request-Lebenszyklus.
Die AIOHTTP-Primärkomponente ist die ClientSession
, die einen Pool von Verbindungen verwaltet und Keep-Alive
standardmäßig unterstützt. Anstatt für jede Request eine neue Verbindung zu öffnen, werden Verbindungen wiederverwendet, was die Leistung verbessert.
Bei einer Request sind in der Regel drei Schritte erforderlich:
- Eröffnung einer Sitzung durch
ClientSession()
. - Asynchrones Senden der GET-Request mit
session.get()
. - Zugriff auf die Response-Daten mit Methoden wie
await response.text()
.
Dieses Design ermöglicht der Ereignisschleife, verschiedene mit
contexts zwischen den Operationen ohne Blockieren zu verwenden, was es ideal für Aufgaben mit hoher Parallelität macht.
Vor diesem Hintergrund können Sie AIOHTTP verwenden, um das HTML der Homepage mit dieser Logik abzurufen:
async with aiohttp.ClientSession() as session:
async with session.get("http://quotes.toscrape.com") as response:
# Access the HTML of the target page
html = await response.text()
Hinter den Kulissen sendet AIOHTTP die Request an den Server und wartet auf die Response, die den HTML-Code der Seite enthält. Sobald die Response eingegangen ist, extrahiert await response.text()
den HTML-Inhalt als Zeichenfolge.
Drucken Sie die Variable html
und Sie werden Folgendes sehen:
<!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>
Gut gemacht! Sie haben den HTML-Inhalt der Zielseite erfolgreich abgerufen. 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-Python-HTML-Parser, der zur Verarbeitung des Inhalts verwendet wird.
Das Objekt soup
enthält das geparste HTML und bietet Methoden zur Extraktion der benötigten Daten.
AIOHTTP hat das Abrufen des HTML übernommen und jetzt wechseln Sie mit BeautifulSoup zur typischen Daten-Parsing-Phase. Weitere Einzelheiten finden Sie in unserem Tutorial zu BeautifulSoup Web Scraping.
Schritt Nr. 5: Schreiben der Datenextraktionslogik
Mit folgendem Code können Sie die Zitate 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
})
Dieser Snippet initialisiert eine Liste mit dem Namen Quotes (Zitate)
, um die gescrapten Daten zu speichern. Anschließend werden alle HTML-Elemente des Zitats identifiziert und in einer Schleife durchlaufen, um den Text, den Autor und die Tags des Zitats zu extrahieren. Jedes extrahierte Zitat wird als Wörterbuch in der Liste Quotes (Zitate)
gespeichert, wodurch die Daten für die spätere Verwendung oder den Export organisiert werden.
Super! Die Scraping-Logik ist nun implementiert.
Schritt Nr. 6: Export der gescrapten Daten
Verwenden Sie diese Codezeilen, um die gescrapten Daten in eine CSV-Datei zu exportieren:
# Open the file 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)
Das obige Snippet öffnet eine Datei mit dem Namen quotes.csv
im Schreibmodus. Dann werden Spaltenüberschriften (Text
, Autor
, Tags
) erstellt, die Überschriften geschrieben und dann jedes Wörterbuch aus der Liste Quotes (Zitate)
in die CSV-Datei geschrieben.
csv.DictWriter
vereinfacht die Datenformatierung und erleichtert so die Speicherung strukturierter Daten. Damit es funktioniert, müssen Sie csv
aus der Python-Standardbibliothek importieren:
import csv
Schritt Nr. 7: Das Ganze zusammensetzen
So sollte Ihr fertiges AIOHTTP-Web-Scraping-Skript aussehen:
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import csv
# Define an asynchronous function to make the HTTP GET request
async def scrape_quotes():
async with aiohttp.ClientSession() as session:
async with session.get("http://quotes.toscrape.com") as response:
# Access the HTML of the target page
html = await response.text()
# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# List 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
})
# Open 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)
# Run the asynchronous function
asyncio.run(scrape_quotes())
Sie können es ausführen 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:
Und voilà! Sie haben gerade gelernt, wie man Web Scraping mit AIOHTTP und BeautifulSoup durchführt.
AIOHTTP für Web Scraping: Erweiterte Funktionen und Techniken
Nachdem Sie nun wissen, wie Sie AIOHTTP für grundlegendes Web Scraping verwenden können, ist es an der Zeit, sich fortgeschrittenere Szenarien anzusehen.
In den folgenden Beispielen wird die Zielwebsite der HTTPBin.io /anything
-Endpunkt sein. Dies ist eine praktische API, die die IP-Adresse, Header und andere vom Requester gesendete Daten zurückgibt.
Machen Sie sich bereit, AIOHTTP für Web Scraping zu beherrschen!
Benutzerdefinierte Header festlegen
Sie können benutzerdefinierte Header in einer AIOHTTP-Request mit dem Argument headers
festlegen:
import aiohttp
import asyncio
async def fetch_with_custom_headers():
# 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"
}
async with aiohttp.ClientSession() as session:
# Make a GET request with custom headers
async with session.get("https://httpbin.io/anything", headers=headers) as response:
data = await response.json()
# Handle the response...
print(data)
# Run the event loop
asyncio.run(fetch_with_custom_headers())
Auf diese Weise stellt AIOHTTP eine GET-HTTP-Request mit den festgelegten Accept
und Accept-Language
Headern.
Einrichtung eines benutzerdefinierten User-Agent
User-Agent
ist einer der kritischsten HTTP-Header für Web Scraping. Standardmäßig verwendet AIOHTTP diesen User-Agent
:
Python/<PYTHON_VERSION> aiohttp/<AIOHTTP_VERSION>
Der obige Standardwert kann Ihre Request leicht als von einem automatisierten Skript stammend entlarven. Dadurch erhöht sich das Risiko, von der Zielwebsite blockiert zu werden.
Um die Wahrscheinlichkeit, entdeckt zu werden, zu verringern, können Sie einen benutzerdefinierten User-Agent
wie zuvor festlegen:
import aiohttp
import asyncio
async def fetch_with_custom_user_agent():
# Define a Chrome-like custom User-Agent
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
}
async with aiohttp.ClientSession(headers=headers) as session:
# Make a GET request with the custom User-Agent
async with session.get("https://httpbin.io/anything") as response:
data = await response.text()
# Handle the response...
print(data)
# Run the event loop
asyncio.run(fetch_with_custom_user_agent())
Entdecken Sie die besten User-Agents für Web Scraping!
Cookies setzen
Genau wie HTTP-Header können Sie benutzerdefinierte Cookies setzen, indem Sie die Cookies
in ClientSession()
verwenden:
import aiohttp
import asyncio
async def fetch_with_custom_cookies():
# Define cookies as a dictionary
cookies = {
"session_id": "9412d7hdsa16hbda4347dagb",
"user_preferences": "dark_mode=false"
}
async with aiohttp.ClientSession(cookies=cookies) as session:
# Make a GET request with custom cookies
async with session.get("https://httpbin.io/anything") as response:
data = await response.text()
# Handle the response...
print(data)
# Run the event loop
asyncio.run(fetch_with_custom_cookies())
Mithilfe von Cookies können Sie die für Ihre Web-Scraping-Requests erforderlichen Sitzungsdaten aufnehmen.
Beachten Sie, dass die in ClientSession
gesetzten Cookies für alle mit dieser Sitzung gemachten Requests gemeinsam genutzt werden. Um auf Sitzungscookies zuzugreifen, wenden Sie sich an ClientSession.cookie_jar
.
Proxy-Integration
In AIOHTTP können Sie Ihre Requests über einen Proxy-Server leiten, um das Risiko von IP-Sperren zu verringern. Verwenden Sie dazu das Proxy
-Argument in der HTTP-Methodenfunktion auf Sitzung
:
import aiohttp
import asyncio
async def fetch_through_proxy():
# Replace with the URL of your proxy server
proxy_url = "<YOUR_PROXY_URL>"
async with aiohttp.ClientSession() as session:
# Make a GET request through the proxy server
async with session.get("https://httpbin.io/anything", proxy=proxy_url) as response:
data = await response.text()
# Handle the response...
print(data)
# Run the event loop
asyncio.run(fetch_through_proxy())
Wie Sie die Proxy-Authentifizierung und -Rotation durchführen können, erfahren Sie in unserer Anleitung Wie man einen Proxy in AIOHTTP verwendet.
Fehlerbehandlung
Standardmäßig gibt AIOHTTP nur bei Verbindungs- oder Netzwerkproblemen Fehler aus. Um Ausnahmen für HTTP-Responses auszulösen, wenn Sie 4xx
– und 5xx
-Statuscodes empfangen, können Sie einen der folgenden Ansätze verwenden:
- Setzen Sie
raise_for_status=True
beim Erstellen derClientSession
: Automatisches Auslösen von Ausnahmen für alle Requests, die über die Sitzung erfolgen, wenn der Response-Status4xx
oder5xx
ist. - Übergeben Sie
raise_for_status=True
direkt an Request-Methoden: Aktivieren Sie die Fehlersuche für einzelne Request-Methoden (wiesession.get()
odersession.post()
), ohne andere zu beeinträchtigen. - Rufen Sie
response.raise_for_status()
manuell auf: Geben Sie die volle Kontrolle darüber, wann Ausnahmen ausgelöst werden, sodass Sie pro Request entscheiden können.
Option Nr. 1 – Beispiel:
import aiohttp
import asyncio
async def fetch_with_session_error_handling():
async with aiohttp.ClientSession(raise_for_status=True) as session:
try:
async with session.get("https://httpbin.io/anything") as response:
# No need to call response.raise_for_status(), as it is automatic
data = await response.text()
print(data)
except aiohttp.ClientResponseError as e:
print(f"HTTP error occurred: {e.status} - {e.message}")
except aiohttp.ClientError as e:
print(f"Request error occurred: {e}")
# Run the event loop
asyncio.run(fetch_with_session_error_handling())
Wenn raise_for_status=True
auf der Sitzungsebene gesetzt ist, werden alle Requests, die über diese Sitzung gemacht werden, einen aiohttp.ClientResponseError
für 4xx
– oder 5xx
-Responses auslösen.
Option Nr. 2 – Beispiel:
import aiohttp
import asyncio
async def fetch_with_raise_for_status():
async with aiohttp.ClientSession() as session:
try:
async with session.get("https://httpbin.io/anything", raise_for_status=True) as response:
# No need to manually call response.raise_for_status(), it is automatic
data = await response.text()
print(data)
except aiohttp.ClientResponseError as e:
print(f"HTTP error occurred: {e.status} - {e.message}")
except aiohttp.ClientError as e:
print(f"Request error occurred: {e}")
# Run the event loop
asyncio.run(fetch_with_raise_for_status())
In diesem Fall wird das Argument raise_for_status=True
direkt an den Aufruf session.get()
übergeben. Dadurch wird sichergestellt, dass automatisch eine Ausnahme für alle 4xx
– oder 5xx
-Statuscodes ausgelöst wird.
Option Nr. 3 – Beispiel:
import aiohttp
import asyncio
async def fetch_with_manual_error_handling():
async with aiohttp.ClientSession() as session:
try:
async with session.get("https://httpbin.io/anything") as response:
response.raise_for_status() # Manually raises error for 4xx/5xx
data = await response.text()
print(data)
except aiohttp.ClientResponseError as e:
print(f"HTTP error occurred: {e.status} - {e.message}")
except aiohttp.ClientError as e:
print(f"Request error occurred: {e}")
# Run the event loop
asyncio.run(fetch_with_manual_error_handling())
Wenn Sie mehr Kontrolle über einzelne Requests wünschen, können Sie response.raise_for_status()
manuell aufrufen, nachdem Sie eine Request gemacht haben. Auf diese Weise können Sie genau entscheiden, wann Sie Fehler angehen möchten.
Wiederholung fehlgeschlagener Requests
AIOHTTP bietet keine integrierte Unterstützung für die automatische Wiederholung von Requests. Um dies zu implementieren, müssen Sie benutzerdefinierte Logik oder eine Bibliothek eines Dritten wie aiohttp-retry
verwenden. Damit können Sie eine Wiederholungslogik für fehlgeschlagene Requests konfigurieren, die bei vorübergehenden Netzwerkproblemen, Zeitüberschreitungen oder Ratenbeschränkungen hilft.
Installieren Sie aiohttp-retry
mit:
pip install aiohttp-retry
Dann können Sie es wie folgt verwenden:
import asyncio
from aiohttp_retry import RetryClient, ExponentialRetry
async def main():
retry_options = ExponentialRetry(attempts=1)
retry_client = RetryClient(raise_for_status=False, retry_options=retry_options)
async with retry_client.get("https://httpbin.io/anything") as response:
print(response.status)
await retry_client.close()
Dadurch wird das Wiederholungsverhalten mit einer exponentiellen Backoff-Strategie konfiguriert. Weitere Informationen finden Sie in den offiziellen Dokumenten.
AIOHTTP vs. Requests für Web Scraping
Nachfolgend eine zusammenfassende Tabelle zum Vergleich von AIOHTTP und Requets für Web Scraping:
Funktion | AIOHTTP | Requests |
---|---|---|
GitHub-Sterne | 15.300 | 52.400 |
Kundenbetreuung | ✔️ | ✔️ |
Sync-Unterstützung | ❌ | ✔️ |
Async-Unterstützung | ✔️ | ❌ |
Server-Unterstützung | ✔️ | ❌ |
Verbindungspooling | ✔️ | ✔️ |
HTTP/2-Unterstützung | ❌ | ❌ |
User-Agent-Anpassung | ✔️ | ✔️ |
Proxy-Unterstützung | ✔️ | ✔️ |
Cookie-Handhabung | ✔️ | ✔️ |
Wiederholungsmechanismus | Nur über eine Bibliothek eines Dritten verfügbar | Verfügbar über HTTPAdapter s |
Leistung | Hoch | Medium |
Community-Unterstützung und -Beliebtheit | Medium | Groß |
Einen vollständigen Vergleich finden Sie in unserem Blogbeitrag zu Requests vs. HTTPX vs. AIOHTTP.
Erfahren Sie, wie man mit HTTPX Websites scrapen kann.
Fazit
Durch diesen Artikel haben Sie erfahren, wie Sie die aiohttp
-Bibliothek für Web Scraping verwenden. Sie haben erkundet, was sie ist, welche Funktionen sie bietet und welchen Nutzen sie hat. AIOHTTP zeichnet sich als schnelle und zuverlässige Wahl für HTTP-Request bei der Erfassung von Online-Daten aus.
Bei automatisierten HTTP-Requests wird jedoch Ihre öffentliche IP-Adresse offengelegt. Das kann Ihre Identität und Ihren Standort preisgeben und Ihre Privatsphäre gefährden. Um Ihre Sicherheit und Privatsphäre zu schützen, ist eine der effektivsten Strategien 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, um unsere Proxys und Scraping-Lösungen zu testen!
Keine Kreditkarte erforderlich