DEEP DIVE · TRENDSHIFT #5

D4Vinci/Scrapling — 웹사이트가 바뀌어도
알아서 살아남는 적응형 스크래핑 프레임워크

52.2k 스타·5k 포크의 Python 웹 스크래핑 신예. CSS 셀렉터가 어제 잘 되다가 오늘 깨졌을 때, adaptive=True 한 줄로 유사도 알고리즘이 변경된 요소를 자동으로 다시 찾아준다. Cloudflare Turnstile/Interstitial을 그냥 통과하고, BS4보다 ~1679배 빠른 lxml 기반 파서, Scrapy 스타일 Spider, 내장 MCP 서버까지 한 라이브러리에 묶었다.

목차
  1. 한 줄 요약
  2. 왜 지금 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석 — 적응형 파서 + 3종 Fetcher
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 시스템 요구사항 & 라이선스
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1한 줄 요약

Scrapling이 정확히 무엇인지부터 못박고 시작
ONE-LINER

"HTML을 긁어오는 도구"가 아니라, "HTML 구조가 바뀌어도 알아서 적응하는 자율 스크래퍼"

Scrapling은 한 줄 요청에서 풀스케일 크롤링까지 다루는 적응형(adaptive) 웹 스크래핑 프레임워크다. BS4·Scrapy·Playwright가 각자 하던 일을 하나의 일관된 API로 통합하고, 거기에 "요소 추적(Smart Element Tracking)"이라는 새 레이어를 얹었다.

핵심 아이디어는 단순하다 — 처음 셀렉터로 요소를 찾았을 때 그 요소의 "지문(서명)"을 저장해두고, 나중에 사이트 구조가 바뀌어 셀렉터가 깨지면 저장된 지문과 가장 비슷한 요소를 자동으로 다시 찾는다.

비유

친구네 집에 자주 갔는데 어느 날 가구 배치가 바뀌었다. 일반 스크래퍼는 "내가 알던 그 자리에 소파가 없네? 못 찾겠다" 하고 멈춘다. Scrapling은 "소파는 가죽이고 3인용이었지" 하고 기억해서, 바뀐 자리에서도 소파를 알아본다. "위치"가 아니라 "특징"으로 요소를 추적하는 게 핵심.

3가지 Fetcher(HTTP / Stealthy / Dynamic)와 Scrapy 스타일 Spider 프레임워크, 그리고 내장 MCP 서버까지 갖춰서 한 라이브러리로 단발 스크래퍼부터 풀스케일 크롤러, AI 에이전트 도구까지 커버한다. Karim Shoair가 2024년부터 단독 메인테이너로 끌어왔고, 2026년 6월 기준 v0.4.9까지 47번 릴리즈했다.

TERM
적응형 스크래핑 (Adaptive Scraping)
스크래퍼가 대상 사이트의 HTML 구조 변경을 자동 감지하고 — 사람이 셀렉터를 다시 안 짜도 — 요소를 다시 찾아내는 방식. 클래스명이 .product에서 .product-card로 바뀌어도 동작한다. Scrapling은 첫 매칭 때 요소의 부모/자식/형제·속성·텍스트를 저장해 "프로파일"을 만든 뒤, 다음 실행에서 유사도가 가장 높은 후보를 고른다.

2왜 지금 주목받는가

TrendShift 5위까지 올라간 이유 — AI 시대 스크래핑의 새 표준

1) "셀렉터가 깨지는 지옥"을 코드 한 줄로 해결

웹 스크래퍼를 운영해본 사람이라면 알고 있다 — 사이트가 디자인을 한번 바꾸면 그날부터 셀렉터가 우수수 깨진다. CSS 클래스명만 바뀌어도 다 다시 짜야 한다.

Scrapling은 첫 매칭 때 auto_save=True로 요소 정보를 저장하고, 다음 실행 때 adaptive=True를 켜면 알아서 비슷한 요소를 다시 찾는다. 유지보수 비용을 거의 0으로 만드는 발상이다.

products = p.css('.product', auto_save=True)   # 1차 실행: 요소 지문 저장
# ... 며칠 후 사이트 구조 변경 ...
products = p.css('.product', adaptive=True)    # 2차 실행: 자동 재탐색

2) Cloudflare Turnstile/Interstitial 즉시 우회

대부분의 상업 사이트는 Cloudflare·DataDome·PerimeterX 같은 봇 차단 시스템 뒤에 있다. requests나 일반 Playwright로는 첫 페이지부터 막힌다.

Scrapling의 StealthyFetcherPatchright(스텔스 Playwright 포크) + browserforge(브라우저 지문 위조) + Apify 지문 데이터셋을 결합해서 Cloudflare Turnstile을 solve_cloudflare=True 한 줄로 통과한다.

