Crawl4AI упрощает асинхронное сканирование веб-страниц и извлечение данных, делая их доступными для больших языковых моделей (LLM) и приложений искусственного интеллекта. ?
CrawlResult
.srcset
, picture
и адаптивных изображений.file://
и необработанный HTML ( raw:
) напрямую.Поиграйтесь с этим
Посетите наш сайт документации
Crawl4AI предлагает гибкие варианты установки для различных случаев использования. Вы можете установить его как пакет Python или использовать Docker.
Выберите вариант установки, который лучше всего соответствует вашим потребностям:
Для выполнения основных задач веб-сканирования и парсинга:
pip install crawl4ai
По умолчанию будет установлена асинхронная версия Crawl4AI, использующая Playwright для сканирования веб-страниц.
Примечание. При установке Crawl4AI сценарий установки должен автоматически установить и настроить Playwright. Однако если вы обнаружите какие-либо ошибки, связанные с Playwright, вы можете установить его вручную, используя один из этих методов:
Через командную строку:
playwright install
Если приведенное выше не работает, попробуйте эту более конкретную команду:
python -m playwright install chromium
Второй метод в некоторых случаях оказался более надежным.
Если вам нужна синхронная версия с использованием Selenium:
pip install crawl4ai[sync]
Для участников, которые планируют изменить исходный код:
git clone https://github.com/unclecode/crawl4ai.git
cd crawl4ai
pip install -e .
Разверните свой собственный экземпляр Crawl4AI одним щелчком мыши:
Рекомендуемые характеристики : минимум 4 ГБ ОЗУ. Для стабильной работы при развертывании выберите «professional-xs» или выше.
Развертывание будет:
Crawl4AI доступен в виде образов Docker для простого развертывания. Вы можете либо извлечь данные непосредственно из Docker Hub (рекомендуется), либо выполнить сборку из репозитория.
# 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
Быстрый тест (работает для обоих вариантов):
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 } " )
Дополнительные настройки, переменные среды и примеры использования см. в нашем Руководстве по развертыванию 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 ())
JsonCssExtractionStrategy
позволяет точно извлекать структурированные данные с веб-страниц с помощью селекторов 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 ())
Более сложные примеры использования можно найти в разделе «Примеры» документации.
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 превосходно справляется со сложными сценариями, такими как сканирование нескольких страниц с динамическим контентом, загружаемым через JavaScript. Вот пример сканирования коммитов GitHub на нескольких страницах:
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 ())
Этот пример демонстрирует способность Crawl4AI обрабатывать сложные сценарии, в которых контент загружается асинхронно. Он сканирует несколько страниц коммитов GitHub, выполняет JavaScript для загрузки нового контента и использует специальные перехватчики, чтобы гарантировать загрузку данных перед продолжением.
Более сложные примеры использования можно найти в разделе «Примеры» документации.
Crawl4AI разработан с упором на скорость. Наша цель — обеспечить максимально быстрый ответ с помощью высококачественного извлечения данных, минимизируя абстракции между данными и пользователем.
Мы провели сравнение скорости Crawl4AI и платного сервиса Firecrawl. Результаты демонстрируют превосходную производительность 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
Как видите, Crawl4AI значительно превосходит Firecrawl:
Полный код сравнения можно найти в нашем репозитории по адресу docs/examples/crawl4ai_vs_firecrawl.py
.
Подробную документацию, включая инструкции по установке, расширенные функции и справочник по API, можно найти на нашем веб-сайте документации.
Подробную информацию о наших планах развития и предстоящих функциях можно найти в нашей дорожной карте.
Мы приветствуем вклад сообщества открытого исходного кода. Ознакомьтесь с нашими правилами внесения взносов для получения дополнительной информации.
Crawl4AI выпускается под лицензией Apache 2.0.
С вопросами, предложениями или отзывами обращайтесь:
Приятного сканирования! ?️
Наша миссия — раскрыть неиспользованный потенциал личных и корпоративных данных в эпоху цифровых технологий. В современном мире отдельные лица и организации создают огромное количество ценных цифровых следов, однако эти данные по большей части остаются некапитализированными и не являются настоящим активом.
Наше решение с открытым исходным кодом дает разработчикам и новаторам возможность создавать инструменты для извлечения и структурирования данных, закладывая основу для новой эры владения данными. Преобразуя личные и корпоративные данные в структурированные, торгуемые активы, мы создаем возможности для отдельных лиц извлечь выгоду из своего цифрового следа, а для организаций — раскрыть ценность своих коллективных знаний.
Такая демократизация данных представляет собой первый шаг к общей экономике данных, где добровольное участие в обмене данными способствует развитию ИИ, обеспечивая при этом возврат выгод создателям данных. Благодаря этому подходу мы строим будущее, в котором развитие ИИ будет основано на подлинных человеческих знаниях, а не на синтетических альтернативах.
Для подробного изучения нашего видения, возможностей и дальнейших действий, пожалуйста, ознакомьтесь с полным описанием нашей миссии.
Подробное описание нашего видения, проблем и решений можно найти в полном заявлении о миссии.