블로그로 돌아가기

파서가 빈 필드를 반환하고 프록시는 관계없다: 레이아웃 드리프트 수정하기

파서가 빈 값을 반환했습니다. 프록시를 변경하고 있지만 문제는 사이트의 리디자인에 있었습니다. 5분 만에 차단과 드리프트 레이아웃을 구분하는 방법, Scrapling의 적응형 선택자가 어떻게 작동하는지(요소의 SQLite 지문과 유사성 검색이 2.46ms 소요됨) 및 기준을 동일한 지오에서 가져와야 하는 이유를 살펴보겠습니다.

📅2026년 9월 5일
파서가 빈 필드를 반환하고 프록시는 관계없다: 레이아웃 드리프트 수정하기

파서가 반년 동안 작동했지만 오늘 데이터베이스에 빈 줄이 추가되었습니다. 첫 번째 생각은 — 차단당했으니 프록시를 변경해야 한다는 것입니다. 풀을 변경하고 IP 품질을 높이며 데이터 센터 대신 레지던트 IP에 비용을 지불해도 필드는 여전히 비어 있습니다. 그 이유는 차단이 아니라 사이트가 새로운 레이아웃으로 이전했기 때문이며, 귀하의 CSS 선택자는 더 이상 아무것에도 연결되어 있지 않습니다.

이것은 가장 비싼 유형의 고장입니다. 왜냐하면 그것은 조용하기 때문입니다. 차단은 즉시 보입니다: 403, CAPTCHA, 리디렉션. 레이아웃의 드리프트는 아무것도 떨어뜨리지 않습니다 — HTTP 200, 페이지가 수신되었고, 트래픽이 지불되었지만 결과는 None입니다. 5분 만에 하나를 다른 것과 구별하는 방법과 각 리디자인 후 수동으로 선택기를 다시 작성하는 것을 중단하는 방법을 살펴보겠습니다.

누가 필요로 하는가

한 스프린트 이상 파서를 운영하는 사람들을 위한 가이드: 경쟁사 가격 모니터링, 리뷰 수집, 채용 공고 집계, 분석을 위한 일일 데이터 추출. 스크립트를 한 번 실행하고 버리는 경우 레이아웃의 드리프트는 귀하와 관련이 없습니다. 스크립트가 몇 달 동안 cron에서 실행되는 경우 이는 유지 관리의 주요 비용 항목입니다.

문제의 규모는 허구가 아닙니다. GroupBWT 분석가의 추정에 따르면, 웹사이트의 관리되지 않는 구조적 변화는 대규모 프로젝트에서 스크래퍼 유지 관리에 대한 약 40–60%의 반복 비용을 발생시킵니다. 특정 산업에서는 10–15%의 크롤러가 매주 수리가 필요합니다 — DOM 이동, 핑거프린팅 및 엔드포인트의 스로틀링 때문입니다. 즉, 선택기 수리는 안티봇 우회 비용과 경쟁하며, 이에 대한 관심은 훨씬 적습니다.

배경은 좋지 않습니다: Apify의 "웹 스크래핑 상태 2026" 보고서에 따르면 65.8%의 응답자가 프록시 사용을 증가시켰고, 58.3%는 연간 프록시 비용 증가를 언급했으며, 62% 이상은 주로 봇 방어 강화로 인한 인프라 비용의 전반적인 증가를 보고했습니다. 이러한 배경에서, 아무것도 얻지 못하는 페이지에서 지불된 트래픽을 소모하는 것은 두 배로 억울합니다.

1단계. 차단과 레이아웃 드리프트 구별하기

