Zurück zum Blog
Anleitungen
Ștefan RăcilăLast updated on Mar 31, 20268 min read

So erstellen Sie einen Webcrawler mit Python – Ein Leitfaden für Anfänger

So erstellen Sie einen Webcrawler mit Python – Ein Leitfaden für Anfänger

Web-Crawling ist der Vorgang, bei dem Webseiten automatisch aufgerufen und nützliche Informationen daraus extrahiert werden. Ein Web-Crawler, auch als Spider oder Bot bekannt, ist ein Programm, das diese Aufgabe übernimmt. In diesem Artikel werden wir erläutern, wie man einen Web-Crawler mit der Programmiersprache Python erstellt. Konkret werden wir zwei Web-Crawler erstellen.

Wir werden einen einfachen Webcrawler von Grund auf in Python unter Verwendung der Bibliotheken Requests und BeautifulSoup erstellen. Danach werden wir über die Vorteile der Verwendung eines Webcrawling-Frameworks wie Scrapy sprechen. Und schließlich werden wir einen Beispiel-Crawler mit Scrapy erstellen, um Daten zu allen Babyprodukten von Amazon zu sammeln. Wir werden auch sehen, wie sich Scrapy auf Websites mit mehreren Millionen Seiten skalieren lässt.

Voraussetzungen

Bevor Sie diesem Artikel folgen, benötigen Sie grundlegende Kenntnisse in Python und müssen Python auf Ihrem Computer installiert haben. Außerdem müssen Sie die Module Requests und BeautifulSoup installieren. Dies können Sie tun, indem Sie den folgenden Befehl in Ihrer Eingabeaufforderung oder Ihrem Terminal ausführen:

$ pip install requests bs4

Für den zweiten Teil dieses Artikels, in dem wir einen Beispiel-Webcrawler mit Scrapy erstellen, müssen Sie das Scrapy-Framework installieren. Die Entwickler dieses Frameworks empfehlen dringend, Scrapy in einer dedizierten virtuellen Umgebung zu installieren, um Konflikte mit Ihren Systempaketen zu vermeiden.

Ich empfehle Ihnen, virtualenv und virtualenvwrapper zu installieren, um eine isolierte Python-Umgebung zu erstellen. Bitte beachten Sie, dass es für Windows eine Version von virtualenvwrapper namens virtualenvwrapper-win gibt.

Sie müssen außerdem pipx über pip installieren, um virtualenv zu installieren.

$ python -m pip install --user pipx

$ python -m pipx ensurepath

Nachdem Sie eine isolierte Python-Umgebung erstellt haben, können Sie Scrapy mit dem folgenden Befehl installieren.

$ pip install Scrapy

Die Installationsanleitung für Scrapy finden Sie hier.

Was ist ein Webcrawler?

Web-Crawling und Web-Scraping sind verwandte, aber unterschiedliche Konzepte. Web-Scraping ist der gesamte Prozess der Datenextraktion aus einer Website. Web-Crawling ist die spezifische Aufgabe, automatisch durch Webseiten zu navigieren, um die URLs zu finden, die gescrapt werden müssen.

Ein Webcrawler beginnt mit einer Liste von URLs, zu denen navigiert werden soll, die als Seed bezeichnet wird. Während er durch jede URL navigiert, durchsucht er den HTML-Code nach Links und filtert diese anhand bestimmter Kriterien. Alle neu gefundenen Links werden einer Warteschlange für die spätere Verarbeitung hinzugefügt. Der extrahierte HTML-Code oder die spezifischen Informationen werden dann zur weiteren Verarbeitung an eine andere Pipeline weitergeleitet.

Bei der Erstellung eines Web-Crawlers ist es wichtig zu beachten, dass nicht alle Seiten einer Website besucht werden. Die Anzahl der besuchten Seiten hängt vom Budget des Crawlers, der Crawling-Tiefe oder der für die Ausführung zugewiesenen Zeit ab.

Viele Websites verfügen über eine robots.txt-Datei, die angibt, welche Teile der Website gecrawlt werden dürfen und welche vermieden werden sollten. Darüber hinaus verfügen einige Websites über eine sitemap.xml, die expliziter ist als robots.txt und Bots konkret anweist, welche Seiten gecrawlt werden sollen, sowie zusätzliche Metadaten für jede URL bereitstellt.

Webcrawler werden häufig für verschiedene Zwecke eingesetzt:

  • SEO-Analysetools sammeln neben HTML auch Metadaten wie Antwortzeit und Antwortstatus, um defekte Seiten und Links zwischen verschiedenen Domains zu erkennen und Backlinks zu erfassen.
  • Preisüberwachungstools crawlen E-Commerce-Websites, um Produktseiten zu finden und Metadaten, insbesondere Preise, zu extrahieren. Die Produktseiten werden dann regelmäßig erneut aufgerufen.
  • Suchmaschinen wie Googlebot, Bingbot und Yandex Bot sammeln den gesamten HTML-Code für einen bedeutenden Teil des Webs und nutzen die Daten, um ihn durchsuchbar zu machen.

Im weiteren Verlauf dieses Artikels werden wir zwei verschiedene Ansätze zum Erstellen eines Webcrawlers in Python vergleichen. Der erste Ansatz nutzt die Requests-Bibliothek für HTTP-Anfragen und BeautifulSoup zum Parsen von HTML-Inhalten. Der zweite Ansatz nutzt ein Webcrawling-Framework. Wir werden Scrapy verwenden.

Verwendung der Bibliotheken Requests und BeautifulSoup

Das Requests-Modul in Python ist ein leistungsstarkes Werkzeug zum Absenden von HTTP-Anfragen. Um es für das Web-Crawling zu nutzen, können Sie zunächst das Modul importieren und eine Anfrage an eine bestimmte URL senden. Zum Beispiel:

url = 'https://amazon.com/s?k=baby+products'

response = requests.get(url)

Sobald Sie die Antwort erhalten haben, können Sie mit BeautifulSoup alle Links aus dem HTML-Inhalt extrahieren. Zum Beispiel:

import json

from urllib.parse import urljoin

from bs4 import BeautifulSoup

html = response.text

links = []

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

for link in soup.find_all('a'):

    path = link.get('href')

    if path and path.startswith('/'):

        path = urljoin(url, path)

   

    links.append(path)

print(json.dumps(links, sort_keys = True, indent = 2))

Anschließend können Sie die Links durchlaufen und Anfragen an sie senden, wobei Sie den Vorgang wiederholen, bis Sie alle Seiten besucht haben, die Sie crawlen möchten. Dies ist eine rekursive Funktion, die genau so funktioniert:

import requests

from urllib.parse import urljoin

from bs4 import BeautifulSoup

import logging

logging.basicConfig(

    format='%(asctime)s %(levelname)s:%(message)s',

    level=logging.INFO)

url = 'https://amazon.com/s?k=baby+products'

visited = []

def crawl(url):

    logging.info(f'Crawling: {url}')

    visited.append(url)

    html = ''

    try:

        html = requests.get(url).text

    except Exception:

        logging.exception(f'Failed to crawl: {url}')

        return

        

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

    # here you can extract and store useful data from the page

    for link in soup.find_all('a'):

        path = link.get('href')

        if path and path.startswith('/'):

            path = urljoin(url, path)

        

        if path not in visited:

            crawl(path)

crawl(url)

Die Funktion protokolliert für jede besuchte URL eine Zeile.

2023-01-16 09:20:51,681 INFO:Crawling: https://amazon.com/s?k=baby+products

2023-01-16 09:20:53,053 INFO:Crawling: https://amazon.com/ref=cs_503_logo

2023-01-16 09:20:54,195 INFO:Crawling: https://amazon.com/ref=cs_503_link

2023-01-16 09:20:55,131 INFO:Crawling: https://amazon.com/dogsofamazon/ref=cs_503_d

2023-01-16 09:20:56,549 INFO:Crawling: https://www.amazon.com/ref=nodl_?nodl_android

2023-01-16 09:20:57,071 INFO:Crawling: https://www.amazon.com/ref=cs_503_logo

2023-01-16 09:20:57,690 INFO:Crawling: https://www.amazon.com/ref=cs_503_link

2023-01-16 09:20:57,943 INFO:Crawling: https://www.amazon.com/dogsofamazon/ref=cs_503_d

2023-01-16 09:20:58,413 INFO:Crawling: https://www.amazon.com.au/ref=nodl_&nodl_android

2023-01-16 09:20:59,555 INFO:Crawling: None

2023-01-16 09:20:59,557 ERROR:Failed to crawl: None

Auch wenn der Code für einen einfachen Webcrawler simpel erscheinen mag, gibt es viele Herausforderungen, die bewältigt werden müssen, um eine gesamte Website erfolgreich zu crawlen. Dazu gehören Probleme wie:

  • Der Logik der Download-URLs fehlt ein Wiederholungsmechanismus, und die URL-Warteschlange ist bei einer hohen Anzahl von URLs nicht sehr effizient.
  • Der Crawler identifiziert sich nicht und ignoriert die robots.txt-Datei.
  • Der Crawler ist langsam und unterstützt keine Parallelität. Das Crawlen jeder URL dauert etwa eine Sekunde, und der Crawler wartet auf eine Antwort, bevor er zur nächsten URL übergeht.
  • Die Logik zur Link-Extraktion unterstützt keine Standardisierung von URLs durch Entfernen von Query-String-Parametern, verarbeitet keine relativen Anker-/Fragment-URLs (wie href="#anchor") und bietet keine Filterung von URLs nach Domain oder das Herausfiltern von Anfragen an statische Dateien.

