Was ist Scrapling?

Scrapling ist ein adaptives Python-Web-Scraping-Framework, entwickelt vom Entwickler D4Vinci. Es hat 2026 auf GitHub Trending schnell an Popularität gewonnen und über 57.000 Sterne erhalten, was es zu einem Vertreter der neuen Generation von Crawler-Tools macht.

Warum braucht man Scrapling?

Traditionelle Crawler-Frameworks (wie Scrapy, BeautifulSoup) stehen vor drei großen Schmerzpunkten:

  1. Code-Ausfall bei Website-Strukturänderungen: CSS-Selektoren oder XPath brechen sofort zusammen, sobald die Seite überarbeitet wird.
  2. Blockierung durch Anti-Bot-Systeme: Schutzmaßnahmen wie Cloudflare Turnstile oder Akamai lassen normale Anfragen direkt mit einem 403-Fehler zurückkommen.
  3. Schlechte Skalierbarkeit: Vom kleinen Datenabruf bis zum groß angelegten parallelen Crawling muss viel Code neu geschrieben werden.

Das Kerndesign-Prinzip von Scrapling lautet "One library, zero compromises" (Eine Bibliothek, keine Kompromisse):

  • Adaptiver Parser: Lernt die Website-Struktur automatisch und lokalisiert Elemente nach Updates selbstständig neu.
  • Integriertes Anti-Blocking: Funktioniert sofort out-of-the-box und umgeht Cloudflare Turnstile und andere gängige Schutzmaßnahmen.
  • Scrapy-ähnliche API: Entwickler, die mit Scrapy vertraut sind, können nahtlos wechseln.
  • Von der Einzelanfrage bis zum Voll-Crawl: Dieselbe API unterstützt sowohl einfaches Scraping als auch groß angelegtes paralleles Crawling.

Scrapling vs. traditionelle Crawler-Tools

Feature BeautifulSoup Scrapy Scrapling
Lernkurve Niedrig Mittel Mittel
Adaptives Parsing ❌ ❌ ✅
Cloudflare-Umgehung ❌ Benötigt Plugin ✅ Integriert
Paralleles Crawling ❌ ✅ ✅
Unterstützung dynamischer Seiten ❌ Benötigt Middleware ✅ Integriertes Playwright
Pause/Fortsetzen ❌ Benötigt Erweiterung ✅ Integriert
Streaming-Ausgabe ❌ ❌ ✅

Installation von Scrapling

Systemvoraussetzungen

  • Python 3.8+
  • pip Paketmanager

Schnelle Installation

BASH
pip install scrapling

Installation überprüfen

PYTHON
from scrapling.fetchers import Fetcher

# Grundlegende Funktionen testen
p = Fetcher.fetch('https://example.com')
print(p.title)  # Gibt den Seitentitel aus

Optionale Abhängigkeiten

Wenn du dynamisches Rendering (JavaScript-Websites) benötigst, musst du Playwright installieren:

BASH
pip install playwright
playwright install chromium

Schnellstart: Dein erster Crawler

Beispiel 1: Einfaches Page-Scraping

Beginnen wir mit einem einfachen Beispiel – wir holen uns die Top-News von Hacker News.

PYTHON
from scrapling.fetchers import Fetcher

# HTTP-Anfrage senden
page = Fetcher.fetch('https://news.ycombinator.com/')

# Daten mit CSS-Selektoren extrahieren
stories = page.css('.titleline > a')

for story in stories[:5]:  # Nur die ersten 5 nehmen
    title = story.text
    link = story.attrs.get('href', '')
    print(f"Titel: {title}")
    print(f"Link: {link}")
    print("-" * 40)

Beispielausgabe:

Titel: Show HN: Ich habe ein Tool für Echtzeit-Code-Zusammenarbeit gebaut
Link: https://github.com/example/collab-tool
----------------------------------------
Titel: Ask HN: Was ist deine Lieblings-Python-Bibliothek im Jahr 2026?
Link: https://news.ycombinator.com/item?id=123456
----------------------------------------

Beispiel 2: Adaptives Parsing (Auto-save)

Das Kernfeature von Scrapling ist das adaptive Parsing. Wenn du Daten zum ersten Mal abgreifst, kannst du auto_save=True aktivieren. Scrapling lernt dann die Seitenstruktur und speichert die Merkmale. Wenn die Website später überarbeitet wird, übergibst du einfach adaptive=True, und es findet die Zielelemente automatisch wieder.

PYTHON
from scrapling.fetchers import Fetcher

page = Fetcher.fetch('https://quotes.toscrape.com/')

# Erster Abruf: auto_save aktivieren
quotes = page.css('.quote', auto_save=True)

for quote in quotes[:3]:
    text = quote.css('.text::text').get()
    author = quote.css('.author::text').get()
    print(f"{text} — {author}")