3) BS4보다 ~1679배 빠른 파서

벤치마크 결과(5000개 중첩 요소 텍스트 추출, 100회 평균):

라이브러리시간 (ms)Scrapling 대비
Scrapling2.021.0×
Parsel/Scrapy2.041.01×
Raw lxml2.541.26×
PyQuery24.17~12×
Selectolax82.63~41×
MechanicalSoup1549.71~767×
BS4 (lxml)1584.31~784×
BS4 (html5lib)3391.91~1679×

JSON 직렬화도 orjson 사용으로 표준 라이브러리 대비 10배 빠르다.

4) AI 에이전트와의 자연스러운 통합 — MCP 서버 내장

pip install "scrapling[ai]" 한 줄이면 Model Context Protocol(MCP) 서버가 함께 설치된다. Claude/Cursor 같은 AI 코딩 도구에 등록하면, AI가 직접 사이트를 긁어와서 파싱한 결과만 받는다.

핵심 가치: AI에게 HTML 1MB를 통째로 보내는 게 아니라, Scrapling이 먼저 셀렉터로 잘라낸 깔끔한 데이터만 전달해서 토큰 비용을 대폭 줄인다. Anthropic 공식 에이전트 스킬(agent-skill/ 폴더), OpenClaw Skill도 번들로 제공.

5) Scrapy의 학습 곡선 없이 풀크롤러를 짤 수 있다

Scrapy는 강력하지만 프로젝트 구조·미들웨어·파이프라인·설정 파일이 복잡하다. Scrapling Spider는 한 파일에 Spider 클래스 하나만 정의하면 끝. 동시성·throttling·robots.txt 준수·pause/resume·스트리밍을 다 내장.

REAL-WORLD VALUE
상업 사이트 스크래핑이 "한 번 짜면 한 달 가는" 시대로

이전: 셀렉터 깨질 때마다 사람이 수동 패치 → 운영 인력 비용 ↑ / 봇 차단 우회 노하우는 회사 비밀 / 풀크롤링은 Scrapy 학습 필수.
Scrapling: adaptive=True 한 줄 + StealthyFetcher 기본 옵션 + Spider 한 파일. 1인 개발자가 운영 가능한 스크래핑 인프라를 만든다.

3기술 스택 전체 지도

pyproject.toml과 Dockerfile에서 추출한 전체 의존성

파서/코어 (필수 의존성)

패키지버전역할
lxml≥6.1.1C 기반 XML/HTML 파서. Scrapling 속도의 90%를 책임진다.
cssselect≥1.4.0CSS 셀렉터를 XPath로 변환. .product::text 같은 pseudo-element도 처리.
orjson≥3.11.8Rust 기반 JSON 직렬화. 표준 json 대비 10배 빠름.
tld≥0.13.2Top-Level Domain 파싱. 도메인/서브도메인 차단에 사용.
w3lib≥2.4.1Scrapy 팀의 URL/HTML 헬퍼.
typing_extensionsPython 3.10에서도 최신 타입 힌트 사용.

Fetchers (선택 — pip install "scrapling[fetchers]")

패키지역할
curl_cffi ≥0.15.0curl-impersonate 바인딩. Chrome/Firefox의 TLS 지문(JA3/JA4)을 그대로 흉내내서 HTTP 레벨에서 봇 탐지 우회. HTTP/3도 지원.
playwright 1.60.0Microsoft의 브라우저 자동화 표준. Chromium·Firefox·WebKit 제어.
patchright 1.60.1Playwright의 스텔스 패치 포크. navigator.webdriver 같은 탐지 시그널 제거.
browserforge ≥1.2.4실제 사용자 통계에서 추출한 헤더/지문 데이터로 위장된 브라우저 핑거프린트 생성.
apify-fingerprint-datapoints ≥0.13.0Apify 회사가 수집한 실 브라우저 지문 데이터셋.
msgspec ≥0.21.1초고속 직렬화 라이브러리(Rust 기반). Pydantic 대안.
anyio ≥4.13.0asyncio/trio 추상화. Scrapling이 둘 다 지원하기 위해 사용.
protego ≥0.6.0Scrapy 팀의 robots.txt 파서. Disallow/Crawl-delay 준수.
click ≥8.3.0CLI 프레임워크. scrapling shell 등 명령어.

AI/Shell (선택)

패키지역할
mcp ≥1.27.0Model Context Protocol 공식 SDK. AI 에이전트가 Scrapling을 도구로 호출할 수 있게.
markdownify ≥1.2.0HTML → Markdown 변환. scrapling extract get url out.md가 이걸 쓴다.
IPython ≥8.37대화형 셸. scrapling shell로 즉석에서 사이트 탐색.

인프라 / 빌드

릴리즈 자동화