진단은 몇 분이 걸리며 순서대로 수행해야 합니다 — 그렇지 않으면 잘못된 고장을 "수리"하기 쉽습니다.

  1. 응답 코드와 본문 크기를 확인하세요. 403, 429, 503, 확인 페이지로의 리디렉션 또는 2–5 KB의 본문 — 이는 안티봇입니다. HTTP 200과 200–800 KB의 완전한 페이지 — 사이트가 귀하를 허용했으며, 프록시 문제는 아닙니다.
  2. 원시 HTML을 디스크에 저장하고 눈으로 열어보세요. 디버거가 아니라 브라우저에서. 상품/리뷰/가격이 제자리에 있지만 파서가 이를 보지 못한다면 — 이는 레이아웃 드리프트입니다.
  3. 파일에서 필요한 텍스트를 검색하세요. HTML에 있지만 귀하의 선택기로는 접근할 수 없다면 — 마크업이 변경되었습니다. 전혀 없다면 — 콘텐츠가 스크립트로 로드되며, HTTP 요청이 아닌 브라우저 엔진이 필요합니다.
  4. 이전의 성공적인 추출과 비교하세요. 동일한 URL의 이전 HTML과 새로운 HTML을 비교하세요: 일반적으로 새로운 클래스 래퍼, 이동한 블록 또는 iddata-*로 변경된 것을 즉시 볼 수 있습니다.
  5. 사이트가 다른 버전의 페이지를 제공하지 않았는지 확인하세요. 이에 대해서는 아래에서 별도로 설명합니다. 왜냐하면 여기서 프록시가 여전히 관련이 있기 때문입니다.

세 번째 항목 후 진단이 "마크업이 이동했다"면 프록시를 변경하는 것은 무의미합니다. 선택기가 만료된 경우에도 요소를 찾을 수 있는 파서가 필요합니다.

2단계. 적응형 선택기란 무엇인가

아이디어는 간단합니다: .product-card > h3.title와 같은 문자열에 고정되지 않고, 라이브러리는 한 번 필요한 요소의 "초상화"를 기억하고 다음 실행 시 이 초상화와 가장 유사한 요소를 페이지에서 찾습니다.

가장 실용적으로 구현된 것은 Scrapling입니다 — 카림 쇼아르의 오픈 소스 Python 프레임워크입니다. 이 프로젝트는 2024년 10월에 출시되었으며 2026년 9월까지 GitHub에서 78,000개 이상의 별을 모았습니다; 작성 시점의 최신 릴리스는 2026년 8월 23일의 v0.4.15이며, 커밋은 매일 이루어집니다. Python 3.10+가 필요합니다.

적응형 검색의 메커니즘은 다음과 같습니다. auto_save=True로 선택기를 호출하면 Scrapling은 요소의 지문을 저장합니다:

  • 태그 이름, 텍스트 및 모든 속성과 그 값;
  • 이웃 태그의 이름;
  • 요소까지의 경로 — 태그 이름만으로;
  • 부모의 태그, 속성 및 텍스트.

지문은 로컬 SQLite 데이터베이스에 저장되며 "도메인 + 식별자" 쌍으로 키가 지정됩니다. 도메인은 페이지의 URL에서 가져오거나 adaptive_domain 매개변수로 설정되며, 기본 식별자는 선택기 문자열 자체입니다 — 또는 identifier=를 전달하면 귀하의 것입니다.

레이아웃이 변경되고 일반 선택기가 빈 값을 반환하면 adaptive=True 호출은 저장된 지문을 불러오고 페이지의 모든 요소를 통해 실행하여 유사성의 흐릿한 평가를 계산합니다 — 속성의 순서까지도. 가장 높은 일치를 가진 요소가 반환됩니다.

비용은 저렴합니다. 프로젝트의 공식 벤치마크에 따르면, 파싱은 1.99 ms가 소요되며, Parsel/Scrapy의 2.01 ms, PyQuery의 22.93 ms, Selectolax의 80.57 ms, BeautifulSoup의 1541 ms와 비교됩니다. 유사한 요소에 대한 적응형 검색 자체는 2.46 ms로 AutoScraper의 13.3 ms와 비교됩니다. 즉, 리디자인에 대한 보험은 수백 밀리초의 네트워크 지연 속에서 요청에 약 두 밀리초를 추가합니다.

3단계. 설치 및 활성화

설치는 브라우저가 필요한지에 따라 다릅니다:

  1. pip install scrapling — 네트워크 부분 없이 파서만 설치합니다. HTML을 자신의 코드로 가져오는 경우 충분합니다.
  2. pip install "scrapling[fetchers]", 그 다음 scrapling install — 페처를 추가하고 종속성과 함께 브라우저를 다운로드합니다.
  3. 추가: [ai] — MCP 서버, [rag] — RAG에 대한 래퍼, [shell] — 대화형 콘솔, [all] — 모두 포함. 준비된 이미지 pyd4vinci/scrapling이 있습니다.