Wenn sich die Website-Struktur ändert:

PYTHON
# Spätere Abrufe: adaptive=True übergeben
page = Fetcher.fetch('https://quotes.toscrape.com/')
quotes = page.css('.quote', adaptive=True)  # Passt sich automatisch der neuen Struktur an!

for quote in quotes[:3]:
    text = quote.css('.text::text').get()
    author = quote.css('.author::text').get()
    print(f"{text} — {author}")

💡 Funktionsweise: Scrapling zeichnet verschiedene Merkmale eines Elements auf (Tag-Typ, benachbarter Text, Attributmuster usw.). Selbst wenn sich CSS-Klassennamen ändern, kann es das Element über andere Merkmale wiederfinden.


Fortgeschrittene Funktionen

1. Cloudflare Turnstile umgehen

Viele Websites nutzen Cloudflare Turnstile oder andere Anti-Bot-Systeme. Der StealthyFetcher von Scrapling kann diese Schutzmaßnahmen automatisch handhaben.

PYTHON
from scrapling.fetchers import StealthyFetcher

# Adaptiven Modus aktivieren
StealthyFetcher.adaptive = True

# Cloudflare automatisch umgehen
page = StealthyFetcher.fetch(
    'https://example-protected-site.com',
    headless=True,       # Headless-Browser-Modus
    network_idle=True    # Warten, bis das Netzwerk inaktiv ist
)

# Daten normal extrahieren
products = page.css('.product-item')
for product in products:
    name = product.css('.name::text').get()
    price = product.css('.price::text').get()
    print(f"{name}: {price}")

Erklärung der wichtigsten Parameter: - headless=True: Verwendet einen Headless-Browser, um echtes Nutzerverhalten zu simulieren. - network_idle=True: Wartet, bis alle Netzwerkanfragen abgeschlossen sind, bevor extrahiert wird (ideal für SPA-Anwendungen). - adaptive=True: Aktiviert das adaptive Parsing.

2. Dynamisches Seiten-Rendering (Playwright)

Für Websites, die JavaScript-Rendering benötigen, verwende den DynamicFetcher.

PYTHON
from scrapling.fetchers import DynamicFetcher

page = DynamicFetcher.fetch(
    'https://spa-example.com',
    wait_for='.content-loaded',  # Warten, bis ein bestimmtes Element erscheint
    timeout=30000                # Timeout-Zeit (Millisekunden)
)

# Dynamisch geladene Inhalte extrahieren
articles = page.css('article')
for article in articles:
    title = article.css('h2::text').get()
    summary = article.css('.summary::text').get()
    print(f"{title}\n{summary}\n")

3. Asynchrones paralleles Scraping

Verwende den AsyncFetcher, um hochparalleles Scraping zu实现.

PYTHON
import asyncio
from scrapling.fetchers import AsyncFetcher

async def fetch_multiple_pages():
    urls = [
        'https://example.com/page/1',
        'https://example.com/page/2',
        'https://example.com/page/3',
        'https://example.com/page/4',
        'https://example.com/page/5',
    ]

    # Anfragen parallel starten
    pages = await AsyncFetcher.fetch_many(urls, concurrency=3)

    for url, page in zip(urls, pages):
        if page:
            title = page.title
            print(f"{url}: {title}")
        else:
            print(f"{url}: Anfrage fehlgeschlagen")

asyncio.run(fetch_multiple_pages())

Spider-Framework: Groß angelegtes Crawling

Scrapling bietet ein Scrapy-ähnliches Spider-Framework, das groß angelegtes paralleles Crawling unterstützt.

Basis-Spider

PYTHON
from scrapling.spiders import Spider, Response