TERM
TLS 지문 (TLS Fingerprint, JA3/JA4)
TLS 핸드셰이크 패킷의 cipher suites·extensions·EC curves 등을 해시한 값. 같은 도메인이라도 requests(Python urllib3)와 진짜 Chrome은 지문이 다르게 나와서 봇 차단 시스템이 이를 보고 거른다. curl_cffi커널 레벨에서 Chrome의 TLS 스택을 복제해서 JA3 검사를 통과시킨다.
TERM
browserforge / 브라우저 지문 (Browser Fingerprint)
서버가 클라이언트의 User-Agent·screen 해상도·navigator.plugins·WebGL 렌더러·폰트 목록 등을 조합해 만든 "이 브라우저는 누구인가" 식별값. browserforge는 실제 사용자 통계에서 추출한 일관된 조합을 생성해서 "Chrome인데 폰트 목록이 이상한" 모순을 없앤다.

4아키텍처 심화 분석 — 적응형 파서 + 3종 Fetcher

Scrapling이 라이브러리 한 개로 BS4·requests·Playwright·Scrapy를 다 대체하는 구조

전체 시스템 구조도

┌─────────────────────────────────────────────────────────────────┐ │ USER CODE (당신의 스크립트) │ │ │ │ from scrapling.fetchers import Fetcher, StealthyFetcher │ │ from scrapling.spiders import Spider │ └────────────────────────────┬────────────────────────────────────┘ │ ┌──────────────┼──────────────┐ │ │ │ ▼ ▼ ▼ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ Fetcher │ │ Stealthy │ │ Dynamic │ ← 3종 Fetcher │ (HTTP) │ │ Fetcher │ │ Fetcher │ │ │ │ (스텔스 BR) │ │(풀 BR 자동) │ ├────────────┼─┴────────────┼─┴────────────┤ │curl_cffi │ patchright │ playwright │ ← 엔진 어댑터 │(TLS 위조) │ +browserforge│ (표준 PW) │ └─────┬──────┴──────┬───────┴──────┬───────┘ │ │ │ └─────────────┼──────────────┘ ▼ ┌────────────────────────────┐ │ Response (HTML/JSON) │ └─────────────┬──────────────┘ │ ▼ ┌────────────────────────────┐ │ Selector (parser.py 58KB) │ ← 핵심 적응형 파서 │ ┌──────────────────────┐ │ │ │ lxml 백엔드 │ │ │ │ + cssselect 변환 │ │ │ │ + 요소 지문 저장 │ │ ← Smart Element │ │ + 유사도 기반 재탐색│ │ Tracking │ │ + BS4 호환 API │ │ │ └──────────────────────┘ │ └─────────────┬──────────────┘ │ ▼ ┌────────────────────────────┐ │ 데이터 (dict/JSON/CSV) │ └────────────────────────────┘ ┌────────────────────────────────────────┐ │ SPIDERS (스파이더) │ │ start_urls → parse() → yield items │ │ + 동시성/throttling/pause/resume/스트림│ └────────────────────────────────────────┘ ┌────────────────────────────────────────┐ │ MCP SERVER (server.json) │ │ stdio → AI 에이전트가 직접 호출 │ │ Claude·Cursor·기타 MCP 클라이언트 │ └────────────────────────────────────────┘

핵심 설계 패턴 1 — Smart Element Tracking (적응형 요소 추적)

Scrapling을 다른 스크래퍼와 결정적으로 차별화하는 부분이다. 셀렉터를 처음 실행할 때 auto_save=True를 주면, 매칭된 요소의 "프로파일"이 디스크에 저장된다.

저장되는 정보:

다음 실행에서 adaptive=True를 주면, Scrapling은 이렇게 동작한다:

  1. 먼저 원래 셀렉터로 시도한다.
  2. 요소를 못 찾거나, 찾았는데 저장된 프로파일과 너무 다르면 → 유사도 매칭 모드 진입.
  3. 저장된 프로파일과 현재 DOM의 모든 요소를 비교해, 유사도 점수가 가장 높은 후보를 반환.
PATTERN
셀렉터 결정성을 깨지 않으면서 유연성을 더하는 방식

"AI가 매번 추론"하는 게 아니라, 결정적 셀렉터를 1차로 시도하고 실패할 때만 유사도 검색으로 폴백한다. 정상 상황에서는 일반 lxml과 같은 속도를 유지하고, 사이트가 바뀐 날에만 비싼 연산을 수행하는 "비용을 사건과 결합한 설계".

핵심 설계 패턴 2 — 3종 Fetcher의 점진적 강화 (Progressive Stealth)

같은 인터페이스로 점점 강한 위장을 선택할 수 있다.