그 다음 두 번의 실행이 필요합니다. 첫 번째는 실제 작업 레이아웃에서 지문을 저장하고, 두 번째는 리디자인을 견딜 수 있습니다:

  1. 기준 실행. adaptive=TrueSelector 객체를 생성하고 반드시 url을 전달하세요 — 그렇지 않으면 도메인이 "default" 키로 이동하고 서로 다른 사이트의 지문이 섞입니다. 필요한 선택기를 auto_save=True로 호출하세요.
  2. 전투 실행. 동일한 선택기지만 adaptive=True로 설정합니다. 마크업이 유지되는 동안 일반 경로가 작동합니다. 고장이 나면 유사성 검색이 활성화됩니다.
  3. 차이를 기록하세요. 일반 선택기가 빈 값을 반환하고 적응형 선택기가 무언가를 찾는 순간은 "사이트가 이전"이라는 신호입니다. 이를 모니터링에서 확인해야 하며 조용히 넘겨서는 안 됩니다.

재작성에 대한 중요한 세부 사항: 저장은 누적되지 않습니다. 동일한 "도메인 + 식별자" 쌍에 대한 반복 auto_save는 이전 지문을 덮어씁니다. 따라서 기준은 확실히 올바른 페이지에서 찍어야 하며, URL 풀 전체를 순회하는 것이 아닙니다.

4단계. 프록시: 어디에 관련이 있는가

우리는 레이아웃 드리프트가 프록시와 관련이 없다고 시작했습니다. 이는 정확히 반만 맞고, 나머지 반은 비용이 듭니다.

사이트가 프록시의 출구로 인해 다른 마크업을 제공할 수 있습니다. 로컬, 언어 및 국가가 페이지 템플릿을 변경합니다: 블록의 순서, 클래스, 가격 및 날짜 형식이 다릅니다. 이는 가설이 아닙니다 — Scrapling 자체에는 주목할 만한 수정이 있습니다: 0.4.12 버전에서 StealthyFetcher의 강제 로컬 en-US가 제거되었습니다. 왜냐하면 강제된 로컬이 실제 지오와 일치하지 않아 동작을 깨뜨렸기 때문입니다. 따라서 작업 규칙은 다음과 같습니다: 데이터를 수집할 때와 동일한 지오에서 기준 지문을 찍으세요. 독일 IP를 통해 찍은 지문은 브라질을 통해 수신한 페이지와 일치하지 않을 것이며, "사이트가 레이아웃을 변경했다"는 잘못된 경고를 받을 것입니다.

실용적인 결과:

  • 풀의 국가가 여러 개인 경우 adaptive_domain을 통해 지문을 분리하여 "도메인 + 국가" 형식의 키를 설정하세요. 그렇지 않으면 SQLite의 한 레코드가 서로 다른 지오의 버전으로 계속 덮어씌워집니다.
  • 긴 시나리오의 경우 하나의 국가와 하나의 세션을 전체 작업에 유지하세요. 이를 설정하는 방법은 스티키 세션과 사용 시기에 대한 자료에서 자세히 설명되어 있습니다.
  • A/B 테스트와 점진적 롤아웃은 동일한 도메인에서 두 개의 활성 레이아웃을 제공합니다. 여기서 적응형 검색은 특히 유용합니다: 두 가지 분기에서 요소를 추출할 수 있으며, 반면에 고정 선택기는 요청의 절반에서 무작위로 빈 값을 반환할 것입니다.

Scrapling에서 프록시를 설정할 수 있는 모든 수준이 있습니다. 빠른 HTTP 요청을 위해 FetcherAsyncFetcher에는 proxies 매개변수가 있습니다. 세션을 위해 ProxyRotator가 있으며, 주소 목록을 전달하면 FetcherSession에 삽입됩니다. 브라우저 DynamicSessionStealthySession은 세션 수준에서 프록시를 수용하여 IP가 시나리오 중간에 변경되지 않도록 합니다.