class QuoteSpider(Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com/"]

    async def parse(self, response: Response):
        # Zitate der aktuellen Seite extrahieren
        for quote in response.css('.quote'):
            yield {
                "text": quote.css('.text::text').get(),
                "author": quote.css('.author::text').get(),
                "tags": quote.css('.tag::text').getall()
            }

        # Zur nächsten Seite blättern
        next_page = response.css('.next a::attr(href)').get()
        if next_page:
            yield self.follow(next_page, callback=self.parse)

# Crawler starten
QuoteSpider().start()

Parallelitätskonfiguration

PYTHON
class MultiPageSpider(Spider):
    name = "multi-page"
    start_urls = [f"https://example.com/page/{i}" for i in range(1, 101)]

    # Parallelität konfigurieren
    custom_settings = {
        "concurrency": 5,           # Maximale Parallelität
        "download_delay": 1,        # Download-Verzögerung (Sekunden)
        "robots_txt_obey": True,    # robots.txt beachten
    }

    async def parse(self, response: Response):
        title = response.css('h1::text').get()
        yield {"url": response.url, "title": title}

MultiPageSpider().start()

Pause und Fortsetzen

Scrapling unterstützt checkpoint-basierte Persistenz. Wenn du Strg+C drückst, um elegant zu beenden, wird beim nächsten Start automatisch fortgesetzt.

PYTHON
class LongRunningSpider(Spider):
    name = "long-crawl"
    start_urls = ["https://large-site.com/"]

    custom_settings = {
        "checkpoint_dir": "./checkpoints",  # Checkpoint-Verzeichnis
    }

    async def parse(self, response: Response):
        # Daten extrahieren...
        yield {"data": "..."}

        # Weiter crawlen
        for link in response.css('a::attr(href)').getall():
            yield self.follow(link, callback=self.parse)

LongRunningSpider().start()

Praxisbeispiele

PYTHON
from scrapling.fetchers import Fetcher

def scrape_github_trending():
    page = Fetcher.fetch('https://github.com/trending')

    repos = page.css('.Box-row')

    trending = []
    for repo in repos[:10]:
        name = repo.css('h2 a::text').get('').strip()
        description = repo.css('p.col-9::text').get('').strip()
        stars = repo.css('[href$=stargazers] span::text').get('').strip()
        language = repo.css('[itemprop=programmingLanguage]::text').get('').strip()

        trending.append({
            "name": name,
            "description": description,
            "stars": stars,
            "language": language
        })

    return trending

if __name__ == "__main__":
    results = scrape_github_trending()
    for repo in results:
        print(f"📦 {repo['name']}")
        print(f"   {repo['description'][:80]}...")
        print(f"   ⭐ {repo['stars']} | 📝 {repo['language']}")
        print()

Fall 2: E-Commerce-Preisüberwachung

PYTHON
from scrapling.fetchers import StealthyFetcher
import json
from datetime import datetime

def monitor_prices():
    urls = [
        "https://amazon.com/dp/B08N5WRWNW",
        "https://amazon.com/dp/B0BSHF7WHW",
        "https://amazon.com/dp/B09G9FPHY6",
    ]

    results = []

    for url in urls:
        page = StealthyFetcher.fetch(url, headless=True)

        title = page.css('#productTitle::text').get('').strip()
        price = page.css('.a-price .a-offscreen::text').get('').strip()

        results.append({
            "url": url,
            "title": title,
            "price": price,
            "timestamp": datetime.now().isoformat()
        })

        print(f"✅ {title[:50]}... - {price}")

    # In JSON speichern
    with open('price_monitor.json', 'w', encoding='utf-8') as f:
        json.dump(results, f, ensure_ascii=False, indent=2)

    print(f"\n📊 {len(results)} Preisdaten in price_monitor.json gespeichert")

if __name__ == "__main__":
    monitor_prices()

Fall 3: Streaming-Ausgabe (Echtzeit-Verarbeitung)

Für lang laufende Crawler kannst du den Streaming-Modus verwenden, um Daten in Echtzeit zu verarbeiten.

PYTHON
from scrapling.spiders import Spider, Response

class StreamingSpider(Spider):
    name = "streaming-demo"
    start_urls = ["https://quotes.toscrape.com/"]

    async def parse(self, response: Response):
        for quote in response.css('.quote'):
            item = {
                "text": quote.css('.text::text').get(),
                "author": quote.css('.author::text').get()
            }
            yield item  # Sofort ausgeben, nicht auf Fertigstellung warten

        next_page = response.css('.next a::attr(href)').get()
        if next_page:
            yield self.follow(next_page, callback=self.parse)

# Streaming-Konsum
async def main():
    spider = StreamingSpider()

    async for item in spider.stream():
        # Jedes Item in Echtzeit verarbeiten
        print(f"Empfangen: {item['text'][:50]}... von {item['author']}")
        # Kann sofort in Datenbank gespeichert oder an Message Queue gesendet werden

import asyncio
asyncio.run(main())

Fortgeschrittene Tipps

1. Proxy-Rotation

PYTHON
from scrapling.spiders import Spider, Response

class ProxySpider(Spider):
    name = "proxy-spider"
    start_urls = ["https://httpbin.org/ip"]

    custom_settings = {
        "proxy_list": [
            "http://proxy1.example.com:8080",
            "http://proxy2.example.com:8080",
            "http://proxy3.example.com:8080",
        ],
        "proxy_rotation": "per_request",  # Proxy bei jeder Anfrage rotieren
    }

    async def parse(self, response: Response):
        ip = response.json().get('origin')
        print(f"Aktuelle IP: {ip}")

2. Benutzerdefinierte Export-Pipelines

PYTHON
from scrapling.spiders import Spider, Response
import csv

class CSVS pider(Spider):
    name = "csv-export"
    start_urls = ["https://quotes.toscrape.com/"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.csv_file = open('quotes.csv', 'w', newline='', encoding='utf-8')
        self.writer = csv.writer(self.csv_file)
        self.writer.writerow(['Text', 'Autor', 'Tags'])

    async def parse(self, response: Response):
        for quote in response.css('.quote'):
            text = quote.css('.text::text').get()
            author = quote.css('.author::text').get()
            tags = ', '.join(quote.css('.tag::text').getall())

            self.writer.writerow([text, author, tags])

        next_page = response.css('.next a::attr(href)').get()
        if next_page:
            yield self.follow(next_page, callback=self.parse)

    def close(self, reason):
        self.csv_file.close()
        print(f"✅ Daten in quotes.csv gespeichert")

3. Entwicklungsmodus (Response-Caching)

Beim Debuggen von Parsing-Logik solltest du vermeiden, den Server wiederholt anzufordern.

PYTHON
from scrapling.spiders import Spider, Response

class DevSpider(Spider):
    name = "dev-mode"
    start_urls = ["https://example.com"]

    custom_settings = {
        "dev_mode": True,              # Entwicklungsmodus aktivieren
        "cache_dir": "./http_cache",   # Cache-Verzeichnis
    }

    async def parse(self, response: Response):
        # Beim ersten Lauf: Response auf der Festplatte cachen
        # Bei späteren Läufen: Direkt von der Festplatte lesen, keine Netzwerkanfrage nötig
        title = response.css('h1::text').get()
        yield {"title": title}

Häufig gestellte Fragen

F1: Was ist der Unterschied zwischen Scrapling und Scrapy?

A: Scrapling kann als moderne, erweiterte Version von Scrapy betrachtet werden: - Adaptives Parsing: Scrapy-Selektoren versagen bei Seitenüberarbeitungen, Scrapling passt sich automatisch an. - Integriertes Anti-Blocking: Scrapy benötigt zusätzliche Middleware, um Cloudflare zu umgehen, Scrapling funktioniert out-of-the-box. - Übersichtlichere API: Die Fetcher-API von Scrapling ist besser für kleines, schnelles Scraping geeignet.

Wenn du bereits mit Scrapy vertraut bist, ist der Wechsel zu Scrapling fast ohne Lernaufwand möglich.

F2: Wie gehe ich mit Seiten nach dem Login um?

A: Verwende StealthyFetcher oder DynamicFetcher, um den Login zu simulieren:

PYTHON
from scrapling.fetchers import DynamicFetcher

page = DynamicFetcher.fetch(
    'https://example.com/login',
    headless=True,
    wait_for='#dashboard'  # Warten, bis nach dem Login weitergeleitet wird
)

# Login durchführen (über Playwright)
page.page.fill('#username', 'dein_benutzername')
page.page.fill('#password', 'dein_passwort')
page.page.click('#login-button')
page.page.wait_for_selector('#dashboard')

# Jetzt können Inhalte nach dem Login gescrapt werden
data = page.css('.private-data::text').getall()

F3: Wie begrenze ich die Crawling-Geschwindigkeit, um Blockierungen zu vermeiden?

A: Konfiguriere Download-Verzögerungen und Parallelitätslimits im Spider:

PYTHON
class PoliteSpider(Spider):
    custom_settings = {
        "concurrency": 2,           # Parallelität reduzieren
        "download_delay": 2,        # 2 Sekunden Intervall zwischen jeder Anfrage
        "robots_txt_obey": True,    # robots.txt beachten
    }

F4: Welche Selektoren unterstützt Scrapling?

A: Es unterstützt CSS-Selektoren und XPath:

PYTHON
# CSS-Selektoren
page.css('.class-name::text').get()
page.css('#id-name').getall()

# XPath
page.xpath('//div[@class="example"]/text()').get()

Zusammenfassung

Scrapling ist das Python-Web-Scraping-Framework, auf das man 2026 am meisten achten sollte. Es kombiniert adaptives Parsing, Anti-Blocking-Fähigkeiten und eine Scrapy-ähnliche API perfekt, sodass Entwickler mit minimalem Code die stabilsten Crawler implementieren können.

Rückblick auf die Kernvorteile: - ✅ Adaptiver Parser: Lokalisiert Elemente nach Seitenüberarbeitungen automatisch neu - ✅ Integriertes Anti-Blocking: Umgeht Cloudflare Turnstile out-of-the-box - ✅ Von der Einzelanfrage bis zum Voll-Crawl: Dieselbe API deckt alle Szenarien ab - ✅ Parallelität, Pause/Fortsetzen, Streaming-Ausgabe: Produktionsreife Features rundum vorhanden

Ressourcen-Links: - GitHub-Repository - Offizielle Dokumentation - Discord-Community

Wenn dir dieser Artikel geholfen hat, teile ihn gerne mit anderen Entwicklern!