Crawl4AI simplifie l'exploration Web asynchrone et l'extraction de données, les rendant accessibles aux grands modèles de langage (LLM) et aux applications d'IA. ?
CrawlResult
.srcset
, picture
et responsive.file://
et le HTML brut ( raw:
).Jouez avec ça
Visitez notre site Web de documentation
Crawl4AI propose des options d'installation flexibles pour s'adapter à différents cas d'utilisation. Vous pouvez l'installer en tant que package Python ou utiliser Docker.
Choisissez l'option d'installation qui correspond le mieux à vos besoins :
Pour les tâches de base d’exploration et de scraping Web :
pip install crawl4ai
Par défaut, cela installera la version asynchrone de Crawl4AI, en utilisant Playwright pour l'exploration du Web.
Remarque : lorsque vous installez Crawl4AI, le script d'installation doit automatiquement installer et configurer Playwright. Cependant, si vous rencontrez des erreurs liées à Playwright, vous pouvez l'installer manuellement en utilisant l'une de ces méthodes :
Via la ligne de commande :
playwright install
Si ce qui précède ne fonctionne pas, essayez cette commande plus spécifique :
python -m playwright install chromium
Cette seconde méthode s’est avérée plus fiable dans certains cas.
Si vous avez besoin de la version synchrone utilisant Selenium :
pip install crawl4ai[sync]
Pour les contributeurs qui envisagent de modifier le code source :
git clone https://github.com/unclecode/crawl4ai.git
cd crawl4ai
pip install -e .
Déployez votre propre instance de Crawl4AI en un seul clic :
Spécifications recommandées : 4 Go de RAM minimum. Sélectionnez « professional-xs » ou supérieur lors du déploiement pour un fonctionnement stable.
Le déploiement va :
Crawl4AI est disponible sous forme d'images Docker pour un déploiement facile. Vous pouvez soit extraire directement depuis Docker Hub (recommandé), soit créer à partir du référentiel.
# 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
Test rapide (fonctionne pour les deux options) :
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 } " )
Pour une configuration avancée, des variables d'environnement et des exemples d'utilisation, consultez notre Guide de déploiement Docker.
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 ())
Le JsonCssExtractionStrategy
permet une extraction précise des données structurées des pages Web à l'aide de sélecteurs CSS.
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 ())
Pour des exemples d'utilisation plus avancés, consultez notre section Exemples dans la documentation.
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 excelle dans la gestion de scénarios complexes, tels que l'exploration de plusieurs pages avec du contenu dynamique chargé via JavaScript. Voici un exemple d'exploration des commits GitHub sur plusieurs pages :
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 ())
Cet exemple démontre la capacité de Crawl4AI à gérer des scénarios complexes où le contenu est chargé de manière asynchrone. Il explore plusieurs pages de commits GitHub, exécute JavaScript pour charger du nouveau contenu et utilise des hooks personnalisés pour garantir que les données sont chargées avant de continuer.
Pour des exemples d'utilisation plus avancés, consultez notre section Exemples dans la documentation.
Crawl4AI est conçu avec la vitesse comme objectif principal. Notre objectif est de fournir la réponse la plus rapide possible avec une extraction de données de haute qualité, en minimisant les abstractions entre les données et l'utilisateur.
Nous avons effectué une comparaison de vitesse entre Crawl4AI et Firecrawl, un service payant. Les résultats démontrent les performances supérieures de 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
Comme vous pouvez le constater, Crawl4AI surpasse considérablement Firecrawl :
Vous pouvez trouver le code de comparaison complet dans notre référentiel à l' docs/examples/crawl4ai_vs_firecrawl.py
.
Pour une documentation détaillée, y compris des instructions d'installation, des fonctionnalités avancées et une référence API, visitez notre site Web de documentation.
Pour des informations détaillées sur nos plans de développement et les fonctionnalités à venir, consultez notre feuille de route.
Nous apprécions les contributions de la communauté open source. Consultez nos directives de contribution pour plus d’informations.
Crawl4AI est publié sous la licence Apache 2.0.
Pour des questions, des suggestions ou des commentaires, n'hésitez pas à nous contacter :
Bonne exploration ! ?️
Notre mission est de libérer le potentiel inexploité des données personnelles et d’entreprise à l’ère numérique. Dans le monde d'aujourd'hui, les individus et les organisations génèrent de grandes quantités d'empreintes numériques précieuses, mais ces données restent largement sous-exploitées en tant que véritable atout.
Notre solution open source permet aux développeurs et aux innovateurs de créer des outils d'extraction et de structuration des données, jetant ainsi les bases d'une nouvelle ère de propriété des données. En transformant les données personnelles et d'entreprise en actifs structurés et négociables, nous créons des opportunités permettant aux individus de capitaliser sur leurs empreintes numériques et aux organisations de libérer la valeur de leurs connaissances collectives.
Cette démocratisation des données représente la première étape vers une économie de données partagées, dans laquelle la participation volontaire au partage des données stimule les progrès de l'IA tout en garantissant que les bénéfices reviennent aux créateurs de données. Grâce à cette approche, nous construisons un avenir dans lequel le développement de l’IA s’appuie sur des connaissances humaines authentiques plutôt que sur des alternatives synthétiques.
Pour une exploration détaillée de notre vision, de nos opportunités et de notre voie à suivre, veuillez consulter notre énoncé de mission complet.
Pour une exploration détaillée de notre vision, de nos défis et de nos solutions, veuillez consulter notre énoncé de mission complet.