또한 풀과 신경을 절약하는 또 다른 기능이 0.4.12 버전에서 추가되었습니다 — AutoThrottle: 라이브러리는 서버의 응답에 따라 요청 간의 지연을 자동으로 조정하며, 차단 시 지연을 두 배로 늘리고 Retry-After 헤더를 존중합니다. 이는 신중한 수집과 단순한 재시도로 인한 차단을 구별하는 행동입니다.

주의할 점

  • SQLite 지문을 git에 커밋하지 마세요. 문서에서 직접 경고합니다. 개인 데이터가 있는 페이지에서 auto_save를 사용하지 마세요 — 지문에 요소의 텍스트와 속성이 포함됩니다.
  • 적응형 검색은 모니터링을 대체하지 않습니다. "가장 유사한" 요소를 반환하지만, 가장 유사한 것이 항상 올바른 것은 아닙니다. 사이트가 할인 가격과 정가를 서로 바꿨다면 유사성이 높지만 데이터는 잘못될 수 있습니다. 값의 범위와 추출에서 빈 필드의 비율을 확인하세요.
  • 조용한 고장은 시끄러운 고장보다 비쌉니다. 선택기가 조용히 None을 반환하는 동안 파이프라인은 페이지를 계속 탐색하고 지불된 트래픽을 소모합니다. 데이터가 추출되지 않은 기가바이트의 실제 비용에 대한 별도의 분석이 있습니다 — 왜 GB당 프록시 비용이 거짓말을 하는가.
  • 지문은 노후화됩니다. 확인된 리디자인 후 기준을 다시 찍어야 하며, 그렇지 않으면 다음 사이트 수정이 구식 초상화로 간주되어 정확도가 떨어집니다.
  • HTML에 콘텐츠가 전혀 없는 경우 — 적응성은 도움이 되지 않으며, 브라우저 페처가 필요합니다. 0.4.15에서 브라우저 탭이 요청 간에 재사용되며, close_pages() 메서드는 이를 강제로 닫습니다; 또한 헤드리스 모드에서의 정지 문제를 수정했으며 Turnstile 솔루션은 브라우저의 로컬에 의존하지 않게 되었습니다.

이 작업에 적합한 프록시 유형은 무엇인가

선택은 파서가 아니라 대상 웹사이트에 의해 결정됩니다:

  • 데이터 센터 프록시 — 심각한 안티봇이 없는 웹사이트에 적합합니다: 문서, 정부 등록부, 공개 디렉토리, RSS 및 CSV 피드(마지막으로 0.4.13에서 XMLFeedSpiderCSVFeedSpider가 자동으로 gzip을 풀도록 추가되었습니다). 저렴하고 빠르며, 여기서 마크업의 안정성이 일반적으로 더 높습니다.
  • 레지던트 프록시 — 마켓플레이스, 집계기 및 지오에 따라 결과를 개인화하는 모든 것에 적합합니다. 여기서는 기준을 찍고 동일한 국가에서 데이터를 수집하는 것이 중요합니다. 그렇지 않으면 고장을 수리하는 것이 아니라 자신의 지리적 문제를 해결하게 됩니다.
  • 모바일 프록시 — 사이트가 모바일 템플릿을 제공하고 이를 그대로 파싱해야 하거나, IP에 대한 신뢰가 기가바이트 비용보다 중요할 때 사용합니다.

간단히 말해

추출에서 빈 필드는 두 가지 다른 진단과 다른 치료법을 의미합니다. 먼저 응답 코드와 원시 HTML을 확인하세요: 페이지가 온전히 수신되었다면 프록시를 변경할 필요가 없으며, 마크업이 이동했습니다. Scrapling의 적응형 선택기는 이 유형의 고장을 요청당 몇 밀리초 내에 처리합니다 — 작업 레이아웃에서 지문을 저장하고, 전투에서 adaptive=True를 활성화하고, 리디자인 신호로 작동 순간을 기록하세요. 그리고 지오를 안정적으로 유지하세요: "갑작스러운 리디자인"의 절반은 실제로는 다른 언어 버전의 페이지가 국가 변경으로 인해 온 것입니다.

안정적인 지오와 예측 가능한 세션이 귀하의 파서에 부족하다면 ProxyCove의 레지던트 프록시를 살펴보세요: 국가 선택, 스티키 세션 및 실제 사용된 트래픽에 대한 지불.