Crawl4AI vereinfacht das asynchrone Web-Crawling und die Datenextraktion und macht es für große Sprachmodelle (LLMs) und KI-Anwendungen zugänglich. ?
CrawlResult
.srcset
, picture
und responsive Bild.file://
Pfade und Roh-HTML ( raw:
:) direkt.Spielen Sie damit herum
Besuchen Sie unsere Dokumentations-Website
Crawl4AI bietet flexible Installationsoptionen für verschiedene Anwendungsfälle. Sie können es als Python-Paket installieren oder Docker verwenden.
Wählen Sie die Installationsoption, die Ihren Anforderungen am besten entspricht:
Für grundlegende Web-Crawling- und Scraping-Aufgaben:
pip install crawl4ai
Standardmäßig wird dadurch die asynchrone Version von Crawl4AI installiert und Playwright für das Web-Crawling verwendet.
Hinweis: Wenn Sie Crawl4AI installieren, sollte das Setup-Skript Playwright automatisch installieren und einrichten. Wenn Sie jedoch auf Fehler im Zusammenhang mit Playwright stoßen, können Sie es mit einer der folgenden Methoden manuell installieren:
Über die Befehlszeile:
playwright install
Wenn das oben Gesagte nicht funktioniert, versuchen Sie es mit diesem spezifischeren Befehl:
python -m playwright install chromium
Diese zweite Methode hat sich in einigen Fällen als zuverlässiger erwiesen.
Wenn Sie die synchrone Version mit Selenium benötigen:
pip install crawl4ai[sync]
Für Mitwirkende, die den Quellcode ändern möchten:
git clone https://github.com/unclecode/crawl4ai.git
cd crawl4ai
pip install -e .
Stellen Sie Ihre eigene Instanz von Crawl4AI mit einem Klick bereit:
Empfohlene Spezifikationen : mindestens 4 GB RAM. Wählen Sie bei der Bereitstellung für einen stabilen Betrieb „professional-xs“ oder höher aus.
Die Bereitstellung wird:
Crawl4AI ist zur einfachen Bereitstellung als Docker-Images verfügbar. Sie können entweder direkt vom Docker Hub ziehen (empfohlen) oder aus dem Repository erstellen.
# Pull and run from Docker Hub (choose one):
docker pull unclecode/crawl4ai:basic # Basic crawling features
docker pull unclecode/crawl4ai:all # Full installation (ML, LLM support)
docker pull unclecode/crawl4ai:gpu # GPU-enabled version
# Run the container
docker run -p 11235:11235 unclecode/crawl4ai:basic # Replace 'basic' with your chosen version
# In case you want to set platform to arm64
docker run --platform linux/arm64 -p 11235:11235 unclecode/crawl4ai:basic
# In case to allocate more shared memory for the container
docker run --shm-size=2gb -p 11235:11235 unclecode/crawl4ai:basic
# Clone the repository
git clone https://github.com/unclecode/crawl4ai.git
cd crawl4ai
# Build the image
docker build -t crawl4ai:local
--build-arg INSTALL_TYPE=basic # Options: basic, all
.
# In case you want to set platform to arm64
docker build -t crawl4ai:local
--build-arg INSTALL_TYPE=basic # Options: basic, all
--platform linux/arm64
.
# Run your local build
docker run -p 11235:11235 crawl4ai:local
Schnelltest (funktioniert für beide Optionen):
import requests
# Submit a crawl job
response = requests . post (
"http://localhost:11235/crawl" ,
json = { "urls" : "https://example.com" , "priority" : 10 }
)
task_id = response . json ()[ "task_id" ]
# Get results
result = requests . get ( f"http://localhost:11235/task/ { task_id } " )
Weitere Informationen zu erweiterten Konfigurationen, Umgebungsvariablen und Verwendungsbeispielen finden Sie in unserem Docker-Bereitstellungshandbuch.
import asyncio
from crawl4ai import AsyncWebCrawler
async def main ():
async with AsyncWebCrawler ( verbose = True ) as crawler :
result = await crawler . arun ( url = "https://www.nbcnews.com/business" )
print ( result . markdown )
if __name__ == "__main__" :
asyncio . run ( main ())
import asyncio
from crawl4ai import AsyncWebCrawler
async def main ():
async with AsyncWebCrawler ( verbose = True ) as crawler :
js_code = [ "const loadMoreButton = Array.from(document.querySelectorAll('button')).find(button => button.textContent.includes('Load More')); loadMoreButton && loadMoreButton.click();" ]
result = await crawler . arun (
url = "https://www.nbcnews.com/business" ,
js_code = js_code ,
css_selector = ".wide-tease-item__description" ,
bypass_cache = True
)
print ( result . extracted_content )
if __name__ == "__main__" :
asyncio . run ( main ())
import asyncio
from crawl4ai import AsyncWebCrawler
async def main ():
async with AsyncWebCrawler ( verbose = True , proxy = "http://127.0.0.1:7890" ) as crawler :
result = await crawler . arun (
url = "https://www.nbcnews.com/business" ,
bypass_cache = True
)
print ( result . markdown )
if __name__ == "__main__" :
asyncio . run ( main ())
Die JsonCssExtractionStrategy
ermöglicht die präzise Extraktion strukturierter Daten aus Webseiten mithilfe von CSS-Selektoren.
import asyncio
import json
from crawl4ai import AsyncWebCrawler
from crawl4ai . extraction_strategy import JsonCssExtractionStrategy
async def extract_news_teasers ():
schema = {
"name" : "News Teaser Extractor" ,
"baseSelector" : ".wide-tease-item__wrapper" ,
"fields" : [
{
"name" : "category" ,
"selector" : ".unibrow span[data-testid='unibrow-text']" ,
"type" : "text" ,
},
{
"name" : "headline" ,
"selector" : ".wide-tease-item__headline" ,
"type" : "text" ,
},
{
"name" : "summary" ,
"selector" : ".wide-tease-item__description" ,
"type" : "text" ,
},
{
"name" : "time" ,
"selector" : "[data-testid='wide-tease-date']" ,
"type" : "text" ,
},
{
"name" : "image" ,
"type" : "nested" ,
"selector" : "picture.teasePicture img" ,
"fields" : [
{ "name" : "src" , "type" : "attribute" , "attribute" : "src" },
{ "name" : "alt" , "type" : "attribute" , "attribute" : "alt" },
],
},
{
"name" : "link" ,
"selector" : "a[href]" ,
"type" : "attribute" ,
"attribute" : "href" ,
},
],
}
extraction_strategy = JsonCssExtractionStrategy ( schema , verbose = True )
async with AsyncWebCrawler ( verbose = True ) as crawler :
result = await crawler . arun (
url = "https://www.nbcnews.com/business" ,
extraction_strategy = extraction_strategy ,
bypass_cache = True ,
)
assert result . success , "Failed to crawl the page"
news_teasers = json . loads ( result . extracted_content )
print ( f"Successfully extracted { len ( news_teasers ) } news teasers" )
print ( json . dumps ( news_teasers [ 0 ], indent = 2 ))
if __name__ == "__main__" :
asyncio . run ( extract_news_teasers ())
Weitere Anwendungsbeispiele für Fortgeschrittene finden Sie in unserem Abschnitt „Beispiele“ in der Dokumentation.
import os
import asyncio
from crawl4ai import AsyncWebCrawler
from crawl4ai . extraction_strategy import LLMExtractionStrategy
from pydantic import BaseModel , Field
class OpenAIModelFee ( BaseModel ):
model_name : str = Field (..., description = "Name of the OpenAI model." )
input_fee : str = Field (..., description = "Fee for input token for the OpenAI model." )
output_fee : str = Field (..., description = "Fee for output token for the OpenAI model." )
async def main ():
async with AsyncWebCrawler ( verbose = True ) as crawler :
result = await crawler . arun (
url = 'https://openai.com/api/pricing/' ,
word_count_threshold = 1 ,
extraction_strategy = LLMExtractionStrategy (
provider = "openai/gpt-4o" , api_token = os . getenv ( 'OPENAI_API_KEY' ),
schema = OpenAIModelFee . schema (),
extraction_type = "schema" ,
instruction = """From the crawled content, extract all mentioned model names along with their fees for input and output tokens.
Do not miss any models in the entire content. One extracted model JSON format should look like this:
{"model_name": "GPT-4", "input_fee": "US$10.00 / 1M tokens", "output_fee": "US$30.00 / 1M tokens"}."""
),
bypass_cache = True ,
)
print ( result . extracted_content )
if __name__ == "__main__" :
asyncio . run ( main ())
Crawl4AI zeichnet sich durch die Bewältigung komplexer Szenarien aus, wie z. B. das Crawlen mehrerer Seiten mit dynamischen Inhalten, die über JavaScript geladen werden. Hier ist ein Beispiel für das Crawlen von GitHub-Commits über mehrere Seiten:
import asyncio
import re
from bs4 import BeautifulSoup
from crawl4ai import AsyncWebCrawler
async def crawl_typescript_commits ():
first_commit = ""
async def on_execution_started ( page ):
nonlocal first_commit
try :
while True :
await page . wait_for_selector ( 'li.Box-sc-g0xbh4-0 h4' )
commit = await page . query_selector ( 'li.Box-sc-g0xbh4-0 h4' )
commit = await commit . evaluate ( '(element) => element.textContent' )
commit = re . sub ( r's+' , '' , commit )
if commit and commit != first_commit :
first_commit = commit
break
await asyncio . sleep ( 0.5 )
except Exception as e :
print ( f"Warning: New content didn't appear after JavaScript execution: { e } " )
async with AsyncWebCrawler ( verbose = True ) as crawler :
crawler . crawler_strategy . set_hook ( 'on_execution_started' , on_execution_started )
url = "https://github.com/microsoft/TypeScript/commits/main"
session_id = "typescript_commits_session"
all_commits = []
js_next_page = """
const button = document.querySelector('a[data-testid="pagination-next-button"]');
if (button) button.click();
"""
for page in range ( 3 ): # Crawl 3 pages
result = await crawler . arun (
url = url ,
session_id = session_id ,
css_selector = "li.Box-sc-g0xbh4-0" ,
js = js_next_page if page > 0 else None ,
bypass_cache = True ,
js_only = page > 0
)
assert result . success , f"Failed to crawl page { page + 1 } "
soup = BeautifulSoup ( result . cleaned_html , 'html.parser' )
commits = soup . select ( "li" )
all_commits . extend ( commits )
print ( f"Page { page + 1 } : Found { len ( commits ) } commits" )
await crawler . crawler_strategy . kill_session ( session_id )
print ( f"Successfully crawled { len ( all_commits ) } commits across 3 pages" )
if __name__ == "__main__" :
asyncio . run ( crawl_typescript_commits ())
Dieses Beispiel demonstriert die Fähigkeit von Crawl4AI, komplexe Szenarien zu bewältigen, in denen Inhalte asynchron geladen werden. Es durchsucht mehrere Seiten von GitHub-Commits, führt JavaScript aus, um neue Inhalte zu laden, und verwendet benutzerdefinierte Hooks, um sicherzustellen, dass Daten geladen werden, bevor fortgefahren wird.
Weitere Anwendungsbeispiele für Fortgeschrittene finden Sie in unserem Abschnitt „Beispiele“ in der Dokumentation.
Bei der Entwicklung von Crawl4AI steht Geschwindigkeit im Vordergrund. Unser Ziel ist es, die schnellstmögliche Antwort mit hochwertiger Datenextraktion zu liefern und Abstraktionen zwischen den Daten und dem Benutzer zu minimieren.
Wir haben einen Geschwindigkeitsvergleich zwischen Crawl4AI und Firecrawl, einem kostenpflichtigen Dienst, durchgeführt. Die Ergebnisse belegen die überlegene Leistung von Crawl4AI:
Firecrawl:
Time taken: 7.02 seconds
Content length: 42074 characters
Images found: 49
Crawl4AI (simple crawl):
Time taken: 1.60 seconds
Content length: 18238 characters
Images found: 49
Crawl4AI (with JavaScript execution):
Time taken: 4.64 seconds
Content length: 40869 characters
Images found: 89
Wie Sie sehen können, übertrifft Crawl4AI Firecrawl deutlich:
Den vollständigen Vergleichscode finden Sie in unserem Repository unter docs/examples/crawl4ai_vs_firecrawl.py
.
Eine ausführliche Dokumentation, einschließlich Installationsanweisungen, erweiterten Funktionen und API-Referenzen, finden Sie auf unserer Dokumentations-Website.
Ausführliche Informationen zu unseren Entwicklungsplänen und kommenden Funktionen finden Sie in unserer Roadmap.
Wir freuen uns über Beiträge aus der Open-Source-Community. Weitere Informationen finden Sie in unseren Beitragsrichtlinien.
Crawl4AI wird unter der Apache 2.0-Lizenz veröffentlicht.
Bei Fragen, Anregungen oder Feedback wenden Sie sich bitte an:
Viel Spaß beim Krabbeln! ?️
Unsere Mission ist es, das ungenutzte Potenzial persönlicher und Unternehmensdaten im digitalen Zeitalter zu erschließen. In der heutigen Welt erzeugen Einzelpersonen und Organisationen große Mengen wertvoller digitaler Fußabdrücke, doch diese Daten bleiben als echter Vermögenswert weitgehend ungenutzt.
Unsere Open-Source-Lösung ermöglicht Entwicklern und Innovatoren die Entwicklung von Tools zur Datenextraktion und -strukturierung und legt damit den Grundstein für eine neue Ära des Dateneigentums. Indem wir persönliche und Unternehmensdaten in strukturierte, handelbare Vermögenswerte umwandeln, schaffen wir Möglichkeiten für Einzelpersonen, ihre digitalen Fußabdrücke zu nutzen, und für Organisationen, den Wert ihres kollektiven Wissens zu erschließen.
Diese Demokratisierung von Daten stellt den ersten Schritt in Richtung einer gemeinsamen Datenökonomie dar, in der die freiwillige Teilnahme am Datenaustausch die Weiterentwicklung der KI vorantreibt und gleichzeitig sicherstellt, dass die Vorteile an die Datenersteller zurückfließen. Mit diesem Ansatz bauen wir eine Zukunft auf, in der die KI-Entwicklung auf authentischem menschlichem Wissen und nicht auf synthetischen Alternativen basiert.
Eine detaillierte Darstellung unserer Vision, unserer Chancen und unseres weiteren Wegs finden Sie in unserem vollständigen Leitbild.
Eine detaillierte Darstellung unserer Vision, Herausforderungen und Lösungen finden Sie in unserem vollständigen Leitbild.