Skip to content

bright-data-de/web-scraping-with-autoscraper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 

Repository files navigation

Web-Scraping mit AutoScraper

Promo

Dieser Leitfaden erklärt, wie Sie AutoScraper mit Python für Web-Scraping verwenden:

What Is 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.

Setting up a Project

Sobald Sie Python 3 oder eine neuere Version installiert haben, erstellen Sie ein Projektverzeichnis und wechseln Sie hinein:

mkdir auto-scrape && cd auto-scrape

Erstellen Sie eine virtuelle Umgebung:

python -m venv env

Aktivieren Sie sie anschließend. Unter Linux und macOS:

source env/bin/activate

Unter Windows:

venv\Scripts\activate

Installieren Sie die Bibliotheken autoscraper und pandas:

pip install autoscraper pandas

Selecting a Target Website

Wenn 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.

Scraping Simple Data with AutoScraper

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.0

Extracting Data from Websites with a Complex Design

Die 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,21

Der gesamte in diesem Artikel entwickelte Code ist in diesem GitHub repo verfügbar.

Common Challenges with AutoScraper

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!

About

AutoScraper mit Python für Web-Scraping. Automatisieren Sie die Datenextraktion aus einfachen und komplexen Websites mit minimalem Setup und ohne manuelles HTML-Parsing.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors