일부 제3자 스크래퍼 비교 글에서는 Crawl4AI에 "적응형 인텔리전스"—즉, 사이트를 학습하고 마크업이 바뀌어도 스스로 복구하는 셀렉터—가 있는 것처럼 소개합니다. 하지만 제가 테스트한 API 범위에서는 그런 동작을 확인하지 못했습니다. Crawl4AI가 실제로 제공하는 기능은 브라우저 기반 Markdown 생성과 CSS/XPath 추출입니다. Scrapling은 별도의 적응형 셀렉터 기능을 제공하지만, 그 범위와 한계는 자체 리뷰에 따로 정리되어 있습니다.

저는 Crawl4AI 0.9.0을 기준 정답이 명확한 다섯 가지 페이지 유형에 적용해 봤습니다. 정적 카탈로그, JavaScript로 렌더링되는 카탈로그, 본문 주변에 불필요한 요소가 많은 기사 페이지, 의도적으로 500 에러를 반환하는 페이지, 그리고 링크로 연결된 멀티페이지 그래프입니다. 테스트한 Markdown 및 스키마 경로는 기대한 피처 콘텐츠를 제대로 반환했습니다. 다만 원본 Markdown에는 불필요한 요소가 함께 남았고, 딥 크롤링은 페이지별 대기 조건이 필요했으며, 일반적인 500 에러는 안티봇처럼 보이는 오류 문구로 표시됐습니다.
Crawl4AI가 실제로 무엇인지
설치할 때 가장 많이 헷갈리는 부분부터 짚어보겠습니다. Crawl4AI는 가벼운 Python 파서가 아닙니다. 처음 실행하는 crawl4ai-setup은 Playwright와 Patchright, 두 개의 브라우저 스택을 조용히 내려받습니다. 이걸 알고 나면 도구의 성격이 분명해집니다. 이건 스크래퍼 모양을 하고 있지만, 실체는 Markdown 변환기가 얹힌 제어된 헤드리스 브라우저입니다.
공식적으로는 웹페이지를 RAG 파이프라인, 에이전트, 데이터 워크플로용 Markdown으로 바꾸는 오픈소스 Apache-2.0 라이브러리입니다. 제가 테스트한 버전은 v0.9.0입니다. 핵심 구성 요소로는 AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, Markdown 생성 기능, 그리고 CSS/XPath 또는 LLM 기반 추출 전략이 있으며, 이는 공식 빠른 시작 가이드에 설명되어 있습니다.
핵심은 이런 식으로 이해하면 됩니다. 대부분의 파싱 라이브러리는 HTTP 요청을 보내고 돌아온 바이트를 해석합니다. 반면 Crawl4AI는 실제 브라우저를 구동합니다. 브라우저 렌더링이 기본 포함이라 순수 HTTP 파서보다 설치가 무겁습니다. 또 비동기적으로 렌더링되는 요소를 안정적으로 추출하려면 명시적인 대기가 여전히 필요할 수 있습니다. 이번 테스트에서는 리디자인 후 셀렉터를 스스로 바꾸는 기능은 확인되지 않았습니다. 따라서 그런 "셀프 힐링" 주장은, 공식 출처와 재현 가능한 API가 명확히 제시되기 전까지는 제3자 비교 글의 오류로 보는 편이 맞습니다.
핵심 기능과 내부 동작 방식
단일 페이지 처리 경로가 이 도구의 핵심입니다. AsyncWebCrawler에 URL을 주면 브라우저에서 페이지를 열고 Markdown을 돌려줍니다. 공식 example.com 빠른 시작 예시에서는 이 왕복이 1.81초 걸렸고 깔끔한 200 응답을 받았습니다. 특별한 건 없지만, 스키마도, 대기도, 브라우저 설정도 없이 최소 구성만으로 잘 동작한다는 점은 확인됐습니다.
비디오 튜토리얼(1:02:38): Crawl4AI 공식 튜토리얼, 빠른 시작 예제를 포함한 1시간 완전판.
구조화 추출은 두 번째 축입니다. 그리고 Crawl4AI가 페이지를 "이해"한다고 부를 수 있는 가장 가까운 기능이기도 한데, 엄밀히 말하면 추론이 아니라 사용자가 직접 작성한 스키마를 적용하는 방식입니다. Markdown만 덤프하는 대신 JsonCssExtractionStrategy로 CSS 스키마를 주면, 요청한 필드만 담긴 JSON 객체를 돌려줍니다. 제 로컬 정적 카탈로그에서는 6개의 깨끗한 JSON 레코드—상품명, 카테고리, 가격, 평점, 상세 URL—를 반환했고, 예상한 6개 상품과 정확히 일치했습니다. 이것이 "페이지를 텍스트로 보여주는 것"과 "데이터를 행 단위로 뽑는 것"의 차이입니다. Crawl4AI는 같은 크롤링에서 둘 다 해냅니다. 다만 셀렉터는 사용자가 직접 정의해야 합니다. 도구가 스키마를 추론해 주는 것은 아닙니다.

동적 렌더링은 브라우저 기반 구조의 장점이 가장 잘 드러나는 부분입니다. wait_for="css:.product-card"를 주고 JavaScript로 렌더링되는 카탈로그에 연결하면, 클라이언트 렌더링이 끝날 때까지 기다린 뒤 추출을 진행합니다. 제 로컬 JS 피처에서는 Markdown과 스키마 출력 모두에서 8/8 상품 회수율을 기록했고, 시간은 약 1.56초였습니다. 공개 Quotes to Scrape JS 페이지에서도 렌더링된 인용문을 잘 가져왔고, 실제로 쓸 수 있는 스크린샷도 저장했습니다. 초기 HTML 안에 내용이 없기 때문에, 순수 HTTP 요청으로는 절대 볼 수 없는 결과입니다.
그다음은 규모와 크롤링입니다. arun_many()는 로컬 상세 페이지 6개를 동시에 처리했고 6/6을 모두 회수하는 데 3.76초가 걸렸습니다. 또한 Crawl4AI는 BFS, DFS, BestFirst 같은 딥 크롤 전략도 제공합니다. 이 전략들은 depth 제한, 페이지 상한, 필터링, 스코어링을 활용해 링크 그래프를 따라갑니다. BFS 딥 크롤은 제 피처 홈페이지의 링크 그래프를 따라가며 5개 페이지를 가져왔습니다. 하지만 바로 여기서부터 마케팅 문구와 실제 동작의 차이가 드러나기 시작합니다. 아래에서 더 자세히 보겠습니다.
설치: README 첫 문단에서는 잘 안 보이는 부분

제 환경에서 설치는 한 가지는 예상보다 수월했고, 다른 한 가지는 더 무거웠습니다. pip install -U crawl4ai와 스모크 테스트는 macOS arm64의 Python 3.14.2에서 성공했습니다. PyPI의 >=3.10 조건에는 이미 3.14가 포함되므로, 이 결과는 어디까지나 테스트한 설치와 워크플로가 잘 됐다는 뜻이지, 더 넓은 호환성을 보장하는 것은 아닙니다.
불편한 부분은 셋업 단계입니다. crawl4ai-setup은 Playwright와 Patchright 양쪽의 브라우저 자산을 내려받습니다. Chrome for Testing, FFmpeg, Headless Shell까지 포함됩니다. 노트북 저장 공간이 빠듯하거나 네트워크가 요금제 기반이라면 실제 비용이 됩니다. 문제는 문서에서 이 점을 앞부분에서 강하게 안내하기보다 가볍게 언급한다는 데 있습니다. 이후 crawl4ai-doctor는 통과했고 crawl4ai.com을 14.65초에 크롤링했습니다. 끝단까지의 스모크 테스트로는 괜찮지만 벤치마크라고 보긴 어렵습니다. 그 숫자만 보고 속도를 단정하진 않을 겁니다.
여기서 얻을 결론은, 본인 평가를 준비할 때는 pip 설치비뿐 아니라 브라우저 다운로드 비용까지 예산에 넣어야 한다는 점입니다. 이건 스크립트에 라이브러리 하나를 추가하는 수준이 아니라, 헤드리스 브라우저 환경을 새로 세우는 것에 가깝습니다. 실제 페이지를 한 번도 크롤링하기 전에 두 개의 브라우저 스택이 디스크를 차지하고, Patchright의 스텔스 계층이 필요 없더라도 그 비용은 한 번은 치러야 합니다.
실사용 테스트: 잘 버틴 부분과 주의할 부분
특히 기억해 둘 만한 결과는 네 가지입니다. 마케팅 페이지라면 종종 뭉개지는 부분이고, 한 사례는 아예 잘못 표기되기도 했습니다.