Fetcher엔진속도스텔스JS 실행적합 케이스
Fetchercurl_cffi★★★★★★★★×API/정적 HTML, 대량 요청
DynamicFetcherplaywright★★★★★JS 렌더링 필요한 SPA
StealthyFetcherpatchright + browserforge★★★★★★★Cloudflare/DataDome 보호 사이트

같은 fetch() API로 3종을 바꿔낄 수 있어서, "먼저 빠른 Fetcher로 시도하다 차단되면 StealthyFetcher로 폴백" 같은 전략이 한 파일에 깔끔하게 들어간다.

핵심 설계 패턴 3 — 멀티 세션 라우팅 (Spider 내부)

Scrapy에는 없는 Scrapling만의 패턴. 한 Spider 안에서 URL 유형에 따라 다른 세션으로 라우팅한다.

class MultiSessionSpider(Spider):
    def configure_sessions(self, manager):
        manager.add("fast",    FetcherSession(impersonate="chrome"))
        manager.add("stealth", AsyncStealthySession(headless=True), lazy=True)

    async def parse(self, response):
        for link in response.css('a::attr(href)').getall():
            if "protected" in link:
                yield Request(link, sid="stealth")   # 보호 페이지 → 스텔스
            else:
                yield Request(link, sid="fast")      # 일반 페이지 → 빠른 HTTP

lazy=True: 무거운 브라우저 세션은 처음 요청이 들어왔을 때만 spin-up. 보호 페이지가 없는 도메인이면 브라우저는 아예 안 뜬다.

핵심 설계 패턴 4 — Checkpoint 기반 Pause & Resume

Scrapy의 JOBDIR과 비슷하지만 더 단순한 API. crawldir="./crawl_data"를 주면:

장시간 크롤(수일~수주)에 필수. 서버 재부팅·네트워크 단절·디버깅 중단에 강하다.

핵심 설계 패턴 5 — Development Mode (응답 캐싱)

parse() 로직을 고치면서 매번 실제 서버에 요청 보내면 차단 위험 + 느림. Dev 모드는 첫 실행 응답을 디스크에 캐시했다가 이후 실행에선 캐시를 사용. Scrapy의 HTTPCACHE_ENABLED를 기본 워크플로로 승격한 것.

핵심 설계 패턴 6 — Streaming Mode

async for item in spider.stream():
    # 결과가 도착하는 순서대로 즉시 받음 (전체 크롤 끝나기 전에)
    await pipeline.send(item)

UI/대시보드/실시간 인덱싱 파이프라인에 결과를 흘려보낼 때 사용. 일반 모드는 크롤 끝나야 결과 모음을 반환하지만, 스트리밍 모드는 도착하는 대로 yield.

TERM
유사도 알고리즘 (Similarity Algorithm)
두 객체가 얼마나 비슷한지 0~1 점수로 매기는 방법. Scrapling은 요소의 (태그·속성·텍스트·구조) 4가지 축에서 각각 점수를 매기고 가중합. 어떤 가중치를 쓰는지는 코드를 봐야 하지만, 핵심 아이디어는 "코사인 유사도""자카드 인덱스"를 텍스트·속성 집합에 적용하는 식.

5디렉토리 구조 해부

핵심 폴더 5개만 이해하면 코드베이스가 통째로 읽힌다
Scrapling/ ├── scrapling/ ← 메인 패키지 (Python 99.9%) │ ├── __init__.py ← 공개 API 노출 (~1.5KB) │ ├── cli.py ← 명령어 라우터 (~20KB) │ │ scrapling install / shell / extract / mcp │ ├── parser.py ← ★ 적응형 셀렉터 코어 (~58KB, 단일 파일) │ │ Selector 클래스 + 유사도 매칭 + auto_save/adaptive │ ├── core/ ← 내부 유틸 (translator·storage·utils) │ │ translator.py = Parsel 호환 CSS→XPath 변환 │ ├── engines/ ← 브라우저/HTTP 엔진 어댑터 │ │ _browsers/, constants.py, │ │ static.py, toolbelt/ │ ├── fetchers/ ← Fetcher 공개 API │ │ Fetcher, AsyncFetcher, │ │ StealthyFetcher, DynamicFetcher, │ │ FetcherSession, StealthySession, ... │ ├── spiders/ ← Spider 프레임워크 │ │ Spider, Request, Response, │ │ SessionManager, Checkpoint, Stream │ └── py.typed ← PEP 561 타입 마커 (IDE에 "타입 힌트 완전" 신호) │ ├── agent-skill/ ← Claude Code Agent Skill 번들 (SKILL.md) ├── docs/ ← 다국어 README (KR/JP/CN/AR/ES/PT/FR/DE/RU) ├── tests/ ← 92% 커버리지 테스트 스위트 ├── images/ ← 스폰서/로고 이미지 ├── benchmarks.py ← BS4/Parsel/PyQuery 등과의 성능 비교 스크립트 ├── cleanup.py ← 캐시/임시 파일 정리 유틸 │ ├── Dockerfile ← python:3.12-slim-trixie + uv + Playwright ├── pyproject.toml ← 의존성 + classifiers + extras (fetchers/ai/shell/all) ├── server.json ← ★ MCP 레지스트리 명세 (PyPI + OCI 양쪽) ├── ROADMAP.md ← 향후 계획 (스키마 자동 감지, regex 자동 생성 등) │ ├── .pre-commit-config.yaml ← ruff·bandit·black 훅 ├── .bandit.yml ← 보안 정적 분석 설정 ├── ruff.toml / pytest.ini ← 린트·테스트 설정 ├── tox.ini ← 멀티 Python 버전(3.10~3.13) 테스트 ├── .readthedocs.yaml ← Read the Docs 자동 빌드 └── zensical.toml ← Zensical 문서 빌더 설정

