Crawl4AI๋ #1 ํธ๋ ๋ฉ GitHub ์ ์ฅ์๋ก, ํ๋ฐํ ์ปค๋ฎค๋ํฐ์ ์ํด ์ ์ง๋ณด์๋๋ฉฐ LLM, AI ์์ด์ ํธ ๋ฐ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ์ํ ์ด๊ณ ์ AI-ready ์น ํฌ๋กค๋ง์ ์ ๊ณตํฉ๋๋ค. ์คํ์์ค์ด๋ฉฐ ์ ์ฐํ๊ณ ์ค์๊ฐ ์ฑ๋ฅ์ ์ํด ๊ตฌ์ถ๋ Crawl4AI๋ ๊ฐ๋ฐ์์๊ฒ ํ์ํ ์๋, ์ ํ์ฑ ๋ฐ ๋ฐฐํฌ ํธ์์ฑ์ ์ ๊ณตํฉ๋๋ค.
โจ ์ต์ ์ ๋ฐ์ดํธ v0.6.0 ํ์ธํ๊ธฐ
๐ ๋ฒ์ 0.6.0์ด ์ถ์๋์์ต๋๋ค! ์ด ๋ฆด๋ฆฌ์ค ํ๋ณด์๋ ์ง๋ฆฌ์ ์์น ๋ฐ ๋ก์ผ์ผ ์ค์ ์ ํตํ World-aware ํฌ๋กค๋ง, ํ ์ด๋ธ-ํฌ-๋ฐ์ดํฐํ๋ ์ ์ถ์ถ, ๋ธ๋ผ์ฐ์ ํ๋ง ๋ฐ ์ฌ์ ์๋ฐ, ๋คํธ์ํฌ ๋ฐ ์ฝ์ ํธ๋๏ฟฝ ์บก์ฒ, AI ๋๊ตฌ๋ฅผ ์ํ MCP ํตํฉ, ์์ ํ ๊ฐ์ ๋ Docker ๋ฐฐํฌ๊ฐ ํฌํจ๋ฉ๋๋ค! ๋ฆด๋ฆฌ์ค ๋ ธํธ ์ฝ๊ธฐ โ
์ ์ปดํจํฐ์์ ์ฌ์ ์ ์ด๋ฆฐ ์์ ๋ก ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๋๋ค. ์ปดํจํฐ ๊ณผํ์์ด์ ์๋ฒ์ง๊ฐ ์ ์๊ฒ Amstrad ์ปดํจํฐ๋ฅผ ์๊ฐํด์ฃผ์ จ์ฃ . ๊ทธ ์ด๊ธฐ ์์ ์ ๊ธฐ์ ์ ๋ํ ๋งค๋ ฅ์ ๋ถ๋ฌ์ผ์ผ์ผฐ๊ณ , ๊ฒฐ๊ตญ ์ปดํจํฐ ๊ณผํ์ ์ ๊ณตํ๊ฒ ๋์์ผ๋ฉฐ ๋ํ์ ์์ ์๋ NLP๋ฅผ ์ ๋ฌธํํ์ต๋๋ค. ๊ทธ ๋น์ ์น ํฌ๋กค๋ง์ ์ฒ์ ๋ฐ์ ๋ค์๊ณ , ์ฐ๊ตฌ์๋ค์ด ๋ ผ๋ฌธ์ ์ ๋ฆฌํ๊ณ ์ถํ๋ฌผ์์ ์ ๋ณด๋ฅผ ์ถ์ถํ ์ ์๋๋ก ๋๋ ๋๊ตฌ๋ฅผ ๋ง๋ค์์ต๋๋ค. ๋ฐ์ดํฐ ์ถ์ถ ๊ธฐ์ ์ ์ฐ๋งํ๋ ๋์ ์ ์ด๋ฉด์๋ ๋ณด๋ ์๋ ๊ฒฝํ์ด์์ฃ .
2023๋ ์ผ๋ก ๋์ด์, ์ ๋ ํ๋ก์ ํธ๋ฅผ ์ํ ๋๊ตฌ๋ฅผ ์์ ์ค์ด์๊ณ ์นํ์ด์ง๋ฅผ ๋งํฌ๋ค์ด์ผ๋ก ๋ณํํ ํฌ๋กค๋ฌ๊ฐ ํ์ํ์ต๋๋ค. ํด๊ฒฐ์ฑ ์ ์ฐพ๋ ์ค, ์คํ์์ค๋ผ๊ณ ์ฃผ์ฅํ์ง๋ง ๊ณ์ ์์ฑ๊ณผ API ํ ํฐ ์์ฑ์ด ํ์ํ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค. ๋ ๋์ ๊ฒ์ SaaS ๋ชจ๋ธ๋ก $16์ ์ฒญ๊ตฌํ๊ณ ํ์ง์ด ์ ๊ธฐ์ค์ ๋ฏธ์น์ง ๋ชปํ์ต๋๋ค. ์ข์ ๊ฐ์ ๋๋ผ๋ฉฐ, ์ด๋ ๋ ๊น์ ๋ฌธ์ ์์ ๊นจ๋ฌ์์ต๋๋ค. ๊ทธ ์ข์ ๊ฐ์ ํฐ๋ณด ๋ถ๋ ธ ๋ชจ๋๋ก ๋ฐ๋์๊ณ , ์ ๋ ์ง์ ํด๊ฒฐ์ฑ ์ ๋ง๋ค๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๋จ ๋ฉฐ์น ๋ง์ Crawl4AI๋ฅผ ๋ง๋ค์์ต๋๋ค. ๋๋๊ฒ๋, ์ด ํ๋ก์ ํธ๋ ๊ธ์๋๋ก ํผ์ ธ ์์ฒ ๊ฐ์ GitHub ์คํ๋ฅผ ์ป์ผ๋ฉฐ ๊ธ๋ก๋ฒ ์ปค๋ฎค๋ํฐ์ ๊ณต๊ฐ์ ์ป์์ต๋๋ค.
์ ๋ Crawl4AI๋ฅผ ์คํ์์ค๋ก ๊ณต๊ฐํ ๋ฐ ๋ ๊ฐ์ง ์ด์ ๊ฐ ์์ต๋๋ค. ์ฒซ์งธ, ์ ๊ฒฝ๋ ฅ ์ ๋ฐ์ ๊ฑธ์ณ ์ ๋ฅผ ์ง์ํด์ค ์คํ์์ค ์ปค๋ฎค๋ํฐ์ ๋ณด๋ตํ๋ ๋ฐฉ๋ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋์งธ, ๋ฐ์ดํฐ๋ ๋ชจ๋ ์ฌ๋์ด ์ ๊ทผํ ์ ์์ด์ผ ํ๋ฉฐ, ์ ๋ฃ ๋ฒฝ ๋ค์ ๊ฐํ๊ฑฐ๋ ์์์ ์ํด ๋ ์ ๋์ด์๋ ์ ๋๋ค๊ณ ๋ฏฟ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ์ดํฐ์ ๋ํ ๊ฐ๋ฐฉํ ์ ๊ทผ์ AI์ ๋ฏผ์ฃผํ๋ฅผ ์ํ ๊ธฐ๋ฐ์ ๋ง๋ จํ๋ฉฐ, ๊ฐ์ธ์ด ์์ ์ ๋ชจ๋ธ์ ํ๋ จํ๊ณ ์ ๋ณด์ ์์ ๊ถ์ ๊ฐ์ง ์ ์๋ ๋น์ ์ ์คํํฉ๋๋ค. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด์ ์ ์ธ ์ปค๋ฎค๋ํฐ๊ฐ ํ๋ ฅํ์ฌ ๊ตฌ์ถํ ์ต๊ณ ์ ์คํ์์ค ๋ฐ์ดํฐ ์ถ์ถ ๋ฐ ์์ฑ ๋๊ตฌ๋ฅผ ๋ง๋ค๊ธฐ ์ํ ๋ ํฐ ์ฌ์ ์ ์ฒซ ๊ฑธ์์ ๋๋ค.
์ด ํ๋ก์ ํธ๋ฅผ ์ง์ํ๊ณ ์ฌ์ฉํ๋ฉฐ ํผ๋๋ฐฑ์ ๊ณต์ ํด์ฃผ์ ๋ชจ๋ ๋ถ๋ค๊ป ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ์ฌ๋ฌ๋ถ์ ๊ฒฉ๋ ค๋ ์ ๊ฐ ๋ ํฐ ๊ฟ์ ๊พธ๋๋ก ๋๊ธฐ๋ถ์ฌํฉ๋๋ค. ํจ๊ปํ์ ์ ์ด์๋ฅผ ์ ์ถํ๊ฑฐ๋ PR์ ์ ์ถํ๊ฑฐ๋ ์๋ฌธ์ ํผ๋จ๋ ค์ฃผ์ธ์. ํจ๊ป๋ผ๋ฉด ์ฌ๋๋ค์ด ์์ ์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ณ AI์ ๋ฏธ๋๋ฅผ ์ฌ๊ตฌ์ฑํ ์ ์๋ ์ง์ ํ ๋๊ตฌ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
# Install the package
pip install -U crawl4ai
# For pre release versions
pip install crawl4ai --pre
# Run post-installation setup
crawl4ai-setup
# Verify your installation
crawl4ai-doctor
๋ธ๋ผ์ฐ์ ๊ด๋ จ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด ์๋์ผ๋ก ์ค์นํ ์ ์์ต๋๋ค:
python -m playwright install --with-deps chromium
import asyncio
from crawl4ai import *
async def main():
async with AsyncWebCrawler() as crawler:
result = await crawler.arun(
url="https://www.nbcnews.com/business",
)
print(result.markdown)
if __name__ == "__main__":
asyncio.run(main())
# Basic crawl with markdown output
crwl https://www.nbcnews.com/business -o markdown
# Deep crawl with BFS strategy, max 10 pages
crwl https://docs.crawl4ai.com --deep-crawl bfs --max-pages 10
# Use LLM extraction with a specific question
crwl https://www.example.com/products -q "Extract all product prices"
srcset
๋ฐ picture
์ ๊ฐ์ ๋ฐ์ํ ์ด๋ฏธ์ง ํ์์ ์ถ์ถํฉ๋๋ค.raw:
) ๋๋ ๋ก์ปฌ ํ์ผ(file://
)์ ์ง์ ์ฒ๋ฆฌํฉ๋๋ค.โจ ์์ ์ง์ ์ฒดํํด๋ณด์ธ์.
โจ ๋ฌธ์ ์น์ฌ์ดํธ ๋ฐฉ๋ฌธํ๊ธฐ.
Crawl4AI๋ ๋ค์ํ ์ฌ์ฉ ์ฌ๋ก์ ๋ง์ถฐ ์ ์ฐํ ์ค์น ์ต์ ์ ์ ๊ณตํฉ๋๋ค. Python ํจํค์ง๋ก ์ค์นํ๊ฑฐ๋ Docker๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํ์์ ๋ง๋ ์ค์น ์ต์ ์ ์ ํํ์ธ์:
๊ธฐ๋ณธ์ ์ธ ์น ํฌ๋กค๋ง ๋ฐ ์คํฌ๋ํ ์์ ์ ์ํ:
pip install crawl4ai
crawl4ai-setup # Setup the browser
๊ธฐ๋ณธ์ ์ผ๋ก Playwright๋ฅผ ์ฌ์ฉํ๋ Crawl4AI์ ๋น๋๊ธฐ ๋ฒ์ ์ด ์ค์น๋ฉ๋๋ค.
๐ ์ฐธ๊ณ : Crawl4AI๋ฅผ ์ค์นํ ๋ crawl4ai-setup
์ด ์๋์ผ๋ก 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 . # Basic installation in editable mode
์ ํ์ ๊ธฐ๋ฅ ์ค์น:
pip install -e ".[torch]" # With PyTorch features
pip install -e ".[transformer]" # With Transformer features
pip install -e ".[cosine]" # With cosine similarity features
pip install -e ".[sync]" # With synchronous crawling (Selenium)
pip install -e ".[all]" # Install all optional features
๐ ์ด์ ์ฌ์ฉ ๊ฐ๋ฅ! ์์ ํ ์ฌ์ค๊ณ๋ Docker ๊ตฌํ์ด ๋์ ๋์์ต๋๋ค! ์ด ์๋ก์ด ์๋ฃจ์ ์ ์ด์ ๋ณด๋ค ๋ ํจ์จ์ ์ด๊ณ ์ํํ ๋ฐฐํฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
์๋ก์ด Docker ๊ตฌํ์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค:
# Pull and run the latest release candidate
docker pull unclecode/crawl4ai:0.6.0-rN # Use your favorite revision number
docker run -d -p 11235:11235 --name crawl4ai --shm-size=1g unclecode/crawl4ai:0.6.0-rN # Use your favorite revision number
# Visit the playground at http://localhost:11235/playground
์ ์ฒด ๋ฌธ์๋ Docker ๋ฐฐํฌ ๊ฐ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
๋น ๋ฅธ ํ ์คํธ ์คํ(๋ Docker ์ต์ ๋ชจ๋ ์๋):
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"]
# Continue polling until the task is complete (status="completed")
result = requests.get(f"http://localhost:11235/task/{task_id}")
๋ ๋ง์ ์์ ๋ Docker ์์ ๋ฅผ ์ฐธ์กฐํ์ธ์. ๊ณ ๊ธ ๊ตฌ์ฑ, ํ๊ฒฝ ๋ณ์ ๋ฐ ์ฌ์ฉ ์์ ๋ Docker ๋ฐฐํฌ ๊ฐ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
ํ๋ก์ ํธ ๊ตฌ์กฐ๋ https://github.com/unclecode/crawl4ai/docs/examples ๋๋ ํ ๋ฆฌ์์ ํ์ธํ ์ ์์ต๋๋ค. ๋ค์ํ ์์ ๊ฐ ์์ผ๋ฉฐ, ์ฌ๊ธฐ์๋ ์ผ๋ถ ์ธ๊ธฐ ์๋ ์์ ๋ฅผ ๊ณต์ ํฉ๋๋ค.
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
from crawl4ai.content_filter_strategy import PruningContentFilter, BM25ContentFilter
from crawl4ai.markdown_generation_strategy import DefaultMarkdownGenerator
async def main():
browser_config = BrowserConfig(
headless=True,
verbose=True,
)
run_config = CrawlerRunConfig(
cache_mode=CacheMode.ENABLED,
markdown_generator=DefaultMarkdownGenerator(
content_filter=PruningContentFilter(threshold=0.48, threshold_type="fixed", min_word_threshold=0)
),
# markdown_generator=DefaultMarkdownGenerator(
# content_filter=BM25ContentFilter(user_query="WHEN_WE_FOCUS_BASED_ON_A_USER_QUERY", bm25_threshold=1.0)
# ),
)
async with AsyncWebCrawler(config=browser_config) as crawler:
result = await crawler.arun(
url="https://docs.micronaut.io/4.7.6/guide/",
config=run_config
)
print(len(result.markdown.raw_markdown))
print(len(result.markdown.fit_markdown))
if __name__ == "__main__":
asyncio.run(main())
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
from crawl4ai.extraction_strategy import JsonCssExtractionStrategy
import json
async def main():
schema = {
"name": "KidoCode Courses",
"baseSelector": "section.charge-methodology .w-tab-content > div",
"fields": [
{
"name": "section_title",
"selector": "h3.heading-50",
"type": "text",
},
{
"name": "section_description",
"selector": ".charge-content",
"type": "text",
},
{
"name": "course_name",
"selector": ".text-block-93",
"type": "text",
},
{
"name": "course_description",
"selector": ".course-content-text",
"type": "text",
},
{
"name": "course_icon",
"selector": ".image-92",
"type": "attribute",
"attribute": "src"
}
}
}
extraction_strategy = JsonCssExtractionStrategy(schema, verbose=True)
browser_config = BrowserConfig(
headless=False,
verbose=True
)
run_config = CrawlerRunConfig(
extraction_strategy=extraction_strategy,
js_code=["""(async () => {const tabs = document.querySelectorAll("section.charge-methodology .tabs-menu-3 > div");for(let tab of tabs) {tab.scrollIntoView();tab.click();await new Promise(r => setTimeout(r, 500));}})();"""],
cache_mode=CacheMode.BYPASS
)
async with AsyncWebCrawler(config=browser_config) as crawler:
result = await crawler.arun(
url="https://www.kidocode.com/degrees/technology",
config=run_config
)
companies = json.loads(result.extracted_content)
print(f"Successfully extracted {len(companies)} companies")
print(json.dumps(companies[0], indent=2))
if __name__ == "__main__":
asyncio.run(main())
import os
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode, LLMConfig
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():
browser_config = BrowserConfig(verbose=True)
run_config = CrawlerRunConfig(
word_count_threshold=1,
extraction_strategy=LLMExtractionStrategy(
# Here you can use any provider that Litellm library supports, for instance: ollama/qwen2
# provider="ollama/qwen2", api_token="no-token",
llm_config = LLMConfig(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"}."""
),
cache_mode=CacheMode.BYPASS,
)
async with AsyncWebCrawler(config=browser_config) as crawler:
result = await crawler.arun(
url='https://openai.com/api/pricing/',
config=run_config
)
print(result.extracted_content)
if __name__ == "__main__":
asyncio.run(main())
import os, sys
from pathlib import Path
import asyncio, time
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
async def test_news_crawl():
# Create a persistent user data directory
user_data_dir = os.path.join(Path.home(), ".crawl4ai", "browser_profile")
os.makedirs(user_data_dir, exist_ok=True)
browser_config = BrowserConfig(
verbose=True,
headless=True,
user_data_dir=user_data_dir,
use_persistent_context=True,
)
run_config = CrawlerRunConfig(
cache_mode=CacheMode.BYPASS
)
async with AsyncWebCrawler(config=browser_config) as crawler:
url = "ADDRESS_OF_A_CHALLENGING_WEBSITE"
result = await crawler.arun(
url,
config=run_config,
magic=True,
)
print(f"Successfully crawled {url}")
print(f"Content length: {len(result.markdown)}")
๐ World-aware ํฌ๋กค๋ง: ์ง์ ํ ๋ก์ผ์ผ๋ณ ์ฝํ ์ธ ๋ฅผ ์ํ ์ง๋ฆฌ์ ์์น, ์ธ์ด ๋ฐ ์๊ฐ๋ ์ค์ :
crun_cfg = CrawlerRunConfig(
url="https://browserleaks.com/geo", # ์์น๋ฅผ ๋ณด์ฌ์ฃผ๋ ํ
์คํธ ํ์ด์ง
locale="en-US", # Accept-Language & UI ๋ก์ผ์ผ
timezone_id="America/Los_Angeles", # JS Date()/Intl ์๊ฐ๋
geolocation=GeolocationConfig( # GPS ์ขํ ์ฌ์ ์
latitude=34.0522,
longitude=-118.2437,
accuracy=10.0,
)
)
๐ ํ ์ด๋ธ-ํฌ-๋ฐ์ดํฐํ๋ ์ ์ถ์ถ: HTML ํ ์ด๋ธ์ ์ง์ CSV ๋๋ pandas ๋ฐ์ดํฐํ๋ ์์ผ๋ก ์ถ์ถ:
crawler = AsyncWebCrawler(config=browser_config)
await crawler.start()
try:
# ์คํฌ๋ํ ๋งค๊ฐ๋ณ์ ์ค์
crawl_config = CrawlerRunConfig(
table_score_threshold=8, # ์๊ฒฉํ ํ
์ด๋ธ ๊ฐ์ง
)
# ์์ฅ ๋ฐ์ดํฐ ์ถ์ถ ์คํ
results: List[CrawlResult] = await crawler.arun(
url="https://coinmarketcap.com/?page=1", config=crawl_config
)
# ๊ฒฐ๊ณผ ์ฒ๋ฆฌ
raw_df = pd.DataFrame()
for result in results:
if result.success and result.media["tables"]:
raw_df = pd.DataFrame(
result.media["tables"][0]["rows"],
columns=result.media["tables"][0]["headers"],
)
break
print(raw_df.head())
finally:
await crawler.stop()
๐ ๋ธ๋ผ์ฐ์ ํ๋ง: ์ฌ์ ์๋ฐ๋ ๋ธ๋ผ์ฐ์ ์ธ์คํด์ค๋ก ํ์ด์ง๊ฐ ๋จ๊ฑฐ์ด ์ํ๋ก ์์๋์ด ์ง์ฐ ์๊ฐ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๊ฐ์
๐ธ๏ธ ๋คํธ์ํฌ ๋ฐ ์ฝ์ ์บก์ฒ: ๋๋ฒ๊น ์ ์ํ ์ ์ฒด ํธ๋ํฝ ๋ก๊ทธ ๋ฐ MHTML ์ค๋ ์ท:
crawler_config = CrawlerRunConfig(
capture_network=True,
capture_console=True,
mhtml=True
)
๐ MCP ํตํฉ: Model Context Protocol์ ํตํด Claude Code์ ๊ฐ์ AI ๋๊ตฌ์ ์ฐ๊ฒฐ
# Claude Code์ Crawl4AI ์ถ๊ฐ
claude mcp add --transport sse c4ai-sse http://localhost:11235/mcp/sse
๐ฅ๏ธ ๋ํํ ํ๋ ์ด๊ทธ๋ผ์ด๋: http://localhost:11235//playground
์์ ๋ด์ฅ ์น ์ธํฐํ์ด์ค๋ก ๊ตฌ์ฑ ํ
์คํธ ๋ฐ API ์์ฒญ ์์ฑ
๐ณ ๊ฐ์ ๋ Docker ๋ฐฐํฌ: ํฅ์๋ ๋ฆฌ์์ค ํจ์จ์ฑ์ ๊ฐ์ถ ๊ฐ์ํ๋ ๋ค์ค ์ํคํ ์ฒ Docker ์ด๋ฏธ์ง
๐ฑ ๋ค๋จ๊ณ ๋น๋ ์์คํ : ํ๋ซํผ๋ณ ์ฑ๋ฅ ํฅ์์ ์ํ ์ต์ ํ๋ Dockerfile
์์ธํ ๋ด์ฉ์ 0.6.0 ๋ฆด๋ฆฌ์ค ๋ ธํธ ๋๋ CHANGELOG์์ ํ์ธํ์ธ์.
crwl
CLI๋ก ํฐ๋ฏธ๋์์ ํธ๋ฆฌํ๊ฒ ์ ๊ทผlxml
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๋น ๋ฅธ HTML ํ์ฑ์์ธํ ๋ด์ฉ์ 0.5.0 ๋ฆด๋ฆฌ์ค ๋ ธํธ์์ ํ์ธํ์ธ์.
Crawl4AI์ ๊ฐ ๋ฆด๋ฆฌ์ค์ ์์ ์ฑ๊ณผ ๊ธฐ๋ฅ์ ์ดํดํ๋ ๋ฐ ๋์์ ์ฃผ๊ธฐ ์ํด ํ์ค Python ๋ฒ์ ๋ฒํธ ์ฒด๊ณ(PEP 440)๋ฅผ ๋ฐ๋ฆ ๋๋ค.
๋ฒ์ ๋ฒํธ๋ MAJOR.MINOR.PATCH
ํจํด์ ๋ฐ๋ฆ
๋๋ค (์: 0.4.3).
๊ฐ๋ฐ ๋จ๊ณ๋ฅผ ๋ํ๋ด๊ธฐ ์ํด ๋ค์ํ ์ ๋ฏธ์ฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค:
dev
(0.4.3dev1): ๊ฐ๋ฐ ๋ฒ์ , ๋ถ์์ a
(0.4.3a1): ์ํ ๋ฆด๋ฆฌ์ค, ์คํ์ ๊ธฐ๋ฅb
(0.4.3b1): ๋ฒ ํ ๋ฆด๋ฆฌ์ค, ๊ธฐ๋ฅ ์์ฑ but ํ
์คํธ ํ์rc
(0.4.3): ๋ฆด๋ฆฌ์ค ํ๋ณด, ์ต์ข
๋ฒ์ ๊ฐ๋ฅ์ฑ์์ ๋ฒ์ ์ค์น:
pip install -U crawl4ai
ํ๋ฆฌ๋ฆด๋ฆฌ์ค ๋ฒ์ ์ค์น:
pip install crawl4ai --pre
ํน์ ๋ฒ์ ์ค์น:
pip install crawl4ai==0.4.3b1
ํ๋ฆฌ๋ฆด๋ฆฌ์ค๋ ๋ค์๊ณผ ๊ฐ์ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค:
ํ๋ก๋์
ํ๊ฒฝ์์๋ ์์ ๋ฒ์ ์ฌ์ฉ์ ๊ถ์ฅํฉ๋๋ค. ์ ๊ธฐ๋ฅ ํ
์คํธ๋ฅผ ์ํ ๊ฒฝ์ฐ --pre
ํ๋๊ทธ๋ก ํ๋ฆฌ๋ฆด๋ฆฌ์ค๋ฅผ ์ ํํ ์ ์์ต๋๋ค.
๐จ ๋ฌธ์ ์ ๋ฐ์ดํธ ์๋ฆผ: ์ต๊ทผ ์ ๋ฐ์ดํธ์ ๊ฐ์ ์ฌํญ์ ๋ฐ์ํ๊ธฐ ์ํด ๋ค์ ์ฃผ์ ๋๊ท๋ชจ ๋ฌธ์ ๊ฐํธ์ ์งํํ ์์ ์ ๋๋ค. ๋ณด๋ค ํฌ๊ด์ ์ด๊ณ ์ต์ ์ ๋ณด๋ฅผ ์ ๊ณตํ ์์ ์ด๋ ๊ธฐ๋ํด์ฃผ์ธ์!
ํ์ฌ ๋ฌธ์(์ค์น ์ง์นจ, ๊ณ ๊ธ ๊ธฐ๋ฅ, API ์ฐธ์กฐ ๋ฑ)๋ ๋ฌธ์ ์น์ฌ์ดํธ์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
๊ฐ๋ฐ ๊ณํ๊ณผ ์์ ๋ ๊ธฐ๋ฅ์ ๋ก๋๋งต์์ ํ์ธํ์ธ์.
์คํ์์ค ์ปค๋ฎค๋ํฐ์ ๊ธฐ์ฌ๋ฅผ ํ์ํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ ๊ธฐ์ฌ ๊ฐ์ด๋๋ผ์ธ์ ์ฐธ์กฐํ์ธ์.
๋ผ์ด์ ์ค ์น์ ์ ๋ฐฐ์ง์ ํจ๊ป ์์ ํ๊ฒ ์ต๋๋ค. ํํํค ํจ๊ณผ๋ฅผ ์ ์ฉํ ๋ฒ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
์ ๋ฐ์ดํธ๋ ๋ผ์ด์ ์ค ์น์ :
์ด ํ๋ก์ ํธ๋ ํ์ ์ ์์ ํ์ ์กฐํญ์ด ํฌํจ๋ Apache License 2.0์ผ๋ก ๋ผ์ด์ ์ค๊ฐ ๋ถ์ฌ๋ฉ๋๋ค. ์์ธํ ๋ด์ฉ์ Apache 2.0 ๋ผ์ด์ ์ค ํ์ผ์ ์ฐธ์กฐํ์ธ์.
Crawl4AI์ ์ฌ์ฉํ ๋ ๋ค์ ์ค ํ๋์ ์ ์์ ํ์ ๋ฐฉ๋ฒ์ ํฌํจํด์ผ ํฉ๋๋ค:
README, ๋ฌธ์ ๋๋ ์น์ฌ์ดํธ์ ๋ค์ ๋ฐฐ์ง ์ค ํ๋๋ฅผ ์ถ๊ฐํ์ธ์:
ํ ๋ง | ๋ฐฐ์ง |
---|---|
๋์ค์ฝ ํ ๋ง (์ ๋๋ฉ์ด์ ) | |
๋์ดํธ ํ ๋ง (๋ค์จ ํจ๊ณผ ์๋ ๋คํฌ) | |
๋คํฌ ํ ๋ง (ํด๋์) | |
๋ผ์ดํธ ํ ๋ง (ํด๋์) |
๋ฐฐ์ง ์ถ๊ฐ HTML ์ฝ๋:
<!-- Disco Theme (Animated) -->
<a href="https://github.com/unclecode/crawl4ai">
<img src="https://raw.githubusercontent.com/unclecode/crawl4ai/main/docs/assets/powered-by-disco.svg" alt="Powered by Crawl4AI" width="200"/>
</a>
<!-- Night Theme (Dark with Neon) -->
<a href="https://github.com/unclecode/crawl4ai">
<img src="https://raw.githubusercontent.com/unclecode/crawl4ai/main/docs/assets/powered-by-night.svg" alt="Powered by Crawl4AI" width="200"/>
</a>
<!-- Dark Theme (Classic) -->
<a href="https://github.com/unclecode/crawl4ai">
<img src="https://raw.githubusercontent.com/unclecode/crawl4ai/main/docs/assets/powered-by-dark.svg" alt="Powered by Crawl4AI" width="200"/>
</a>
<!-- Light Theme (Classic) -->
<a href="https://github.com/unclecode/crawl4ai">
<img src="https://raw.githubusercontent.com/unclecode/crawl4ai/main/docs/assets/powered-by-light.svg" alt="Powered by Crawl4AI" width="200"/>
</a>
<!-- Simple Shield Badge -->
<a href="https://github.com/unclecode/crawl4ai">
<img src="https://img.shields.io/badge/Powered%20by-Crawl4AI-blue?style=flat-square" alt="Powered by Crawl4AI"/>
</a>
๋ฌธ์์ ๋ค์ ์ค์ ์ถ๊ฐํ์ธ์:
This project uses Crawl4AI (https://github.com/unclecode/crawl4ai) for web data extraction.
์ฐ๊ตฌ๋ ํ๋ก์ ํธ์์ Crawl4AI์ ์ฌ์ฉํ์ จ๋ค๋ฉด ๋ค์์ ์ธ์ฉํด ์ฃผ์ธ์:
@software{crawl4ai2024,
author = {UncleCode},
title = {Crawl4AI: Open-source LLM Friendly Web Crawler & Scraper},
year = {2024},
publisher = {GitHub},
journal = {GitHub Repository},
howpublished = {\url{https://github.com/unclecode/crawl4ai}},
commit = {Please use the commit hash you're working with}
}
ํ ์คํธ ์ธ์ฉ ํ์:
UncleCode. (2024). Crawl4AI: Open-source LLM Friendly Web Crawler & Scraper [Computer software].
GitHub. https://github.com/unclecode/crawl4ai
์ง๋ฌธ, ์ ์ ๋๋ ํผ๋๋ฐฑ์ด ์์ผ์๋ฉด ์ธ์ ๋ ์ง ์ฐ๋ฝ์ฃผ์ธ์:
ํ๋ณตํ ํฌ๋กค๋ง ๋์ธ์! ๐ธ๏ธ๐
์ฐ๋ฆฌ์ ๋ฏธ์ ์ ๊ฐ์ธ ๋ฐ ๊ธฐ์ ๋ฐ์ดํฐ์ ๊ฐ์น๋ฅผ ํด์ ํ์ฌ ๋์งํธ ํ์ ์ ๊ตฌ์กฐํ๋ ๊ฑฐ๋ ๊ฐ๋ฅํ ์์ฐ์ผ๋ก ๋ณํํ๋ ๊ฒ์ ๋๋ค. Crawl4AI์ ๊ฐ์ธ๊ณผ ์กฐ์ง์ ์คํ์์ค ๋๊ตฌ๋ฅผ ์ ๊ณตํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๊ณ ๊ตฌ์กฐํํจ์ผ๋ก์จ ๊ณต์ ๋ฐ์ดํฐ ๊ฒฝ์ ๋ฅผ ์กฐ์ฑํฉ๋๋ค.
์ฐ๋ฆฌ๋ AI๊ฐ ์ค์ ์ธ๊ฐ ์ง์์ผ๋ก ๊ตฌ๋๋๋ ๋ฏธ๋๋ฅผ ์์ํ๋ฉฐ, ๋ฐ์ดํฐ ์ฐฝ์์๊ฐ ์์ ์ ๊ธฐ์ฌ๋ก ์ง์ ํํ์ ๋ฐ์ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค. ๋ฐ์ดํฐ ๋ฏผ์ฃผํ์ ์ค๋ฆฌ์ ๊ณต์ ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํจ์ผ๋ก์จ ์ง์ ํ AI ๋ฐ์ ์ ๊ธฐ๋ฐ์ ๋ง๋ จํ๊ณ ์์ต๋๋ค.
์์ธํ ๋ด์ฉ์ ์ ์ฒด ๋ฏธ์ ์ค๋ช ์ ์ฐธ์กฐํ์ธ์.