공개 데모 페이지 두 개도 무난하게 통과했습니다. Books to Scrape 홈 페이지에서는 Crawl4AI가 2.43초 만에 13,476자의 Markdown을 생성했습니다. 공개 Quotes JS 페이지는 약 3.1초 만에 렌더링된 Markdown 1,666자를 반환했습니다. 다만 이것만으로 대규모 트래픽, 적대적인 사이트, 장기 안정성, 세션, 프록시, 재시도, 메모리 동작을 판단할 수는 없습니다.
기사 피처는 Markdown 품질의 주의점을 보여줍니다. Crawl4AI는 제목과 본문 3/3개 문단을 모두 잡아냈습니다. 성과는 좋습니다. 하지만 원본 Markdown에는 네비게이션 텍스트, 관련 링크, 구독 안내 문구, 푸터 텍스트도 함께 들어 있었습니다. 이건 버그가 아닙니다. 콘텐츠 필터나 대상 셀렉터가 없으면 "이 페이지를 Markdown으로 바꾸라"는 말은 사실상 페이지 전체를 뜻합니다. 즉, 원본 Markdown 변환과 깔끔한 기사 추출은 구분해야 합니다. 후자가 필요하다면 PruningContentFilter 같은 콘텐츠 필터나 대상 셀렉터를 써야 합니다. 다만 저는 아직 그 조합을 강하게 검증하지 않았기 때문에, 청결도 수치를 단정하진 않겠습니다.

가장 의미 있었던 결과는 고의로 만든 오류 페이지였습니다. 작은 본문을 가진 HTTP 500 페이지를 일부러 띄웠습니다. Crawl4AI는 success=false와 상태 코드 500을 반환했으니 그 자체는 맞았습니다. 하지만 오류 메시지는 *"Blocked by anti-bot protection: Structural: minimal_text on small page."*라고 설명했습니다. 실제 안티봇 장벽은 없었습니다. 그냥 작은 에러 페이지였을 뿐입니다. Crawl4AI의 구조적 휴리스틱은 눈에 보이는 텍스트가 매우 적다는 이유만으로 안티봇 상황으로 해석한 것입니다. 이 도구 위에 무엇인가를 올릴 계획이라면 이 점은 중요합니다. 로그에 "anti-bot"이라는 라벨이 보인다고 곧바로 믿지 마세요. 실제 HTTP 상태 코드와 응답 본문을 먼저 확인해야 합니다. 원본 결과는 벤치마크 저장소의 results/local_failure_500.json에 있습니다.
딥 크롤링은 의도적인 설정이 필요합니다. 직접 지정한 동적 크롤은 wait_for와 함께 깨끗하게 동작했지만, BFS 딥 크롤은 동적 카탈로그를 발견하고도 실패했습니다. 최소 텍스트 분류는 카드가 렌더링되기 전에 읽은 것과 일치합니다. 그리고 딥 크롤은 직접 크롤에서 쓴 대기 조건을 가져오지 않았습니다. 다섯 페이지 중 세 개는 성공했고 두 개는 실패했습니다. 다만 여기에는 wait_for를 적용해 다시 실행한 결과가 없으므로, 이것은 아직 추론이지 입증된 원인은 아닙니다.
숫자로 보면 어디쯤인지