중요도별 읽는 순서

  1. scrapling/__init__.py — 공개 API 한 페이지로 보기 (가장 먼저 읽을 것)
  2. scrapling/parser.py — 적응형 매칭 알고리즘. 58KB 단일 파일에 핵심 로직이 다 들어있다. 코드 리딩에서 가장 보람 있는 부분.
  3. scrapling/fetchers/ + engines/ — 3종 Fetcher가 어떻게 동일 인터페이스를 유지하는지
  4. scrapling/spiders/ — Spider/SessionManager/Checkpoint 구현
  5. benchmarks.py — "왜 빠른가"를 수치로 보기
  6. Dockerfile — uv 캐시 마운트 패턴 학습 (실무에 바로 적용 가능한 베스트 프랙티스)
비유

코드베이스가 마치 "스크래퍼 한 채를 통째로 지은 단독주택" 같다. parser.py 한 파일이 거실이고(여기서 다 일어남), fetchers/는 주방·욕실 같은 기능 공간, spiders/는 마당. Scrapy처럼 마이크로커널·미들웨어·확장 시스템 같은 게 없어서 "메서드 정의 찾으려면 IDE 점프 한 번이면 끝"이다.

6학습 포인트 (기술별)

Scrapling 코드를 읽으면서 자연스럽게 배우는 것들

1) lxml의 진짜 활용법

lxml은 빠르지만 API가 투박하다. Scrapling은 lxml을 베이스로 깔고 BS4 스타일·Parsel 스타일·CSS pseudo-element까지 같이 노출한다. parser.py를 읽으면:

실습: lxml로 직접 작은 셀렉터를 짜본 뒤, Scrapling이 어떻게 그 위에 추상화를 얹는지 비교.

2) TLS 지문 위조 & curl_cffi

일반 requests로 막히던 사이트가 curl_cffi.get(url, impersonate="chrome") 한 줄로 통과되는 마법. 이게 어떻게 가능한지 추적해보면 네트워크 보안 지식이 풍부해진다.

실습: 같은 사이트에 requests·httpx·curl_cffi로 각각 요청 보내고 응답 차이 관찰.

3) Playwright 스텔스 모드

Playwright는 강력하지만 navigator.webdriver=true 같은 자동화 시그널이 그대로 남는다. patchright는 어떤 시그널을 어떻게 패치하는지 코드로 학습할 수 있다.

4) Scrapy의 핵심 패턴을 미니멀하게 다시 짠 케이스 스터디

Scrapy를 다 공부하기엔 부담이지만, Spider/Request/Response/Pipeline의 본질은 scrapling/spiders/를 읽으면 1~2시간이면 잡힌다. 동시성 제어·throttling·재시도 로직이 어떻게 구현되는지가 그대로 노출.

5) asyncio + anyio 동시성 패턴

비동기 컨텍스트 매니저(async with), 세션 풀, 타임아웃 처리, asyncio.gather 사용 패턴. "비동기 코드를 동기 컨텍스트에서도 쓸 수 있게 만드는" FetcherSession의 듀얼 인터페이스 구현이 특히 볼만하다.

6) MCP 서버 구현

scrapling[ai]의 MCP 서버 코드는 "기존 Python 라이브러리에 MCP 인터페이스 얹는 법"의 표준 예제. 도구 명세·파라미터·반환 타입을 어떻게 정의하는지, stdio transport와 HTTP transport(EXPOSE 8000) 양쪽을 어떻게 지원하는지 학습.

7) uv + Docker 베스트 프랙티스

Dockerfile의 캐시 마운트 패턴은 그대로 가져다 다른 Python 프로젝트에 적용 가능:

RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --no-install-project --all-extras --compile-bytecode
COPY . .
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --all-extras --compile-bytecode