Im nächsten Abschnitt werden wir sehen, wie Scrapy diese Probleme löst und es einfach macht, die Funktionalität des Web-Crawlers für benutzerdefinierte Anwendungsfälle zu erweitern.

So erstellen Sie einen Webcrawler in Python mit dem Scrapy-Framework

Scrapy ist ein leistungsstarkes Framework zur Erstellung von Webcrawlern in Python. Es bietet eine integrierte Möglichkeit, Links zu verfolgen und Informationen aus Webseiten zu extrahieren. Sie müssen ein neues Scrapy-Projekt und einen Spider erstellen, um das Verhalten Ihres Crawlers zu definieren.

Bevor Sie mit dem Crawlen einer Website wie Amazon beginnen, ist es wichtig, die robots.txt-Datei der Website zu überprüfen, um festzustellen, welche URL-Pfade zulässig sind. Scrapy liest diese Datei automatisch und folgt ihr, wenn die Einstellung ROBOTSTXT_OBEY auf „true“ gesetzt ist, was die Standardeinstellung für Projekte ist, die mit dem Scrapy-Befehl `startproject` erstellt wurden.

Um ein neues Scrapy-Projekt zu erstellen, müssen Sie den folgenden Befehl ausführen:

$ scrapy startproject amazon_crawler

Dieser Befehl generiert ein Projekt mit der folgenden Struktur:

amazon_crawler/

├── scrapy.cfg

└── amazon_crawler

    ├── __init__.py

    ├── items.py

    ├── middlewares.py

    ├── pipelines.py

    ├── settings.py

    └── spiders

        ├── __init__.py

Um einen Spider zu erstellen, verwenden Sie den Befehl `genspider` aus der Scrapy-CLI. Der Befehl hat folgende Definition:

$ scrapy genspider [options] <name> <domain>

Um einen Spider für diesen Crawler zu generieren, können wir Folgendes ausführen:

$ cd amazon_crawler

$ scrapy genspider baby_products amazon.com

Dadurch sollte eine Datei namens `baby_products.py` im Ordner `spiders` erstellt und folgender Code generiert werden:

import scrapy

class BabyProductsSpider(scrapy.Spider):

    name = 'wikipedia'

    allowed_domains = ['en.wikipedia.com']

    start_urls = ['http://en.wikipedia.com/']

    def parse(self, response):

        pass

Scrapy bietet außerdem eine Vielzahl vorgefertigter Spider-Klassen an, wie beispielsweise CrawlSpider, XMLFeedSpider, CSVFeedSpider und SitemapSpider. Die CrawlSpider-Klasse, die auf der Basis-Spider-Klasse aufbaut, enthält ein zusätzliches „rules“-Attribut, um zu definieren, wie durch eine Website navigiert werden soll. Jede Regel nutzt einen LinkExtractor, um zu bestimmen, welche Links von jeder Seite extrahiert werden sollen.

Für unseren Anwendungsfall sollten wir unsere Spider-Klasse von CrawlSpider ableiten. Außerdem müssen wir eine LinkExtractor-Regel erstellen, die dem Crawler mitteilt, Links nur aus der Paginierung von Amazon zu extrahieren. Denken Sie daran, dass unser Ziel darin bestand, Daten zu allen Babyprodukten von Amazon zu sammeln; wir wollen also nicht tatsächlich allen Links folgen, die wir auf der Seite finden.

Dann müssen wir zwei weitere Methoden in unserer Klasse erstellen: `parse_item` und `parse_product`. `parse_item` wird als Callback-Funktion an unsere LinkExtractor-Regel übergeben und bei jedem extrahierten Link aufgerufen. `parse_product` analysiert jedes Produkt… ¯\_(ツ)_/¯

from scrapy.spiders import CrawlSpider, Rule

from scrapy.linkextractors import LinkExtractor

from bs4 import BeautifulSoup

