935 lines
27 KiB
Markdown
935 lines
27 KiB
Markdown
# Crawl4AI 프로젝트 분석 및 기능명세
|
|
|
|
분석 대상: `C:\Users\lasta\MyProject\AI\참고\crawl4ai-main`
|
|
분석일: 2026-05-13
|
|
목적: 향후 웹 크롤링/추출 플랫폼의 기준 소스로 삼기 위한 구조 분석 및 정확한 기능명세 정리
|
|
|
|
## 1. 프로젝트 개요
|
|
|
|
Crawl4AI는 Python 기반 오픈소스 웹 크롤러/스크레이퍼 SDK이다. 핵심 목표는 일반 웹페이지, 동적 웹앱, 로컬 파일, 원시 HTML을 수집한 뒤 LLM/RAG/에이전트 파이프라인에 적합한 Markdown, 구조화 JSON, 링크/미디어/메타데이터로 변환하는 것이다.
|
|
|
|
주요 특징은 다음과 같다.
|
|
|
|
- 비동기 크롤링: `AsyncWebCrawler` 중심의 async SDK
|
|
- 브라우저 크롤링: Playwright/Patchright 기반 동적 페이지 처리
|
|
- HTTP 크롤링: 브라우저 없이 빠른 HTTP fetch 처리
|
|
- Markdown 생성: 원문 Markdown, citation 포함 Markdown, 필터링된 fit Markdown 지원
|
|
- 구조화 추출: LLM 기반 의미 추출을 주요 방식으로 지원하며, CSS/XPath/LXML/Regex 기반 결정적 추출도 함께 제공
|
|
- 딥 크롤링: BFS, DFS, Best-First 전략 및 URL 필터/스코어러
|
|
- URL 시딩: sitemap, Common Crawl, HEAD 메타데이터, BM25 기반 URL 후보 생성
|
|
- 안티봇 보조: stealth, undetected browser adapter, proxy retry, fallback fetch hook
|
|
- 배포형 API: Docker/FastAPI 서버, REST API, streaming, job API, MCP bridge, monitor dashboard
|
|
- 운영 기능: 캐시, smart cache validation, browser pool, rate limit, Redis job state, webhook
|
|
|
|
## 2. 기술 스택
|
|
|
|
- 언어: Python 3.10 이상
|
|
- 브라우저 엔진: Playwright, Patchright
|
|
- HTTP: aiohttp, httpx
|
|
- HTML 처리: lxml, BeautifulSoup, cssselect
|
|
- 데이터 모델: Pydantic v2, dataclass
|
|
- 저장소/캐시: aiosqlite 기반 로컬 캐시, Docker 서버는 Redis job state 사용
|
|
- LLM 연동: `unclecode-litellm`
|
|
- 검색/랭킹: rank-bm25, snowballstemmer, numpy
|
|
- 이미지/문서: Pillow, optional PDF parser
|
|
- API 서버: FastAPI, slowapi, prometheus-fastapi-instrumentator
|
|
- 배포: Dockerfile, docker-compose, supervisord
|
|
|
|
## 3. 최상위 구조
|
|
|
|
```text
|
|
crawl4ai-main/
|
|
crawl4ai/ # SDK 본체
|
|
crawl4ai/deep_crawling/ # 딥 크롤링 전략, 필터, 스코어러
|
|
crawl4ai/crawlers/ # 특화 크롤러 예: google_search, amazon_product
|
|
crawl4ai/processors/pdf/ # PDF 처리 전략
|
|
crawl4ai/script/ # C4A script 컴파일러/검증기
|
|
deploy/docker/ # FastAPI 서버, browser pool, job, monitor, MCP
|
|
docs/ # 공식 문서/예제/릴리즈 노트
|
|
tests/ # 단위/통합/회귀/Docker/브라우저 테스트
|
|
```
|
|
|
|
패키지 공개 API는 `crawl4ai/__init__.py`에서 대부분 export한다. 앞으로 우리 프로젝트에서 사용하거나 래핑할 핵심 객체는
|
|
`AsyncWebCrawler`, `BrowserConfig`, `CrawlerRunConfig`, `CacheMode`, 추출 전략류, 딥 크롤링 전략류, `CrawlResult`이다.
|
|
|
|
## 4. 핵심 런타임 아키텍처
|
|
|
|
### 4.1 기본 흐름
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A["사용자: URL + BrowserConfig + CrawlerRunConfig"] --> B["AsyncWebCrawler.arun"]
|
|
B --> C["CacheContext: 캐시 읽기/쓰기 판단"]
|
|
C --> D{"캐시 사용 가능?"}
|
|
D -- yes --> E["캐시 결과 로드 및 optional freshness 검증"]
|
|
D -- no --> F["CrawlerStrategy.crawl"]
|
|
F --> G["Playwright 또는 HTTP fetch"]
|
|
G --> H["apocess_html: HTML 정리/스크랩/Markdown/추출"]
|
|
E --> H
|
|
H --> I["CrawlResult 반환"]
|
|
```
|
|
|
|
### 4.2 주요 컴포넌트
|
|
|
|
- `AsyncWebCrawler`: SDK 중심 클래스. lifecycle, 캐시, robots.txt, proxy retry, anti-bot retry, HTML 후처리, 단일/다중/딥 크롤링 진입점을 담당한다.
|
|
- `AsyncCrawlerStrategy`: 실제 fetch 계층의 추상화.
|
|
- `AsyncPlaywrightCrawlerStrategy`: 동적 브라우저 페이지 처리, JS 실행, wait, iframe, screenshot, PDF, MHTML, shadow DOM, network/console capture 등을 담당한다.
|
|
- `AsyncHTTPCrawlerStrategy`: 브라우저 없는 HTTP 기반 수집. raw/file/http 다운로드 및 text/file 판단을 처리한다.
|
|
- `ContentScrapingStrategy`: HTML에서 cleaned HTML, media, links, metadata, tables 등을 산출한다.
|
|
- `MarkdownGenerationStrategy`: cleaned HTML을 LLM 친화 Markdown으로 변환한다.
|
|
- `ExtractionStrategy`: Markdown/HTML/text를 구조화 데이터로 추출한다. 특히 `LLMExtractionStrategy`는 이 프로젝트가 지향하는 LLM 친화 크롤링의 핵심 추출 방식이다.
|
|
- `DeepCrawlStrategy`: 단일 URL이 아닌 graph traversal 방식의 다중 URL 크롤링을 수행한다.
|
|
- `BaseDispatcher`: 다중 URL 크롤링 시 concurrency, memory, rate limit, retry, streaming을 담당한다.
|
|
|
|
## 5. SDK 기능명세
|
|
|
|
### 5.1 `AsyncWebCrawler`
|
|
|
|
기능:
|
|
|
|
- `async with AsyncWebCrawler(...)` context manager 지원
|
|
- `start()`, `close()` 명시 lifecycle 지원
|
|
- `arun(url, config)` 단일 URL/파일/raw HTML 크롤링
|
|
- `arun_many(urls, config, dispatcher)` 다중 URL 크롤링
|
|
- `aseed_urls(...)` URL 후보 생성
|
|
- `aprocess_html(...)` fetch 이후 HTML 처리 파이프라인
|
|
- `thread_safe=True`일 때 내부 lock으로 동시 접근 직렬화
|
|
- `base_directory/.crawl4ai/cache` 캐시 디렉터리 생성
|
|
- `robots.txt` 검사 옵션 지원
|
|
- `deep_crawl_strategy`가 들어오면 `arun` 호출이 딥 크롤링으로 장식됨
|
|
|
|
입력 URL 형식:
|
|
|
|
- `http://...`, `https://...`
|
|
- `file://...`
|
|
- `raw:<html>`, `raw://<html>`
|
|
|
|
반환:
|
|
|
|
- 일반 단일 크롤: `CrawlResult`
|
|
- 딥 크롤 또는 streaming 설정: 전략/설정에 따라 `CrawlResult` 목록 또는 async stream
|
|
|
|
### 5.2 `BrowserConfig`
|
|
|
|
브라우저 인스턴스/컨텍스트 설정이다.
|
|
|
|
주요 항목:
|
|
|
|
- 브라우저 종류: `browser_type=chromium|firefox|webkit`
|
|
- 실행 형태: `headless`, `browser_mode=dedicated|builtin|docker|custom`
|
|
- CDP 연결: `cdp_url`, `browser_context_id`, `target_id`, `cache_cdp_connection`
|
|
- persistent context: `use_persistent_context`, `user_data_dir`, `storage_state`
|
|
- viewport: `viewport_width`, `viewport_height`, `viewport`, `device_scale_factor`
|
|
- proxy: `proxy_config`, deprecated `proxy`
|
|
- 다운로드: `accept_downloads`, `downloads_path`
|
|
- 인증/헤더: `cookies`, `headers`, `user_agent`
|
|
- user-agent 생성: `user_agent_mode=random`, `user_agent_generator_config`
|
|
- 성능 모드: `text_mode`, `light_mode`, `memory_saving_mode`, `max_pages_before_recycle`
|
|
- 안티봇: `enable_stealth`
|
|
- 리소스 차단: `avoid_ads`, `avoid_css`
|
|
- 초기 스크립트: `init_scripts`
|
|
|
|
주의:
|
|
|
|
- `enable_stealth`는 builtin managed browser와 함께 사용할 수 없도록 검증된다.
|
|
- `proxy` 문자열은 deprecated이며 내부적으로 `ProxyConfig`로 변환된다.
|
|
- `browser_mode=builtin|docker|custom`은 managed browser/CDP 경로를 사용한다.
|
|
|
|
### 5.3 `CrawlerRunConfig`
|
|
|
|
개별 크롤 요청 단위 설정이다. 앞으로 우리 프로젝트에서 가장 자주 매핑해야 할 객체다.
|
|
|
|
콘텐츠 처리:
|
|
|
|
- `word_count_threshold`
|
|
- `css_selector`
|
|
- `target_elements`
|
|
- `excluded_tags`
|
|
- `excluded_selector`
|
|
- `only_text`
|
|
- `keep_data_attributes`
|
|
- `keep_attrs`
|
|
- `remove_forms`
|
|
- `prettiify`
|
|
- `parser_type`
|
|
- `scraping_strategy`
|
|
|
|
추출/Markdown:
|
|
|
|
- `extraction_strategy`
|
|
- `chunking_strategy`
|
|
- `markdown_generator`
|
|
- `table_extraction`
|
|
- `table_score_threshold`
|
|
|
|
캐시:
|
|
|
|
- `cache_mode=ENABLED|DISABLED|READ_ONLY|WRITE_ONLY|BYPASS`
|
|
- `check_cache_freshness`
|
|
- `cache_validation_timeout`
|
|
- legacy 옵션 `bypass_cache`, `disable_cache`, `no_cache_read`, `no_cache_write`는 deprecated 접근 시 에러 유도
|
|
|
|
세션/프록시:
|
|
|
|
- `session_id`
|
|
- `proxy_config`
|
|
- `proxy_rotation_strategy`
|
|
- `proxy_session_id`
|
|
- `proxy_session_ttl`
|
|
- `proxy_session_auto_release`
|
|
|
|
브라우저 지역/정체성:
|
|
|
|
- `locale`
|
|
- `timezone_id`
|
|
- `geolocation`
|
|
- `user_agent`
|
|
- `user_agent_mode`
|
|
|
|
페이지 로딩/대기:
|
|
|
|
- `wait_until`
|
|
- `page_timeout`
|
|
- `wait_for`
|
|
- `wait_for_timeout`
|
|
- `wait_for_images`
|
|
- `delay_before_return_html`
|
|
- `mean_delay`
|
|
- `max_range`
|
|
- `semaphore_count`
|
|
|
|
상호작용:
|
|
|
|
- `js_code`
|
|
- `js_code_before_wait`
|
|
- `c4a_script`
|
|
- `js_only`
|
|
- `scan_full_page`
|
|
- `scroll_delay`
|
|
- `max_scroll_steps`
|
|
- `process_iframes`
|
|
- `flatten_shadow_dom`
|
|
- `remove_overlay_elements`
|
|
- `remove_consent_popups`
|
|
- `simulate_user`
|
|
- `override_navigator`
|
|
- `magic`
|
|
- `adjust_viewport_to_content`
|
|
|
|
미디어/아카이브:
|
|
|
|
- `screenshot`
|
|
- `screenshot_wait_for`
|
|
- `screenshot_height_threshold`
|
|
- `force_viewport_screenshot`
|
|
- `pdf`
|
|
- `capture_mhtml`
|
|
- `exclude_external_images`
|
|
- `exclude_all_images`
|
|
- `image_description_min_word_threshold`
|
|
- `image_score_threshold`
|
|
|
|
링크:
|
|
|
|
- `exclude_external_links`
|
|
- `exclude_internal_links`
|
|
- `exclude_social_media_links`
|
|
- `exclude_social_media_domains`
|
|
- `exclude_domains`
|
|
- `score_links`
|
|
- `preserve_https_for_internal_links`
|
|
- `link_preview_config`
|
|
|
|
디버깅/관찰:
|
|
|
|
- `verbose`
|
|
- `log_console`
|
|
- `capture_network_requests`
|
|
- `capture_console_messages`
|
|
|
|
연결/실행:
|
|
|
|
- `method`
|
|
- `stream`
|
|
- `prefetch`
|
|
- `process_in_browser`
|
|
- `check_robots_txt`
|
|
|
|
딥 크롤링/매칭:
|
|
|
|
- `deep_crawl_strategy`
|
|
- `virtual_scroll_config`
|
|
- `url_matcher`
|
|
- `match_mode=OR|AND`
|
|
|
|
안티봇 재시도:
|
|
|
|
- `max_retries`
|
|
- `fallback_fetch_function`
|
|
|
|
### 5.4 `CrawlResult`
|
|
|
|
크롤 결과 모델이다.
|
|
|
|
주요 필드:
|
|
|
|
- `url`
|
|
- `success`
|
|
- `html`
|
|
- `cleaned_html`
|
|
- `markdown`
|
|
- `extracted_content`
|
|
- `media`
|
|
- `links`
|
|
- `metadata`
|
|
- `tables`
|
|
- `screenshot`
|
|
- `pdf`
|
|
- `mhtml`
|
|
- `downloaded_files`
|
|
- `js_execution_result`
|
|
- `session_id`
|
|
- `status_code`
|
|
- `response_headers`
|
|
- `redirected_url`
|
|
- `redirected_status_code`
|
|
- `ssl_certificate`
|
|
- `network_requests`
|
|
- `console_messages`
|
|
- `dispatch_result`
|
|
- `head_fingerprint`
|
|
- `cached_at`
|
|
- `cache_status`
|
|
- `crawl_stats`
|
|
- `error_message`
|
|
|
|
`markdown`는 문자열처럼 동작하면서 내부적으로 `MarkdownGenerationResult`를 제공한다.
|
|
|
|
`MarkdownGenerationResult` 필드:
|
|
|
|
- `raw_markdown`
|
|
- `markdown_with_citations`
|
|
- `references_markdown`
|
|
- `fit_markdown`
|
|
- `fit_html`
|
|
|
|
## 6. 추출 기능명세
|
|
|
|
Crawl4AI의 추출 계층은 LLM 기반 의미 추출을 중심 기능으로 제공하고, CSS/XPath/LXML/Regex 기반 추출을 보완적인 결정적 전략으로 함께 둔다. 즉 이 프로젝트는 단순 HTML 파서가 아니라, 수집한 웹 콘텐츠를 LLM이 바로 이해하고 구조화할 수 있는 형태로 변환하는 것을 주요 방식으로 삼는다.
|
|
|
|
### 6.1 LLM 기반 추출
|
|
|
|
클래스: `LLMExtractionStrategy`
|
|
|
|
기능:
|
|
|
|
- LLM provider, instruction, schema 기반 구조화 추출
|
|
- chunk 단위 분할 후 병렬/순차 LLM 호출
|
|
- token usage 집계
|
|
- JSON schema 기반 결과 유도 가능
|
|
- Docker API의 `/llm`, `/llm/job`, `/ask`에서도 사용
|
|
|
|
사용처:
|
|
|
|
- 크롤링 결과의 기본 의미 추출 방식
|
|
- 비정형/반정형 페이지에서 의미 기반 필드 추출
|
|
- 사용자가 자연어 instruction으로 원하는 데이터 구조를 지정하는 추출
|
|
- RAG용 요약/질의응답
|
|
- schema 기반 JSON 생성 및 schema 자동 생성 보조
|
|
|
|
### 6.2 CSS/XPath/LXML 기반 JSON 추출
|
|
|
|
클래스:
|
|
|
|
- `JsonCssExtractionStrategy`
|
|
- `JsonXPathExtractionStrategy`
|
|
- `JsonLxmlExtractionStrategy`
|
|
|
|
기능:
|
|
|
|
- 반복 요소 base selector 지정
|
|
- field별 selector, type, attribute, transform 지정
|
|
- text/html/attribute/source 추출
|
|
- nested/list field 추출
|
|
- LLM을 이용한 schema 생성 보조 메서드 제공
|
|
|
|
권장 사용:
|
|
|
|
- 쇼핑몰 상품 목록, 뉴스 목록, 테이블형 반복 카드처럼 DOM 구조가 안정적인 사이트
|
|
- LLM 호출 비용을 줄여야 하거나 완전히 반복적인 DOM 패턴이 검증된 경우
|
|
|
|
### 6.3 Regex 추출
|
|
|
|
클래스: `RegexExtractionStrategy`
|
|
|
|
기능:
|
|
|
|
- email, url, phone 등 정규식 패턴 기반 추출
|
|
- 사용자 정의 패턴 지원
|
|
- plain text 변환 후 추출 가능
|
|
|
|
### 6.4 Cosine/Embedding 추출
|
|
|
|
클래스: `CosineStrategy`
|
|
|
|
기능:
|
|
|
|
- 문서 chunk embedding
|
|
- query와 유사한 문서 조각 필터링
|
|
- hierarchical clustering 보조
|
|
|
|
주의:
|
|
|
|
- optional dependency가 필요할 수 있다.
|
|
- LLM 없이 관련 섹션만 좁히는 용도에 적합하다.
|
|
|
|
## 7. Markdown 및 콘텐츠 필터링
|
|
|
|
### 7.1 Markdown 생성
|
|
|
|
클래스: `DefaultMarkdownGenerator`
|
|
|
|
기능:
|
|
|
|
- HTML을 Markdown으로 변환
|
|
- 링크 citation 및 reference 목록 생성
|
|
- content filter 적용 후 `fit_markdown`, `fit_html` 생성
|
|
- 표/코드/헤딩/링크가 LLM 입력에 적합하도록 정리
|
|
|
|
### 7.2 Content Filter
|
|
|
|
클래스:
|
|
|
|
- `PruningContentFilter`: 휴리스틱 기반 noise 제거
|
|
- `BM25ContentFilter`: query 기반 관련 콘텐츠 선별
|
|
- `LLMContentFilter`: LLM 기반 관련 콘텐츠 선별
|
|
|
|
사용 기준:
|
|
|
|
- 단순 문서 정리: `PruningContentFilter`
|
|
- 사용자 질의 중심 수집: `BM25ContentFilter`
|
|
- 의미적 판단이 중요한 고품질 추출: `LLMContentFilter`
|
|
- 우리 프로젝트의 기본 의미 필터링/추출 정책: LLM 우선, 필요 시 BM25/CSS/XPath로 비용과 속도를 보완
|
|
|
|
## 8. 브라우저 크롤링 기능명세
|
|
|
|
`AsyncPlaywrightCrawlerStrategy`가 담당한다.
|
|
|
|
지원 기능:
|
|
|
|
- Playwright browser/context/page lifecycle
|
|
- dedicated browser, managed browser, CDP 연결
|
|
- persistent profile 및 storage state
|
|
- JS 실행: 크롤 전/후 스크립트, C4A script 컴파일 결과
|
|
- selector/function 기반 wait
|
|
- iframe 처리
|
|
- shadow DOM flatten
|
|
- overlay/consent popup 제거
|
|
- full page scan 및 virtual scroll
|
|
- lazy image 대기
|
|
- screenshot 캡처
|
|
- PDF export
|
|
- MHTML 캡처
|
|
- file download 처리
|
|
- network request capture
|
|
- console message capture
|
|
- SSL certificate fetch
|
|
- navigator override 및 simulated user 동작
|
|
- stealth 적용
|
|
|
|
브라우저 관리자:
|
|
|
|
- `ManagedBrowser`는 CDP endpoint를 제공하는 browser process를 직접 띄우거나 기존 CDP에 연결한다.
|
|
- memory saving, light mode, text mode, proxy flag, debugging port, user data dir를 관리한다.
|
|
|
|
## 9. HTTP 크롤링 기능명세
|
|
|
|
`AsyncHTTPCrawlerStrategy`가 담당한다.
|
|
|
|
지원 기능:
|
|
|
|
- HTTP/HTTPS 요청
|
|
- `file://` 로컬 파일 처리
|
|
- `raw:` HTML 처리
|
|
- content-type 기반 text/file 판단
|
|
- 파일 다운로드명 추출
|
|
- proxy formatting
|
|
- hook 실행
|
|
- browser 없이 빠른 HTML 수집
|
|
|
|
제약:
|
|
|
|
- JS 렌더링, 실제 브라우저 DOM 변화, screenshot/PDF 등은 브라우저 전략 필요
|
|
|
|
## 10. 딥 크롤링 기능명세
|
|
|
|
### 10.1 전략
|
|
|
|
- `BFSDeepCrawlStrategy`: breadth-first 탐색
|
|
- `DFSDeepCrawlStrategy`: depth-first 탐색
|
|
- `BestFirstCrawlingStrategy`: URL score 기반 우선순위 탐색
|
|
|
|
공통 기능:
|
|
|
|
- `max_depth`
|
|
- `max_pages`
|
|
- stream/batch 실행
|
|
- cancellation
|
|
- link discovery
|
|
- visited/seen 관리
|
|
- resume/export state 일부 지원
|
|
- crawler의 `arun`을 decorator로 감싸 단일 호출 인터페이스와 통합
|
|
|
|
### 10.2 필터
|
|
|
|
- `FilterChain`: 여러 URL filter 조합
|
|
- `URLPatternFilter`: glob/패턴 기반 include/exclude
|
|
- `DomainFilter`: allowed/blocked domain, subdomain 판단
|
|
- `ContentTypeFilter`: 확장자/content type 기반 판단
|
|
- `ContentRelevanceFilter`: BM25 기반 관련도
|
|
- `SEOFilter`: title, meta description, canonical, schema.org, URL 품질 기반 score
|
|
|
|
### 10.3 스코어러
|
|
|
|
- `KeywordRelevanceScorer`
|
|
- `PathDepthScorer`
|
|
- `ContentTypeScorer`
|
|
- `FreshnessScorer`
|
|
- `DomainAuthorityScorer`
|
|
- `CompositeScorer`
|
|
|
|
Best-first crawling에서 우선순위 계산에 사용한다.
|
|
|
|
## 11. 다중 URL 크롤링/Dispatcher
|
|
|
|
클래스:
|
|
|
|
- `BaseDispatcher`
|
|
- `MemoryAdaptiveDispatcher`
|
|
- `SemaphoreDispatcher`
|
|
- `RateLimiter`
|
|
|
|
기능:
|
|
|
|
- URL별 config 선택: `url_matcher`와 `match_mode`
|
|
- concurrency 제한
|
|
- memory threshold 기반 backpressure
|
|
- domain별 rate limit
|
|
- retry
|
|
- task status, memory usage, peak memory 기록
|
|
- streaming result 지원
|
|
- dispatcher monitor 연계
|
|
|
|
권장:
|
|
|
|
- 소량 병렬: `SemaphoreDispatcher`
|
|
- 대량/장시간 크롤: `MemoryAdaptiveDispatcher`
|
|
|
|
## 12. URL Seeder 기능명세
|
|
|
|
클래스: `AsyncUrlSeeder`
|
|
|
|
기능:
|
|
|
|
- sitemap 기반 URL 수집
|
|
- Common Crawl index 기반 URL 수집
|
|
- URL pattern 필터링
|
|
- live validation
|
|
- HEAD 요청으로 title/meta/canonical 등 head data 수집
|
|
- BM25/query 기반 URL relevance scoring
|
|
- nonsense URL 필터링
|
|
- cache 사용
|
|
- 여러 domain에 대한 batch seeding
|
|
|
|
설정 객체: `SeedingConfig`
|
|
|
|
주요 사용 시나리오:
|
|
|
|
- “사이트 전체 중 특정 주제/상품/문서 URL 후보를 먼저 뽑고, 선별된 URL만 실제 크롤링”
|
|
- 대규모 사이트에서 full crawl 전에 seed 후보를 줄이는 단계
|
|
|
|
## 13. Adaptive Crawler 기능명세
|
|
|
|
클래스:
|
|
|
|
- `AdaptiveCrawler`
|
|
- `AdaptiveConfig`
|
|
- `CrawlState`
|
|
- `StatisticalStrategy`
|
|
- `EmbeddingStrategy`
|
|
|
|
기능:
|
|
|
|
- 수집 상태를 누적하며 confidence 계산
|
|
- query coverage, consistency, saturation 기반 stop 판단
|
|
- 링크 relevance/novelty/authority 기반 ranking
|
|
- embedding 기반 semantic exploration
|
|
- state save/load
|
|
|
|
사용 시나리오:
|
|
|
|
- 고정 depth/page 수가 아니라 “원하는 정보가 충분히 모였을 때 멈추는” 연구형 크롤러
|
|
|
|
## 14. 캐시 기능명세
|
|
|
|
캐시 모드:
|
|
|
|
- `ENABLED`: 읽기/쓰기
|
|
- `DISABLED`: 캐시 사용 안 함
|
|
- `READ_ONLY`: 읽기만
|
|
- `WRITE_ONLY`: 쓰기만
|
|
- `BYPASS`: 해당 작업에서 캐시 우회
|
|
|
|
Smart Cache:
|
|
|
|
- `check_cache_freshness=True`일 때 ETag, Last-Modified, head fingerprint로 freshness 검증
|
|
- fresh면 `cache_status=hit_validated`
|
|
- 검증 실패 시 fallback으로 cached result 사용 가능
|
|
- stale/unknown이면 재크롤
|
|
|
|
캐시 대상:
|
|
|
|
- web URL과 file URL은 cacheable
|
|
- raw HTML은 기본적으로 cacheable 아님
|
|
|
|
## 15. 프록시 및 안티봇 기능명세
|
|
|
|
프록시:
|
|
|
|
- `ProxyConfig`
|
|
- 문자열/dict/env 기반 생성
|
|
- list proxy 지원
|
|
- `ProxyRotationStrategy`, `RoundRobinProxyStrategy`
|
|
- sticky proxy session: `proxy_session_id`, `proxy_session_ttl`
|
|
- NSTProxy API 연동 helper
|
|
|
|
안티봇:
|
|
|
|
- HTML/status 기반 block detection
|
|
- `max_retries`
|
|
- 여러 proxy 순회
|
|
- 실패 통계 `crawl_stats`
|
|
- 최후 수단 `fallback_fetch_function`
|
|
- `enable_stealth`
|
|
- `UndetectedAdapter`
|
|
- browser flags에서 automation 흔적 일부 완화
|
|
|
|
주의:
|
|
|
|
- CAPTCHA 해결 자체는 본체 기능이 아니라 예제에 가까운 외부 서비스 연동 형태다.
|
|
- 안티봇 우회는 사이트 약관/법적 제한을 반드시 확인해야 한다.
|
|
|
|
## 16. Docker/FastAPI 서버 기능명세
|
|
|
|
경로: `deploy/docker`
|
|
|
|
### 16.1 서버 구성
|
|
|
|
- `server.py`: FastAPI entrypoint
|
|
- `api.py`: crawl/md/llm 처리 로직
|
|
- `crawler_pool.py`: browser pool
|
|
- `job.py`: 비동기 job API
|
|
- `monitor.py`, `monitor_routes.py`: dashboard/metrics
|
|
- `auth.py`: JWT token 발급/검증
|
|
- `webhook.py`: job 완료 webhook 전달
|
|
- `mcp_bridge.py`: MCP schema/tool bridge
|
|
- `schemas.py`: request/response schema
|
|
|
|
### 16.2 REST endpoint
|
|
|
|
- `GET /`: playground redirect
|
|
- `POST /token`: JWT token 발급
|
|
- `POST /config/dump`: config object serialization
|
|
- `POST /md`: URL을 Markdown으로 변환
|
|
- `POST /html`: HTML 반환
|
|
- `POST /screenshot`: screenshot 반환/저장
|
|
- `POST /pdf`: PDF 반환/저장
|
|
- `POST /execute_js`: 지정 JS 실행
|
|
- `GET /llm/{url:path}`: URL + query 기반 LLM QA
|
|
- `GET /schema`: 서버/API schema
|
|
- `GET /hooks/info`: hook 지원 정보
|
|
- `GET /health`: health check
|
|
- `GET /metrics`: Prometheus metrics
|
|
- `POST /crawl`: 다중 URL 크롤
|
|
- `POST /crawl/stream`: streaming crawl
|
|
- `GET /ask`: 질문/응답형 endpoint
|
|
- `POST /llm/job`: LLM extraction background job 생성
|
|
- `GET /llm/job/{task_id}`: LLM job 조회
|
|
- `POST /crawl/job`: crawl background job 생성
|
|
- `GET /crawl/job/{task_id}`: crawl job 조회
|
|
|
|
Monitor endpoint:
|
|
|
|
- `GET /dashboard`
|
|
- `GET /health`
|
|
- `GET /requests`
|
|
- `GET /browsers`
|
|
- `GET /endpoints/stats`
|
|
- `GET /timeline`
|
|
- `GET /logs/janitor`
|
|
- `GET /logs/errors`
|
|
- `POST /actions/cleanup`
|
|
- `POST /actions/kill_browser`
|
|
- `POST /actions/restart_browser`
|
|
- `POST /stats/reset`
|
|
- `WebSocket /ws`
|
|
|
|
### 16.3 API 요청 모델
|
|
|
|
`CrawlRequest`:
|
|
|
|
- `urls: List[str]`, 1~100개
|
|
- `browser_config: Dict`
|
|
- `crawler_config: Dict`
|
|
|
|
`CrawlRequestWithHooks`:
|
|
|
|
- `CrawlRequest` + optional `hooks`
|
|
|
|
`MarkdownRequest`:
|
|
|
|
- `url`
|
|
- `f=fit|raw|bm25|llm`
|
|
- `q`
|
|
- `c`
|
|
- `provider`
|
|
- `temperature`
|
|
- `base_url`
|
|
|
|
`ScreenshotRequest`:
|
|
|
|
- `url`
|
|
- `screenshot_wait_for`
|
|
- `wait_for_images`
|
|
- `output_path`
|
|
|
|
`PDFRequest`:
|
|
|
|
- `url`
|
|
- `output_path`
|
|
|
|
`JSEndpointRequest`:
|
|
|
|
- `url`
|
|
- `scripts`
|
|
|
|
### 16.4 보안/운영
|
|
|
|
- JWT token 인증
|
|
- hooks는 기본 비활성화: `CRAWL4AI_HOOKS_ENABLED=false`
|
|
- hook code 실행은 RCE 위험이 있으므로 운영 환경에서는 비활성 권장
|
|
- global page semaphore로 동시 page 수 제한
|
|
- rate limiting
|
|
- TrustedHost/HTTPS middleware 옵션
|
|
- Redis 기반 task state 및 TTL
|
|
- Prometheus metrics
|
|
- playground와 monitor dashboard 정적 파일 제공
|
|
|
|
## 17. CLI 기능명세
|
|
|
|
entrypoint:
|
|
|
|
- `crwl = crawl4ai.cli:main`
|
|
- `crawl4ai-setup`
|
|
- `crawl4ai-doctor`
|
|
- `crawl4ai-download-models`
|
|
- `crawl4ai-migrate`
|
|
|
|
README 기준 CLI 예:
|
|
|
|
```bash
|
|
crwl https://www.nbcnews.com/business -o markdown
|
|
crwl https://docs.crawl4ai.com --deep-crawl bfs --max-pages 10
|
|
crwl https://www.example.com/products -q "Extract all product prices"
|
|
```
|
|
|
|
역할:
|
|
|
|
- 빠른 단일 URL 크롤
|
|
- Markdown 출력
|
|
- 딥 크롤 옵션
|
|
- 질의 기반 LLM 추출
|
|
- 설정 파일 기반 실행 예제 제공
|
|
|
|
## 18. C4A Script 기능명세
|
|
|
|
경로: `crawl4ai/script`
|
|
|
|
공개 API:
|
|
|
|
- `c4a_compile`
|
|
- `c4a_validate`
|
|
- `c4a_compile_file`
|
|
- `CompilationResult`
|
|
- `ValidationResult`
|
|
- `ErrorDetail`
|
|
|
|
역할:
|
|
|
|
- 사람이 읽기 쉬운 C4A script를 JavaScript로 컴파일
|
|
- `CrawlerRunConfig(c4a_script=...)`에 넣으면 `js_code`로 변환되어 브라우저에서 실행
|
|
- 폼 입력, 클릭, 스크롤, 로그인 흐름 등 반복 브라우저 작업 자동화에 적합
|
|
|
|
## 19. 특화 크롤러
|
|
|
|
경로:
|
|
|
|
- `crawl4ai/crawlers/google_search`
|
|
- `crawl4ai/crawlers/amazon_product`
|
|
|
|
역할:
|
|
|
|
- 공통 SDK 위에 특정 사이트/도메인 추출 로직을 래핑한 예시
|
|
- 향후 우리 프로젝트에서 도메인별 크롤러를 만들 때 참고할 구조
|
|
|
|
## 20. 테스트 자산
|
|
|
|
테스트는 다음 범위를 포괄한다.
|
|
|
|
- 기본 async crawler
|
|
- browser manager/context/CDP/profile
|
|
- raw HTML/file/http 처리
|
|
- caching/smart cache
|
|
- markdown/content filter
|
|
- extraction strategies
|
|
- table extraction
|
|
- link/media extraction
|
|
- deep crawling, filters, scorers, resume/cancel
|
|
- Docker API/server/hooks/security/webhook
|
|
- proxy/sticky sessions
|
|
- memory/stress
|
|
- regression tests
|
|
|
|
이 프로젝트를 기반으로 개발할 때는 기존 테스트명을 기능별 체크리스트로 활용할 수 있다.
|
|
|
|
## 21. 우리 프로젝트에 적용할 때의 권장 아키텍처
|
|
|
|
### 21.1 권장 래핑 계층
|
|
|
|
우리 코드에서 Crawl4AI를 직접 전역적으로 흩뿌려 쓰기보다 아래 계층으로 감싸는 것을 권장한다.
|
|
|
|
```text
|
|
우리 서비스
|
|
CrawlJob API / Queue
|
|
Domain Crawler Service
|
|
Crawl4AI Adapter
|
|
- BrowserConfig factory
|
|
- CrawlerRunConfig factory
|
|
- ExtractionStrategy factory
|
|
- Result normalizer
|
|
Crawl4AI SDK
|
|
```
|
|
|
|
### 21.2 우리가 정의해야 할 내부 표준
|
|
|
|
- 크롤 목적별 profile:
|
|
- `fast_static`: HTTP 또는 text/light mode
|
|
- `dynamic_page`: Playwright + JS/wait
|
|
- `full_capture`: screenshot/pdf/mhtml/network
|
|
- `structured_extract`: CSS/XPath schema
|
|
- `semantic_extract`: LLM/BM25
|
|
- `deep_discovery`: URL seeder + deep crawl
|
|
|
|
- 결과 저장 표준:
|
|
- raw html
|
|
- cleaned html
|
|
- raw markdown
|
|
- fit markdown
|
|
- extracted JSON
|
|
- media/links/tables
|
|
- crawl metadata/status/error
|
|
|
|
- 실패 표준:
|
|
- DNS/network timeout
|
|
- HTTP error
|
|
- robots blocked
|
|
- anti-bot blocked
|
|
- extraction empty
|
|
- schema mismatch
|
|
- LLM provider failure
|
|
|
|
## 22. 장점
|
|
|
|
- SDK/API/CLI/Docker를 모두 제공해 개발-운영 경로가 넓다.
|
|
- 동적 페이지 처리 기능이 풍부하다.
|
|
- Markdown과 구조화 추출이 기본 내장되어 LLM/RAG 파이프라인과 맞다.
|
|
- 딥 크롤링, URL 시딩, adaptive crawling까지 있어 단순 scraper보다 확장성이 높다.
|
|
- 캐시/dispatcher/browser pool/monitor 등 운영 기능도 상당히 갖추어져 있다.
|
|
|
|
## 23. 리스크 및 주의사항
|
|
|
|
- 코드베이스가 크고 기능이 빠르게 확장된 흔적이 있어 일부 API가 deprecated 상태다.
|
|
- README 일부 문자는 인코딩이 깨져 있어 원문 문서만 보고 자동 처리하기 어렵다.
|
|
- hook code 실행은 보안상 위험하다.
|
|
- LLM extraction은 이 오픈소스가 제공하는 주요 추출 방식이다. 우리 프로젝트에서는 크롤링 옵션으로 추출 방식을 선택할 수 있게 하되, 기본 정책은 LLM 기반 추출 우선으로 둔다. CSS/XPath/Regex/schema 기반 추출은 비용, 속도, 반복 DOM 안정성이 중요한 경우 선택 가능한 보완 전략으로 사용한다.
|
|
- 브라우저 기반 대량 크롤링은 메모리 누수/컨텍스트 정리/프로세스 recycle 정책이 중요하다.
|
|
- anti-bot/stealth/proxy 기능은 기술적으로 제공되지만 법적/약관 리스크를 별도로 관리해야 한다.
|
|
- Docker 서버는 Redis, browser pool, auth, monitor 등 운영 의존성이 있어 단순 SDK 사용보다 배포 복잡도가 높다.
|
|
|
|
## 24. 향후 개발 기준 기능명세
|
|
|
|
이 소스를 기반으로 우리 프로젝트를 진행할 때 최소 기능 기준은 다음과 같이 잡는 것을 권장한다.
|
|
|
|
### 24.1 MVP 필수
|
|
|
|
- 단일 URL 크롤
|
|
- 다중 URL 크롤
|
|
- 동적 페이지 JS 렌더링
|
|
- wait selector/function
|
|
- raw HTML 처리
|
|
- Markdown 변환
|
|
- LLM 기반 의미 추출
|
|
- CSS/XPath 기반 JSON 추출 옵션
|
|
- 캐시 모드
|
|
- screenshot 선택 캡처
|
|
- 링크/미디어/메타데이터 수집
|
|
- 표 추출
|
|
- 에러/상태/HTTP status 기록
|
|
|
|
### 24.2 1차 확장
|
|
|
|
- URL seeding
|
|
- BFS/DFS deep crawl
|
|
- domain/pattern/content-type filter
|
|
- BM25 query 기반 content filter
|
|
- proxy config
|
|
- session reuse
|
|
- persistent browser profile
|
|
- network/console capture
|
|
- smart cache validation
|
|
|
|
### 24.3 운영 확장
|
|
|
|
- Docker API 또는 자체 FastAPI 래퍼
|
|
- job queue
|
|
- streaming result
|
|
- Redis/task state
|
|
- webhook
|
|
- monitor dashboard
|
|
- Prometheus metrics
|
|
- browser pool
|
|
- rate limit
|
|
- memory adaptive dispatcher
|
|
|
|
### 24.4 고급 확장
|
|
|
|
- adaptive crawler
|
|
- best-first scoring
|
|
- embedding strategy
|
|
- C4A script 기반 브라우저 자동화
|
|
- custom domain crawler
|
|
- anti-bot retry/fallback
|
|
- MHTML/PDF archive
|
|
|
|
## 25. 결론
|
|
|
|
Crawl4AI는 단순 페이지 다운로드 도구가 아니라 “웹을 LLM 친화 데이터로 변환하는 비동기 크롤링 프레임워크”에 가깝다.
|
|
앞으로 우리 프로젝트의 기본 소스로 삼는다면 `AsyncWebCrawler + CrawlerRunConfig + ExtractionStrategy + MarkdownGenerator + DeepCrawlStrategy`
|
|
조합을 중심으로 래핑하고, Docker 서버 코드는 운영형 API 설계 참고 또는 별도 배포 모듈로 분리해 사용하는 것이 가장 현실적이다.
|
|
|
|
가장 중요한 설계 결정은 다음 세 가지다.
|
|
|
|
1. 기본 추출 방식은 Crawl4AI의 주요 설계 방향에 맞춰 LLM 기반 의미 추출을 우선한다.
|
|
2. CSS/XPath/Regex 같은 결정적 전략은 크롤링 옵션으로 제공해 비용, 속도, 반복 DOM 안정성이 중요한 경우 선택하게 한다.
|
|
3. 브라우저 크롤링은 비용이 크므로 URL seeding, cache, dispatcher, profile 재사용으로 호출량을 통제한다.
|