의존성을 먼저 설치하고(레이어 캐시), 그 다음에 소스 복사. 코드만 바뀌면 의존성 설치 단계는 캐시 hit.

8) Python 패키징의 모범 답안

pyproject.tomloptional-dependencies 트리(fetchersai/shellall)를 어떻게 구성했는지, classifiers·MyPy·Pyright 설정·zip-safe 플래그까지 — 그대로 베껴서 자기 프로젝트에 적용 가능한 템플릿이다.

7시스템 요구사항 & 라이선스

실제로 깔아보려면 뭐가 필요한가

최소 요구사항

설치 단계

# 1) 코어만 (파서만 필요할 때)
pip install scrapling

# 2) Fetcher까지 (HTTP 요청·브라우저 자동화 포함)
pip install "scrapling[fetchers]"
scrapling install         # Playwright 브라우저 + 시스템 의존성

# 3) 전부 (AI/MCP + 인터랙티브 셸 + Fetcher)
pip install "scrapling[all]"
scrapling install

# 4) Docker
docker pull pyd4vinci/scrapling
# 또는
docker pull ghcr.io/d4vinci/scrapling:latest

라이선스 — BSD-3-Clause

CAUTION
법적/윤리적 고려 — 스크래핑은 본질적으로 회색지대

저자가 README에 명시: "교육·연구 목적용. 사용자는 현지 데이터 수집·개인정보 법규를 준수할 책임이 있고, 항상 대상 사이트의 ToS와 robots.txt를 존중하라." Cloudflare 우회 기능이 강력한 만큼, 운영 환경에서 쓸 때는 (1) 대상 사이트의 ToS 확인, (2) robots.txt 준수, (3) 합리적인 throttling, (4) 개인정보 수집 시 GDPR/PIPA 적합성을 반드시 점검할 것.

8직접 해볼 수 있는 실습 과제

난이도 ★ ~ ★★★★★

★ 기초 — Hello, Scrapling (30분)

EXERCISE 1

quotes.toscrape.com에서 인용구 100개 긁어 JSON으로 저장

1) pip install "scrapling[fetchers]" + scrapling install
2) Fetcher.get()로 첫 페이지 가져오기
3) .css('.quote')로 인용구 추출, 각 인용구에서 .text::text·.author::text·.tag::text 뽑기
4) 다음 페이지 링크 따라가서 10페이지까지 반복
5) orjson으로 결과를 quotes.json으로 저장

학습 목표: 기본 fetch + CSS 셀렉터 + 페이지네이션 패턴 익히기.

★★ 중급 — 적응형 스크래핑 직접 검증 (1~2시간)

EXERCISE 2

Smart Element Tracking을 의도적으로 깨뜨려보기

1) 간단한 HTML 파일 2개 만들기 — v1.html(<div class="product">), v2.html(<div class="product-card">)
2) v1에 auto_save=True로 셀렉터 매칭 → 지문 저장
3) v2에 동일 셀렉터 + adaptive=True로 매칭 → 자동 재탐색 동작 확인
4) 클래스명 외에 텍스트·구조·속성이 점점 더 달라지는 케이스(v3, v4...)를 만들고 어느 지점에서 매칭이 실패하는지 측정
5) 결과를 표로 정리

학습 목표: 유사도 매칭의 강점·한계를 손으로 확인. Scrapling 마법이 어디까지 가능한지 직감 잡기.

★★★ 중상급 — Stealth 모드로 Cloudflare 통과 (2~3시간)

EXERCISE 3

nopecha.com/demo/cloudflare에서 콘텐츠 추출

1) 먼저 일반 Fetcher.get()으로 시도 → 차단 확인
2) DynamicFetcher로 시도 → 여전히 차단
3) StealthyFetcher.fetch(url, solve_cloudflare=True)로 통과
4) DevTools/네트워크 탭에서 일반 Playwright vs Patchright의 헤더 차이 비교
5) 결과를 블로그 글이나 노트로 정리

학습 목표: 봇 차단 시스템의 동작 원리 + 우회 방법 + 윤리적 경계 이해.

★★★★ 상급 — 풀크롤러 + Pause/Resume (반나절)

EXERCISE 4

HackerNews 전체 글 50000개 메타데이터 크롤링 — 도중에 끊고 재개해보기

1) Spider 클래스 정의 (start_urls = HN top stories API)
2) concurrent_requests=20, download_delay=0.5로 thro+ttling
3) crawldir="./hn_crawl" 옵션으로 시작
4) 1000개쯤 진행됐을 때 Ctrl+C → 상태 저장 확인
5) 같은 명령으로 재시작 → 멈춘 시점부터 이어지는지 검증
6) 결과를 JSONL로 export하고 분석

학습 목표: 장시간 크롤링 운영 패턴, 체크포인트 시스템 이해.