class BabyProductsSpider(CrawlSpider):

    name = 'baby_products'

    allowed_domains = ['amazon.com']

    start_urls = ['https://amazon.com/s?k=baby+products']

    rules = (

        Rule(

            LinkExtractor(

                restrict_css='.s-pagination-strip'

            ),

            callback='parse_item',

            follow=True),

        )

    def parse_item(self, response):

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

        products = soup.select('div[data-component-type="s-search-result"]')

        data = []

        for product in products:

            parsed_product = self.parse_product(product)

            if (parsed_product != 'error'):

                data.append(parsed_product)

        return {

            'url': response.url,

            'data': data

        }

    def parse_product(self, product):

        try:

            link = product.select_one('a.a-text-normal')

            price = product.select_one('span.a-price > span.a-offscreen').text

            return {

                'product_url': link['href'],

                'name': link.text,

                'price': price

            }

        except:

            return 'error'

Um den Crawler zu starten, kannst du folgenden Befehl ausführen:

$ scrapy crawl baby_products

In der Konsole werden zahlreiche Logs angezeigt (Sie können eine Logdatei mit `--logfile [log_file_name]` angeben).

Ich habe Amazon Search als Beispiel verwendet, um die Grundlagen der Erstellung eines Web-Crawlers in Python zu veranschaulichen. Der Crawler findet jedoch nicht viele Links, denen er folgen kann, und ist nicht auf einen bestimmten Anwendungsfall für die Daten zugeschnitten. Wenn Sie bestimmte Daten aus Amazon Search extrahieren möchten, können Sie die Nutzung unserer Amazon Product Data API in Betracht ziehen. Wir haben benutzerdefinierte Parser für Amazon Search, Produkt- und Kategorieseiten erstellt, die Daten im JSON-Format zurückgeben, die direkt in Ihrer Anwendung verwendet werden können.

Warum ist es besser, einen professionellen Scraping-Dienst zu nutzen, als einen Crawler?

Web-Crawling kann zwar ein nützliches Werkzeug zum Extrahieren von Daten aus dem Internet sein, die Einrichtung kann jedoch zeitaufwändig und komplex sein. Darüber hinaus kann Web-Scraping gegen die Nutzungsbedingungen einiger Websites verstoßen und dazu führen, dass Ihre IP-Adresse gesperrt wird oder sogar rechtliche Schritte gegen Sie eingeleitet werden.

Professionelle Scraping-Dienste hingegen nutzen fortschrittliche Techniken und Technologien, um Anti-Scraping-Maßnahmen zu umgehen und Daten zu extrahieren, ohne entdeckt zu werden. Sie kümmern sich zudem um die Wartung und Skalierung der Scraping-Infrastruktur, sodass Sie sich auf die Analyse und Nutzung der Daten konzentrieren können. Darüber hinaus bieten sie ein höheres Maß an Datengenauigkeit und -vollständigkeit, da sie komplexere Anwendungsfälle der Datenextraktion bewältigen und groß angelegte Scraping-Aufträge abwickeln können.

Zusammenfassung

Zusammenfassend lässt sich sagen, dass Web-Crawling zwar ein nützliches Werkzeug zur Datenextraktion aus dem Internet sein kann, dessen Einrichtung jedoch zeitaufwändig und komplex sein kann. Zudem kann Web-Crawling gegen die Nutzungsbedingungen einiger Websites verstoßen und dazu führen, dass Ihre IP-Adresse gesperrt wird oder sogar rechtliche Schritte gegen Sie eingeleitet werden. Daher ist es für anspruchsvollere und groß angelegte Scraping-Aufträge besser, einen professionellen Scraping-Dienst zu nutzen.

Wenn Sie nach einer Alternative zum eigenständigen Crawling suchen, sollten Sie WebScrapingAPI in Betracht ziehen. WebScrapingAPI ist ein professioneller Web-Scraping-Dienst, mit dem Sie ganz einfach Daten von Websites extrahieren können, ohne einen eigenen Web-Scraper erstellen und warten zu müssen.

Es ist eine schnelle, zuverlässige und kostengünstige Lösung, die für Unternehmen jeder Größe geeignet ist.

Probieren Sie es doch noch heute aus! Es ist kostenlos und wir bieten eine 14-tägige Testphase an, für die keine Kreditkarte erforderlich ist.

Über den Autor
Ștefan Răcilă, Full-Stack-Entwickler @ WebScrapingAPI
Ștefan RăcilăFull-Stack-Entwickler

Stefan Racila ist DevOps- und Full-Stack-Entwickler bei WebScrapingAPI, wo er Produktfunktionen entwickelt und die Infrastruktur wartet, die für die Zuverlässigkeit der Plattform sorgt.

Los geht’s

Sind Sie bereit, Ihre Datenerfassung zu erweitern?

Schließen Sie sich den über 2.000 Unternehmen an, die WebScrapingAPI nutzen, um Webdaten im Unternehmensmaßstab ohne zusätzlichen Infrastrukturaufwand zu extrahieren.