Dieser Leitfaden erklärt, wie Sie AutoScraper mit Python für Web-Scraping verwenden:
- Was ist AutoScraper?
- Ein Projekt einrichten
- Eine Ziel-Website auswählen
- Einfache Daten mit AutoScraper scrapen
- Daten aus Websites mit komplexem Design extrahieren
- Häufige Herausforderungen mit AutoScraper
AutoScraper ist eine Python-Bibliothek, die Web-Scraping vereinfacht, indem sie Daten auf Websites anhand von Beispielabfragen automatisch identifiziert und extrahiert, wodurch die manuelle HTML-Inspektion entfällt. Sie verarbeitet dynamische Websites mit minimalem Setup effizient. Erfahren Sie hier mehr über das Scraping dynamischer Websites.
Sobald Sie Python 3 oder eine neuere Version installiert haben, erstellen Sie ein Projektverzeichnis und wechseln Sie hinein:
mkdir auto-scrape && cd auto-scrapeErstellen Sie eine virtuelle Umgebung:
python -m venv envAktivieren Sie sie anschließend. Unter Linux und macOS:
source env/bin/activateUnter Windows:
venv\Scripts\activateInstallieren Sie die Bibliotheken autoscraper und pandas:
pip install autoscraper pandasWenn Sie öffentliche Websites scrapen, stellen Sie sicher, dass Sie die Nutzungsbedingungen (ToS) oder die Datei robots.txt der Website prüfen, um sicherzustellen, dass die Website Scraping erlaubt.
Dieser Leitfaden geht davon aus, dass Daten von Scrape This Site’s Countries of the World: A Simple Example page gescrapet werden, einer anfängerfreundlichen Sandbox, die zum Testen von Scraping-Tools entwickelt wurde.
Diese Seite hat eine einfache Struktur und ist damit ein hervorragender Einstieg, um die Grundlagen der Datenextraktion zu erlernen. Sobald Sie mit den grundlegenden Konzepten vertraut sind, gehen wir zu einem komplexeren Beispiel über – der Seite Hockey Teams: Forms, Searching, and Pagination page.
Verwenden Sie das folgende Skript, um eine Liste von Ländern zusammen mit deren Hauptstadt, Bevölkerung und Fläche zu scrapen:
# 1. Import dependencies
from autoscraper import AutoScraper
import pandas as pd
# 2. Define the URL of the site to be scraped
url = "https://www.scrapethissite.com/pages/simple/"
# 3. Instantiate the AutoScraper
scraper = AutoScraper()
# 4. Define the wanted list by using an example from the web page
# This list should contain some text or values that you want to scrape
wanted_list = ["Andorra", "Andorra la Vella", "84000", "468.0"]
# 5. Build the scraper based on the wanted list and URL
scraper.build(url, wanted_list)
# 6. Get the results for all the elements matched
results = scraper.get_result_similar(url, grouped=True)
# 7. Display the keys and sample data to understand the structure
print("Keys found by the scraper:", results.keys())
# 8. Assign columns based on scraper keys and expected order of data
columns = ["Country Name", "Capital", "Area (sq km)", "Population"]
# 9. Create a DataFrame with the extracted data
data = {columns[i]: results[list(results.keys())[i]] for i in range(len(columns))}
df = pd.DataFrame(data)
# 10. Save the DataFrame to a CSV file
csv_filename = 'countries_data.csv'
df.to_csv(csv_filename, index=False)
print(f"Data has been successfully saved to {csv_filename}")Das obige Skript beginnt mit dem Import der erforderlichen Bibliotheken: AutoScraper und pandas. Als Nächstes wird die URL der Ziel-Website definiert, gefolgt von der Erstellung einer AutoScraper-Instanz.
Hier zeigt sich der Vorteil von AutoScraper: Im Gegensatz zu traditionellen Scrapern, die explizite Anweisungen wie XPath oder CSS-Selektoren erfordern, können Sie bei AutoScraper Beispieldaten angeben. Statt festzulegen, wo sich Elemente auf der Seite befinden, listen Sie einfach einige Beispielwerte auf, die Sie extrahieren möchten. Diese Liste, wanted_list genannt, enthält repräsentative Datenpunkte – wie den Namen eines Landes, die Hauptstadt, die Bevölkerung und die Fläche.
Sobald die wanted_list festgelegt ist, wird der Scraper mit der angegebenen URL und den Beispieldaten aufgebaut. AutoScraper analysiert dann die Webseite, identifiziert Muster und generiert Scraping-Regeln. Diese Regeln ermöglichen es dem Scraper, ähnliche Daten auf derselben oder anderen Webseiten zu erkennen und zu extrahieren.
Weiter unten im Skript wird die Methode get_result_similar aufgerufen, um alle Daten abzurufen, die den von AutoScraper erlernten Mustern entsprechen. Um besser zu verstehen, wie der Scraper die Datenstruktur interpretiert, gibt das Skript die Regel-IDs aus, die den extrahierten Daten zugeordnet sind. Die Ausgabe sollte in etwa so aussehen:
Keys found by the scraper: dict_keys(['rule_4y6n', 'rule_gghn', 'rule_a6r9', 'rule_os29'])
Die Kommentare acht und neun definieren Spaltennamen und strukturieren die extrahierten Daten in einem pandas DataFrame. Kommentar zehn speichert diese Daten dann als CSV-Datei.
Nachdem Sie das Skript ausgeführt haben (python script.py), erscheint im Projektverzeichnis eine Datei countries_data.csv mit Inhalten wie:
Country Name,Capital,Area (sq km),Population
Andorra,Andorra la Vella,84000,468.0
United Arab Emirates,Abu Dhabi,4975593,82880.0
...246 collapsed rows
Zambia,Lusaka,13460305,752614.0
Zimbabwe,Harare,11651858,390580.0Die vorherige Technik kann bei komplexen Websites wie der Seite Hockey Teams page Schwierigkeiten haben, die eine Tabelle mit vielen ähnlichen Werten enthält. Versuchen Sie, Teamnamen, Jahre, Siege und andere Felder mit derselben Methode zu extrahieren, um die Herausforderung zu beobachten.
Glücklicherweise unterstützt AutoScraper die Verfeinerung seines Modells, indem während des Build-Schritts unnötige Regeln entfernt werden. So können Sie das machen:
from autoscraper import AutoScraper
import pandas as pd
# Define the URL of the site to be scraped
url = "https://www.scrapethissite.com/pages/forms/"
def setup_model():
# Instantiate the AutoScraper
scraper = AutoScraper()
# Define the wanted list by using an example from the web page
# This list should contain some text or values that you want to scrape
wanted_list = ["Boston Bruins", "1990", "44", "24", "0.55", "299", "264", "35"]
# Build the scraper based on the wanted list and URL
scraper.build(url, wanted_list)
# Get the results for all the elements matched
results = scraper.get_result_similar(url, grouped=True)
# Display the data to understand the structure
print(results)
# Save the model
scraper.save("teams_model.json")
def prune_rules():
# Create an instance of Autoscraper
scraper = AutoScraper()
# Load the model saved earlier
scraper.load("teams_model.json")
# Update the model to only keep necessary rules
scraper.keep_rules(['rule_hjk5', 'rule_9sty', 'rule_2hml', 'rule_3qvv', 'rule_e8x1', 'rule_mhl4', 'rule_h090', 'rule_xg34'])
# Save the updated model again
scraper.save("teams_model.json")
def load_and_run_model():
# Create an instance of Autoscraper
scraper = AutoScraper()
# Load the model saved earlier
scraper.load("teams_model.json")
# Get the results for all the elements matched
results = scraper.get_result_similar(url, grouped=True)
# Assign columns based on scraper keys and expected order of data
columns = ["Team Name", "Year", "Wins", "Losses", "Win %", "Goals For (GF)", "Goals Against (GA)", "+/-"]
# Create a DataFrame with the extracted data
data = {columns[i]: results[list(results.keys())[i]] for i in range(len(columns))}
df = pd.DataFrame(data)
# Save the DataFrame to a CSV file
csv_filename = 'teams_data.csv'
df.to_csv(csv_filename, index=False)
print(f"Data has been successfully saved to {csv_filename}")
# setup_model()
# prune_rules()
# load_and_run_model()Dieses Skript definiert drei Methoden: setup_model, prune_rules und load_and_run_model.
Die Methode setup_model erstellt eine Scraper-Instanz, definiert eine wanted_list, baut den Scraper auf, scraped Daten von der Ziel-URL, gibt die erfassten Regel-IDs aus und speichert das Modell als teams_model.json im Projektverzeichnis.
Um das Skript auszuführen, kommentieren Sie die Zeile # setup_model() im Skript aus, speichern Sie die Datei (z. B. script.py) und führen Sie sie mit python script.py aus.
Die Ausgabe sieht so aus:
{'rule_hjk5': ['Boston Bruins', 'Buffalo Sabres', 'Calgary Flames', 'Chicago Blackhawks', 'Detroit Red Wings', 'Edmonton Oilers', 'Hartford Whalers', 'Los Angeles Kings', 'Minnesota North Stars', 'Montreal Canadiens', 'New Jersey Devils', 'New York Islanders', 'New York Rangers', 'Philadelphia Flyers', 'Pittsburgh Penguins', 'Quebec Nordiques', 'St. Louis Blues', 'Toronto Maple Leafs', 'Vancouver Canucks', 'Washington Capitals', 'Winnipeg Jets', 'Boston Bruins', 'Buffalo Sabres', 'Calgary Flames', 'Chicago Blackhawks'], 'rule_uuj6': ['Boston Bruins', 'Buffalo Sabres', 'Calgary Flames', 'Chicago Blackhawks', 'Detroit Red Wings', 'Edmonton Oilers', 'Hartford Whalers', 'Los Angeles Kings', 'Minnesota North Stars', 'Montreal Canadiens', 'New Jersey Devils', 'New York Islanders', 'New York Rangers', 'Philadelphia Flyers', 'Pittsburgh Penguins', 'Quebec Nordiques', 'St. Louis Blues', 'Toronto Maple Leafs', 'Vancouver Canucks', 'Washington Capitals', 'Winnipeg Jets', 'Boston Bruins', 'Buffalo Sabres', 'Calgary Flames', 'Chicago Blackhawks'], 'rule_9sty': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_9nie': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_41rr': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_ufil': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_ere2': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_w0vo': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_rba5': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_rmae': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_ccvi': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_3c34': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_4j80': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_oc36': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_93k1': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_d31n': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_ghh5': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_5rne': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_4p78': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_qr7s': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_60nk': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_wcj7': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_0x7y': ['1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1990', '1991', '1991', '1991', '1991'], 'rule_2hml': ['44', '31', '46', '49', '34', '37', '31', '46', '27', '39', '32', '25', '36', '33', '41', '16', '47', '23', '28', '37', '26', '36', '31', '31', '36'], 'rule_swtb': ['24'], 'rule_e8x1': ['0.55', '14', '0.575', '0.613', '-25', '0', '-38', '0.575', '-10', '24', '8', '-67', '32', '-15', '0.512', '-118', '0.588', '-77', '-72', '0', '-28', '-5', '-10', '-9', '21'], 'rule_3qvv': ['24', '30', '26', '23', '38', '37', '38', '24', '39', '30', '33', '45', '31', '37', '33', '50', '22', '46', '43', '36', '43', '32', '37', '37', '29'], 'rule_n07w': ['24', '30', '26', '23', '38', '37', '38', '24', '39', '30', '33', '45', '31', '37', '33', '50', '22', '46', '43', '36', '43', '32', '37', '37', '29'], 'rule_qmem': ['0.55', '0.388', '0.575', '0.613', '0.425', '0.463', '0.388', '0.575', '0.338', '0.487', '0.4', '0.312', '0.45', '0.412', '0.512', '0.2', '0.588', '0.287', '0.35', '0.463', '0.325', '0.45', '0.388', '0.388', '0.45'], 'rule_b9gx': ['264', '278', '263', '211', '298', '272', '276', '254', '266', '249', '264', '290', '265', '267', '305', '354', '250', '318', '315', '258', '288', '275', '299', '305', '236'], 'rule_mhl4': ['299', '292', '344', '284', '273', '272', '238', '340', '256', '273', '272', '223', '297', '252', '342', '236', '310', '241', '243', '258', '260', '270', '289', '296', '257'], 'rule_24nt': ['264', '278', '263', '211', '298', '272', '276', '254', '266', '249', '264', '290', '265', '267', '305', '354', '250', '318', '315', '258', '288', '275', '299', '305', '236'], 'rule_h090': ['264', '278', '263', '211', '298', '272', '276', '254', '266', '249', '264', '290', '265', '267', '305', '354', '250', '318', '315', '258', '288', '275', '299', '305', '236'], 'rule_xg34': ['35', '14', '81', '73', '-25', '0', '-38', '86', '-10', '24', '8', '-67', '32', '-15', '37', '-118', '60', '-77', '-72', '0', '-28', '-5', '-10', '-9', '21']}
Diese Ausgabe zeigt die Daten, die AutoScraper beim Aufruf von get_result_similar von der Ziel-Website gesammelt hat. Sie enthält Duplikate, weil AutoScraper versucht, Beziehungen abzuleiten und Daten in Regeln zu gruppieren. Wenn es korrekt gruppiert, können Daten leicht von ähnlichen Websites extrahiert werden.
AutoScraper hat jedoch bei dieser Website Schwierigkeiten aufgrund der vielen Zahlen, was zu zahlreichen falschen Korrelationen und einem großen Datensatz mit Duplikaten führt.
Um fortzufahren, analysieren Sie die Daten und wählen Sie die Regeln mit den korrekten Daten aus (d. h. solche, die den Daten aus einer Spalte in der richtigen Reihenfolge entsprechen). In diesem Fall enthielten die folgenden Regeln die richtigen Daten (ermittelt durch Überprüfung, dass jede Regel 25 Datenpunkte enthielt, entsprechend der Anzahl der Zeilen auf der Zielseite):
['rule_hjk5', 'rule_9sty', 'rule_2hml', 'rule_3qvv', 'rule_e8x1', 'rule_mhl4', 'rule_h090', 'rule_xg34']
Aktualisieren Sie die Methode prune_rules. Kommentieren Sie dann die Zeile setup_model() aus und heben Sie die Kommentierung der Zeile prune_rules() im Skript auf. Wenn Sie es ausführen, lädt es das Modell aus teams_model.json, entfernt unnötige Regeln und speichert das aktualisierte Modell. Sie können den Inhalt von teams_model.json prüfen, um die gespeicherten Regeln zu verifizieren.
Um anschließend die Methode load_and_run_model auszuführen, kommentieren Sie die prune_rules-Zeilen aus, heben Sie die Kommentierung der Zeile load_and_run_model auf und führen Sie das Skript erneut aus. Dadurch werden die korrekten Daten extrahiert und in teams_data.csv im Projektverzeichnis gespeichert, und es wird folgende Ausgabe angezeigt:
Data has been successfully saved to teams_data.csv
So sieht die Datei teams_data.csv nach einem erfolgreichen Lauf aus:
Team Name,Year,Wins,Losses,Win %,Goals For (GF),Goals Against (GA),+/-
Boston Bruins,1990,44,0.55,24,299,264,35
Buffalo Sabres,1990,31,14,30,292,278,14
...21 more rows
Calgary Flames,1991,31,-9,37,296,305,-9
Chicago Blackhawks,1991,36,21,29,257,236,21Der gesamte in diesem Artikel entwickelte Code ist in diesem GitHub repo verfügbar.
AutoScraper ist hervorragend für einfache Anwendungsfälle mit kleinen Datensätzen und eindeutigen Datenpunkten. Für komplexere Szenarien, wie das Scrapen von Tabellen, kann es jedoch umständlich sein. Außerdem unterstützt es kein JavaScript-Rendering, daher müssen Sie es mit Tools wie Splash, Selenium oder Puppeteer integrieren.
Wenn Sie auf Probleme wie IP-Blocks stoßen oder benutzerdefinierte Header benötigen, ermöglicht AutoScraper Ihnen, zusätzliche Anfrage-Parameter für sein requests-Modul anzugeben, etwa so:
# build the scraper on an initial URL
scraper.build(
url,
wanted_list=wanted_list,
request_args=dict(proxies=proxies) # this is where you can pass in a list of proxies or customer headers
)Zum Beispiel können Sie so einen benutzerdefinierten User-Agent und einen Proxy für das Scraping mit AutoScraper festlegen:
request_args = {
"headers: {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 \
(KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36" # You can customize this value with your desired user agent. This value is the default used by Autoscraper.
},
"proxies": {
"http": "http://user:[email protected]:3128/" # Example proxy to show you how to use the proxy port, host, username, and password values
}
}
# build the scraper on an initial URL
scraper.build(
url,
wanted_list=wanted_list,
request_args=request_args
)AutoScraper verwendet die Python-Bibliothek requests und unterstützt keine Ratenbegrenzung. Um eine Ratenbegrenzung zu handhaben, können Sie manuell Throttling implementieren oder eine vorgefertigte Lösung wie die Bibliothek ratelimit verwenden.
Da AutoScraper nur mit nicht-dynamischen Websites funktioniert, kann es keine CAPTCHA-geschützten Websites verarbeiten. Für diese Fälle sollten Sie eine robustere Lösung wie die Bright Data Web Scraping API in Betracht ziehen, die eine strukturierte Datenextraktion von Websites wie LinkedIn, Amazon und Zillow unterstützt.
Registrieren Sie sich jetzt und beginnen Sie, die Produkte von Bright Data zu erkunden, einschließlich einer kostenlosen Testversion!