★★★★★ 고급 — MCP 서버를 Claude/Cursor에 연결 (반나절)

EXERCISE 5

Scrapling MCP를 자기 AI 도구에 등록하고 자연어로 스크래핑

1) pip install "scrapling[ai]"
2) Claude Desktop/Cursor의 MCP 설정에 Scrapling 서버 추가 (uvx scrapling mcp 또는 docker run ... scrapling mcp)
3) AI에게 자연어로 요청: "trendshift.io 메인의 상위 10개 트렌딩 레포 이름과 별 개수를 표로 정리해줘"
4) 어떤 도구를 어떤 인자로 호출했는지 로그 확인
5) 동일 요청을 직접 Scrapling 코드로 짜보고 토큰 비용/속도 비교
6) Claude Code Agent Skill(agent-skill/SKILL.md) 형식으로 자기만의 워크플로 작성

학습 목표: MCP 도구 등록·호출 패턴, "토큰 효율적인" AI 에이전트 설계.

9관련 기술 심화 학습 로드맵

Scrapling을 이해하려면 이걸 같이 알아야 한다 — 5주 코스

1주차 — HTML 파싱의 기본기

2주차 — HTTP 클라이언트와 TLS 위장

3주차 — 브라우저 자동화와 스텔스

4주차 — Spider/크롤러 아키텍처

5주차 — AI 에이전트 통합 (MCP)

10핵심 키워드 사전

