Crawl4AI는 비동기식 웹 크롤링 및 데이터 추출을 단순화하여 LLM(대형 언어 모델) 및 AI 애플리케이션에 액세스할 수 있도록 합니다. ?
CrawlResult
내에서 통합된 파일 크롤링, 다운로드 및 추적.srcset
, picture
및 반응형 이미지 형식을 지원합니다.file://
경로 및 원시 HTML( raw:
)을 직접 크롤링합니다.이것저것 가지고 놀아보세요
문서 웹사이트 방문
Crawl4AI는 다양한 사용 사례에 적합한 유연한 설치 옵션을 제공합니다. Python 패키지로 설치하거나 Docker를 사용할 수 있습니다.
귀하의 필요에 가장 적합한 설치 옵션을 선택하십시오:
기본적인 웹 크롤링 및 스크래핑 작업의 경우:
pip install crawl4ai
기본적으로 웹 크롤링을 위해 Playwright를 사용하여 Crawl4AI의 비동기 버전을 설치합니다.
참고: 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의 자체 인스턴스를 배포하십시오.
권장 사양 : 최소 4GB RAM. 안정적인 운영을 위해 배포 시 "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 라이센스에 따라 출시됩니다.
질문, 제안 또는 피드백이 있는 경우 언제든지 다음 연락처로 문의하세요.
즐거운 크롤링을 즐기세요! ?️
우리의 임무는 디지털 시대에 개인 및 기업 데이터의 아직 개발되지 않은 잠재력을 활용하는 것입니다. 오늘날의 세계에서 개인과 조직은 막대한 양의 귀중한 디지털 발자국을 생성하지만 이 데이터는 진정한 자산으로 활용되지 않는 경우가 많습니다.
우리의 오픈 소스 솔루션은 개발자와 혁신가가 데이터 추출 및 구조화를 위한 도구를 구축하여 데이터 소유권의 새로운 시대를 위한 기반을 마련할 수 있도록 지원합니다. 개인 및 기업 데이터를 구조화되고 거래 가능한 자산으로 변환함으로써 개인이 디지털 발자국을 활용하고 조직이 집단 지식의 가치를 실현할 수 있는 기회를 만들고 있습니다.
이러한 데이터의 민주화는 데이터 공유에 대한 자발적인 참여가 AI 발전을 주도하는 동시에 데이터 작성자에게 혜택이 돌아가도록 보장하는 공유 데이터 경제를 향한 첫 번째 단계를 나타냅니다. 이러한 접근 방식을 통해 우리는 AI 개발이 합성 대안이 아닌 진정한 인간 지식을 기반으로 하는 미래를 구축하고 있습니다.
우리의 비전, 기회 및 향후 진로에 대한 자세한 내용은 전체 사명 선언문을 참조하세요.
우리의 비전, 과제 및 솔루션에 대한 자세한 내용을 알아보려면 전체 사명 선언문을 참조하세요.