| 테스트 | 결과 | 관측된 실행 시간(단일 캡처 런) |
|---|---|---|
빠른 시작 (example.com) | 성공, 200 | 1.81초 |
| 로컬 정적 카탈로그(Markdown) | 상품 6/6 회수 | 0.731초 |
| 로컬 정적 CSS 스키마 추출 | JSON 레코드 6개 | 0.740초 |
로컬 동적 카탈로그 (wait_for) | 상품 8/8 회수 | 1.559초 |
| 로컬 동적 CSS 스키마 추출 | JSON 레코드 8개 | 1.561초 |
| 기사 Markdown | 문단 3/3개 (+ 불필요한 요소 포함) | 0.752초 |
| 공개 Books to Scrape 홈 페이지 | Markdown 13,476자 | 2.425초 |
| 공개 Quotes JS 페이지 | 렌더링된 Markdown 1,666자 | 3.111초 |
arun_many() (로컬 페이지 6개) | 6/6 회수 | 3.760초 |
| 로컬 BFS 딥 크롤 | 5개 페이지 발견, 3개 성공 / 2개 실패 | 3.239초 |
| 의도적 500 페이지 | 실패, 500("anti-bot"으로 잘못 라벨링) | 0.745초 |
이 수치는 스모크 테스트 시간이지 성능 벤치마크가 아닙니다. 이 글에는 하드웨어, 반복 횟수, 워밍/콜드 상태, 캐시 상태, 동시성 제어, 분산 정보가 없습니다. 즉, 이 머신에서 나열된 워크플로가 돌아갔다는 것만 보여줍니다. 전체 실행 산출물은 벤치마크 저장소 디렉터리에 있습니다.
의사결정 수준의 성능 테스트를 하려면 각 워크플로를 새 브라우저 세션과 재사용 세션에서 반복하고, 한 자리 반올림 값이 아니라 분포를 보고, 브라우저 빌드를 고정하고, CPU·메모리·캐시 상태·동시성을 기록해야 합니다. 그래야 라이브러리 오버헤드와 브라우저 기동 비용, 네트워크 변동을 분리해 볼 수 있습니다.
| 요구사항 | 이번 리뷰에서의 적합도 | 핵심 조건 |
|---|---|---|
| 페이지를 렌더링해 Markdown으로 반환 | 적합 | 결과를 기사용으로 쓰기 전에 불필요한 요소를 제거할 것 |
| 스키마 형태의 JSON 추출 | 적합 | CSS 스키마는 여전히 직접 작성하고 유지해야 함 |
| 비동기 페이지 콘텐츠를 기다리기 | 지원됨 | 대상별로 명시적인 wait_for 조건을 정의할 것 |
| 동적 페이지를 깊게 크롤링 | 조건부 | 준비 상태 규칙을 전파해야 함; 테스트한 기본값은 일부 실패를 낳았음 |
| 작은 의존성의 가벼운 HTTP 파서로 사용 | 부적합 | 브라우저 자산과 그 유지보수까지 배포 범위에 포함됨 |
| 셀프 힐링 셀렉터 사용 | 이번 테스트에서는 미지원 | 관련 없는 비교 문구를 근거로 추정하지 말 것 |
장단점
장점:
- 하나의 라이브러리로 원본 Markdown과 CSS 스키마 기반 JSON을 모두 처리할 수 있어, 두 도구를 억지로 이어 붙일 필요가 없습니다.
- 브라우저 렌더링이 기본 포함되어 있으며, 비동기 렌더링 대상에는 명시적인
wait_for가 필요할 수 있습니다. - 테스트한 단일 페이지 워크플로는 위에 적은 시간 내에 완료됐습니다. 다만 상대적 속도 우위는 주장하지 않습니다.
- Apache-2.0 라이선스라 상업적으로도 부담이 적고, 카피레프트 걱정이 없습니다.
- 최근 릴리스가 있고 커뮤니티도 활발한 편입니다.
단점:
- 처음 설치할 때 브라우저 스택 두 개를 내려받아야 해서 무겁습니다. 소개글에서는 이 점이 충분히 드러나지 않습니다.
- 원본 Markdown에는 콘텐츠 필터를 쓰지 않으면 불필요한 요소가 포함됩니다.
- 딥 크롤링은 동적 페이지를 자동으로 기다려 주지 않습니다. 각 크롤마다 직접 설정해야 하며, 그렇지 않으면 실패합니다.
- 오류 메시지가 단순한 에러를 "anti-bot"으로 오인할 수 있어 로그 해석이 헷갈립니다.
- 일부 비교 글과 달리 적응형 셀렉터는 없습니다. 스키마는 직접 작성하고 정적 방식으로 유지해야 합니다.
- 브라우저 환경의 실행과 유지보수, 업데이트와 장애 대응까지 사용자가 직접 맡아야 합니다.
누구에게 맞고, 누구는 건너뛰어야 하나
Crawl4AI는 RAG나 에이전트 파이프라인을 만드는 개발자, 헤드리스 브라우저 환경을 운영할 수 있는 사람, 그리고 같은 크롤링에서 Markdown과 구조화 JSON을 모두 얻고 싶은 사람이라면 충분히 검토할 가치가 있습니다. 이번 테스트는 적대적인 사이트 대응, 장기 안정성, 메모리, 세션, 재시도, 프록시, 프로덕션 배포까지 다루지 않았으므로, 여기서의 추천은 이 워크플로 범위에 한정됩니다.
반대로, 아주 작고 의존성이 적은 HTTP 파서를 원했다면 이 도구는 정반대입니다. 브라우저 다운로드용 디스크와 대역폭을 아낄 수 없다면, 또는 프로덕션에서 브라우저 스택 유지보수를 떠안고 싶지 않다면 건너뛰는 편이 낫습니다. 특히 셀프 힐링 셀렉터 때문에 왔다면 더더욱 그렇습니다. 이 도구는 그런 제품이 아니며, 존재하지 않는 기능을 전제로 워크플로를 짜면 나중에 반드시 발목을 잡습니다. 순수한 기사 텍스트 추출과 불필요한 요소 제거가 목표라면, 그 일에 더 특화된 가벼운 도구가 더 나을 수 있습니다.
대안과 Thunderbit가 들어가는 위치
솔직하게 말하면, Crawl4AI는 직접 호스팅하고 직접 유지보수하는 무료 오픈소스 라이브러리입니다. 사용료는 없지만, 대신 컴퓨팅·대역폭·저장공간·브라우저 업데이트·스키마 관리·운영 작업의 비용은 직접 부담해야 합니다.
반대편에는 Thunderbit 같은 관리형 스크래핑 서비스가 있습니다. 이 경우 가져오기와 추출이 API 뒤에 숨겨져 있습니다. Thunderbit는 이번 피처들로 돌려보지 않았기 때문에, 렌더링, 안티봇 처리, CAPTCHA, 정확도, 속도에 대해 이 글에서 짝지은 비교를 하진 않습니다. 여기서 중요한 비교는 운영 책임의 차이입니다. 브라우저 기반 라이브러리를 직접 호스팅할 것인지, 아니면 그 계층을 서비스에 맡길 것인지의 문제입니다.
차이는 결국 누가 브라우저를 운영하느냐입니다. Crawl4AI에서는 렌더링, 대기 조건, 스키마, 유지보수를 모두 사용자가 책임집니다. 관리형 API에서는 호출당 비용을 내는 대신 운영 책임의 일부를 제공업체에 넘깁니다. 이번 실험은 두 경로의 결과를 직접 비교하지는 않았습니다.
관련 벤치마크 리뷰: 오픈소스 스크래퍼 전체 비교, Firecrawl 자체 호스팅 리뷰, trafilatura 기사 추출 리뷰.
결론
Crawl4AI는 Markdown과 스키마 형태 JSON을 모두 만들어 주는 브라우저 기반 오픈소스 추출 도구를 원하고, 브라우저 환경까지 직접 운영할 준비가 되어 있다면 꽤 괜찮은 선택입니다. 이번 피처에서 직접 실행한 정적 크롤과 대기 조건이 포함된 동적 크롤은 모두 성공했습니다. Apache-2.0 라이선스도 관대하지만, 일반적인 의존성 및 배포 검토는 여전히 필요합니다.
브라우저 자산 비용은 반드시 예산에 넣으세요. 원본 Markdown은 기사용으로 쓰기 전에 필터링이 필요합니다. 딥 크롤의 대기 조건은 의도적으로 설정해야 하며, 로그에 "anti-bot"이라고 나오더라도 상태 코드와 응답 본문으로 검증해야 합니다. 스키마 셀렉터는 여전히 사용자가 직접 작성하고 관리해야 합니다. 이것이 이번 테스트에서 확인된 판단 기준입니다. 프로덕션 규모와 적대적인 사이트에서의 동작은 아직 열린 질문으로 남아 있습니다.
웹 데이터 추출용 Thunderbit 사용해 보기 Get Started Free
자주 묻는 질문
Crawl4AI에 적응형 또는 셀프 힐링 셀렉터가 있나요? 아니요. 일부 비교 글에서는 "적응형 인텔리전스"가 있다고 하지만, Crawl4AI는 사용자가 작성한 CSS/XPath 스키마를 그대로 맞춥니다. 요소를 지문처럼 추적하거나 마크업 변경 후 다시 찾아오는 기능은 없습니다. 이번 테스트에서 구조화 추출은 제가 직접 정의한 스키마로 6/6과 8/8 회수율을 보였습니다. 사이트의 클래스명이 바뀌면, 사용자가 스키마를 수정할 때까지는 깨집니다. 셀프 힐링 요소 추적은 다른 라이브러리의 기능이지 이 도구의 기능이 아닙니다.
설치가 왜 이렇게 큰가요?
crawl4ai-setup이 Playwright와 Patchright 양쪽의 전체 브라우저 자산을 내려받기 때문입니다. Chrome for Testing, FFmpeg, Headless Shell까지 포함됩니다. 실제 브라우저 렌더링을 제공하는 대가입니다. 순수 HTTP 파서보다 무겁고, 스텔스 스택을 전혀 쓰지 않더라도 그 비용은 지불해야 합니다.
Crawl4AI는 JavaScript로 렌더링된 페이지를 처리할 수 있나요?
네. 실제 헤드리스 브라우저를 구동하기 때문입니다. 테스트에서는 wait_for="css:.product-card"가 적용된 동적 카탈로그가 상품 8/8개를 온전히 가져왔고, 공개 Quotes JS 페이지도 정상 렌더링됐습니다. 다만 딥 크롤에서는 그 대기 조건이 자동으로 발견된 페이지에 적용되지 않아, BFS 크롤이 동적 페이지에서 실패했습니다. 대기 설정은 크롤마다 직접 해줘야 합니다.
Crawl4AI는 깔끔한 기사 본문만 주나요, 아니면 페이지 전체를 주나요?
기본값은 페이지 전체입니다. 이번 테스트에서도 본문 문단은 모두 가져왔지만, 네비게이션·관련 링크·푸터 텍스트도 함께 남았습니다. 깔끔한 기사 추출이 목적이라면 원본 Markdown에 기대기보다 콘텐츠 필터(PruningContentFilter 같은 것)나 대상 셀렉터를 써야 합니다.
Crawl4AI의 오류 메시지를 믿어도 되나요? 조금은 의심하면서 읽는 편이 좋습니다. 본문이 아주 짧은 의도적 500 에러 페이지가 "Blocked by anti-bot protection"으로 표시됐는데, 이는 눈에 보이는 텍스트가 적다는 휴리스틱 때문이었고 실제 안티봇 장벽은 없었습니다. 원본 결과는 벤치마크 저장소에 있습니다. 사이트가 차단하는지 결론 내리기 전에 항상 HTTP 상태 코드와 응답 본문을 먼저 확인하세요.