Scrapling 코드/문서를 읽다 마주칠 용어 30개
FETCHER
Fetcher / StealthyFetcher / DynamicFetcher
Scrapling의 3가지 페이지 가져오기 도구. 각각 (1) curl_cffi 기반 빠른 HTTP, (2) patchright 기반 스텔스 브라우저, (3) 표준 Playwright 브라우저. 같은 인터페이스를 공유해 폴백 전략이 쉽다.
SESSION
FetcherSession / StealthySession / DynamicSession
단발 fetch가 아니라 쿠키·로그인 상태를 유지하면서 여러 요청 보낼 때 사용. with 블록으로 자원 자동 정리. FetcherSession은 동기/비동기 양쪽에서 동작.
PARSER
Selector
scrapling.parser.Selector. 파싱된 HTML 트리의 노드를 감싸는 객체. .css()·.xpath()·.find_all()·.find_similar()·.next_sibling·.parent 등 풍부한 API. lxml 노드를 직접 다룰 필요 없게 해주는 추상화.
ADAPTIVE
adaptive=True / auto_save=True
Smart Element Tracking 활성 플래그. auto_save는 매칭 결과를 디스크에 지문으로 저장. adaptive는 다음 실행 때 셀렉터가 깨졌으면 저장된 지문으로 유사한 요소 자동 검색. 한 쌍으로 사용.
IMPERSONATE
impersonate="chrome" / "firefox135"
curl_cffi에 전달되는 옵션. Chrome/Firefox/Edge의 특정 버전 TLS 지문·헤더 순서를 그대로 흉내. JA3 검사를 통과시킨다.
STEALTH
solve_cloudflare=True
StealthyFetcher 옵션. Cloudflare Turnstile/Interstitial 페이지를 자동 감지하고 통과. JS 챌린지 완료 + 쿠키 저장까지 한 번에.
SPIDER
Spider / Request / Response
Scrapy 스타일 크롤러 API. name·start_urls·concurrent_requests·async parse()로 정의. yield Request(url)로 추가 요청, yield dict로 결과 항목 산출.
CHECKPOINT
crawldir
Spider 시작 시 주는 디렉토리 경로. 큐·방문 URL·결과를 주기적으로 저장. Ctrl+C로 graceful 종료 → 같은 경로로 재시작하면 이어서 진행.
STREAM
async for item in spider.stream()
크롤이 끝나기 전에 결과가 도착하는 대로 받기. 실시간 대시보드·인덱싱 파이프라인용. 일반 모드는 result.items로 끝난 후 한꺼번에.
SESSION ROUTING
SessionManager / sid="..."
한 Spider 안에서 URL을 다른 세션으로 라우팅. 일반 페이지는 빠른 HTTP, 보호 페이지만 스텔스 브라우저로 처리하는 식.
DEV MODE
Response Caching
개발 모드에서 첫 응답을 디스크에 캐시. 이후 같은 요청은 캐시 사용. parse() 로직 디버깅을 빠르게.
TLS-FP
JA3 / JA4
TLS 핸드셰이크 패킷을 해싱한 봇 탐지 지문. requests의 urllib3 스택과 진짜 Chrome은 JA3 값이 달라서 잘 보호된 사이트는 즉시 차단. curl_cffi가 이를 우회.
BR-FP
Browser Fingerprint
User-Agent + Accept-Language + screen 크기 + WebGL 렌더러 + 폰트 목록 + 캔버스 해시 등을 조합한 클라이언트 식별값. browserforge가 실 사용자 통계에서 일관된 조합을 생성.
MCP
Model Context Protocol
Anthropic이 표준화한 AI 도구 호출 프로토콜. AI 에이전트가 외부 함수를 호출해 결과를 받는 방식을 통일. Scrapling은 uvx scrapling mcp로 stdio 기반 MCP 서버 실행.
PSEUDO
::text / ::attr(href)
CSS 셀렉터에 Scrapy/Parsel이 도입한 pseudo-element. 표준 CSS 아님. .title::text는 매칭된 요소의 직접 텍스트, a::attr(href)는 href 속성값. Scrapling이 이걸 지원.
ROBOTS
robots.txt / Protego / robots_txt_obey
사이트 루트의 /robots.txt에 명시된 크롤러 정책. Disallow·Crawl-delay·Request-rate. Spider 옵션 robots_txt_obey=True로 자동 준수, Protego 라이브러리가 파싱.
BLOCK
Domain Blocking / Ad Blocking
브라우저 Fetcher에서 특정 도메인 요청 차단(block_resources) 또는 알려진 광고/추적 도메인 ~3500개 자동 차단. 속도와 대역폭 절감.
DOH
DNS-over-HTTPS
DNS 쿼리를 평문 UDP가 아니라 HTTPS로 보내는 방식. 프록시 사용 시 DNS가 ISP를 통해 새는 "DNS Leak"을 막음. Scrapling은 Cloudflare DoH 사용 옵션 제공.
PROXY
ProxyRotator
프록시 IP 풀을 순환·랜덤·커스텀 전략으로 회전. 모든 세션 타입에 일관 적용 가능. 요청별 override도 지원.
TYPING
py.typed / Pyright / MyPy
PEP 561 마커 파일. py.typed가 패키지에 있으면 IDE/타입 체커가 "이 패키지는 타입 힌트 완비"로 인식. Scrapling은 Pyright + MyPy 양쪽으로 매 변경마다 자동 검사.
EXTRACT
scrapling extract / shell
CLI 명령. scrapling extract get URL out.md로 코드 없이 URL→마크다운/텍스트/HTML 추출. scrapling shell은 IPython 기반 인터랙티브 환경 (curl 명령을 Scrapling 코드로 변환하는 단축키 등).
UV
uv (Astral)
Astral이 만든 Rust 기반 Python 패키지 매니저. pip 대비 10~100배 빠름. Scrapling Dockerfile에서 의존성 설치에 사용. uv sync로 락 파일 기반 설치.
ORJSON
orjson
Rust로 짠 JSON 직렬화 라이브러리. 표준 라이브러리 json보다 ~10배 빠름. Scrapling 내부의 result.items.to_json/to_jsonl 모두 orjson.
FRAMEWORK
Patchright
Playwright의 스텔스 패치 포크. navigator.webdriver 제거, 자동화 시그널 차단, 인간형 마우스 패턴 등. 표준 Playwright API와 호환되면서 봇 탐지를 회피.
CFFI
curl_cffi
curl-impersonate(Chrome/Firefox TLS 스택 흉내내는 curl 포크)의 Python 바인딩. impersonate="chrome" 한 인자로 JA3 우회.
SCRAPY-LIKE
Parsel / w3lib
Scrapy 팀이 만든 독립 라이브러리들. Parsel은 셀렉터 API, w3lib는 URL/HTML 헬퍼. Scrapling은 둘 다 가져다 자체 셀렉터를 구현했다.
ASYNC
AsyncFetcher / AsyncStealthySession
모든 Fetcher의 비동기 버전. asyncio.gather로 수십~수백 요청 동시 실행. 풀크롤러에선 필수.
CONFIG
concurrent_requests / download_delay / max_pages
Spider 설정. 동시 요청 수 / 요청 사이 지연 / 브라우저 탭 풀 크기. throttling과 메모리 관리.
CLOUDFLARE
Turnstile / Interstitial / 5초 챌린지
Cloudflare가 봇을 거르는 3가지 화면. Turnstile은 사용자 인지 가능한 체크박스, Interstitial은 "5초만 기다려주세요" 페이지, 챌린지는 JS 실행 검증. Scrapling이 셋 다 자동 통과.
SIMILARITY
find_similar() / below_elements()
Selector 메서드. 현재 요소와 유사한 요소들 / 현재 요소 아래에 나오는 요소들을 자동 검색. 사이트 구조를 모르고도 "이거랑 비슷한 다른 항목들" 찾기 가능.

11참고 링크

더 깊이 파고들 때 봐야 할 것들

공식

한국어 문서

핵심 의존성 학습 자료

비교 학습 자료

봇 탐지 / 우회 학습