크롤러
웹 크롤러를 먼저 머릿속에 그리기
웹 크롤러를 단순한 다운로드 프로그램이 아니라 웹이라는 거대한 연결망을 돌아다니는 자동 수집 시스템으로 이해합니다.
웹 크롤러는 몇 개의 시작 URL에서 출발해 웹 페이지를 내려받고, 그 안에서 새로운 링크를 찾아 다시 방문하는 작업을 반복하는 시스템입니다. 핵심은 한 페이지를 가져오는 것이 아니라 발견 → 방문 → 분석 → 새로운 주소 발견 → 다시 방문이라는 순환을 자동으로 계속하는 데 있습니다.
웹을 거대한 도시라고 생각하면 이해하기 쉽습니다. 웹 페이지는 건물이고, URL은 주소이며, 링크는 건물과 건물을 연결하는 길입니다. 크롤러는 이 도시를 돌아다니며 어떤 건물이 어디에 있는지 기록하는 조사원과 비슷합니다.
설계 전에 요구사항부터 정하기
좋은 시스템 설계는 기술을 고르는 것보다 무엇을 얼마나 처리해야 하는지 명확히 정의하는 것에서 시작합니다.
같은 웹 크롤러라도 목적과 규모에 따라 필요한 구조가 완전히 달라지기 때문입니다. 특정 회사 홈페이지 1만 개를 수집하는 시스템과 검색 엔진처럼 수십억 페이지를 수집하는 시스템은 필요한 서버, 네트워크, 저장 공간이 전혀 다릅니다. 그래서 먼저 무엇을, 얼마나, 얼마나 자주, 얼마나 오래 수집할지를 정해야 합니다.
전체 크롤링 흐름 이해하기
URL 하나가 시스템에 들어와 페이지가 저장되고 새로운 URL이 다시 큐에 들어가기까지의 전체 생명주기를 살펴봅니다.
URL은 먼저 방문 대기 목록에 들어가고, 다운로더가 이를 꺼내 페이지를 내려받습니다. 내려받은 문서는 파싱과 검증을 거친 뒤 중복 여부를 확인하고, 새로운 콘텐츠라면 저장합니다. 그 페이지에서 다시 URL을 추출해 필터링하고 처음 보는 주소만 방문 대기 목록에 넣으면서 같은 과정이 반복됩니다.
URL Frontier → Downloader → Parser → Duplicate Check → Content Store → URL Extractor → URL Filter → Visited Check → URL Frontier로 기억하면 됩니다.웹을 그래프로 바라보기
페이지와 링크를 그래프로 생각하면 크롤러가 왜 BFS와 큐를 사용하는지 자연스럽게 이해할 수 있습니다.
웹 페이지 하나를 노드, 페이지 사이의 링크를 간선이라고 보면 웹 전체가 거대한 그래프가 됩니다. 크롤러는 현재 페이지에서 연결된 다른 페이지를 발견하면서 이 그래프를 이동합니다. 그래서 DFS와 BFS 같은 그래프 탐색 개념이 웹 크롤링 설계에도 등장합니다.
URL Frontier: 크롤러의 교통관제센터
수십억 개의 URL 중 무엇을 언제 방문할지 결정하는 URL Frontier의 역할을 이해합니다.
URL Frontier는 단순한 URL 목록이 아니라 크롤러의 스케줄러에 가깝습니다. 어떤 페이지를 먼저 방문할지, 같은 사이트를 언제 다시 요청할지, 이미 처리한 URL을 다시 넣을지 등을 결정합니다. 사람으로 비유하면 수많은 배달 주문을 기사들에게 배분하는 관제센터와 비슷합니다.
Politeness: 빠르게보다 예의 바르게
크롤러가 상대 웹사이트를 공격하지 않으면서 안정적으로 데이터를 수집하는 방법을 이해합니다.
크롤러가 특정 웹사이트에 너무 많은 요청을 보내면 상대 서버에 큰 부하를 줄 수 있기 때문입니다. 예를 들어 같은 사이트에 수백 개 Worker가 동시에 요청하면 정상적인 크롤링도 DoS 공격과 비슷한 결과를 낼 수 있습니다. 그래서 대규모 크롤러는 처리량뿐 아니라 사이트별 요청 속도를 반드시 제어합니다.
중요한 페이지를 먼저 수집하기
모든 URL을 똑같이 대하지 않고 가치가 높은 페이지를 우선해서 수집하는 이유와 방법을 이해합니다.
크롤링 자원은 한정되어 있지만 발견되는 URL은 사실상 끝이 없기 때문입니다. 검색 엔진이라면 중요한 공식 문서나 인기 페이지를 먼저 수집하는 것이 이름도 없는 저품질 페이지를 먼저 수집하는 것보다 가치가 높습니다. 따라서 URL마다 중요도를 계산해 처리 순서를 조정합니다.
HTML Downloader와 네트워크 병목
웹 페이지를 실제로 가져오는 과정에서 DNS, 타임아웃, 분산 처리 같은 네트워크 문제를 살펴봅니다.
실제 대규모 다운로더는 URL을 받아 DNS 조회, 연결, HTTP 요청, 응답 검사, 타임아웃, 실패 처리까지 수행해야 합니다. 수많은 사이트의 응답 속도와 상태가 모두 다르기 때문에 외부 네트워크의 불확실성을 견뎌야 합니다. 그래서 다운로더는 크롤러에서 가장 병목이 되기 쉬운 컴포넌트 중 하나입니다.
robots.txt와 크롤링 규칙
기술적으로 접근할 수 있는 페이지라고 해서 모두 마음대로 수집하는 것은 아니라는 점을 이해합니다.
robots.txt는 웹사이트 운영자가 크롤러에게 어떤 경로를 수집하지 말아 달라고 알려주는 표준적인 규칙 파일입니다. 크롤러는 사이트를 방문하기 전에 해당 파일을 확인하고 자신의 User-agent에 적용되는 규칙을 읽습니다. 이를 지키는 것은 Politeness와 책임 있는 크롤링의 기본 요소입니다.
중복 URL과 중복 콘텐츠 구분하기
같은 주소를 다시 방문하는 문제와 다른 주소에서 같은 내용을 얻는 문제를 구분해 해결합니다.
두 문제는 서로 다릅니다. 중복 URL은 같은 주소를 또 방문하려는 문제이고, 중복 콘텐츠는 주소는 다른데 내용이 같은 문제입니다. 따라서 실제 크롤러에서는 URL 방문 기록과 콘텐츠 중복 기록을 별도로 관리해야 합니다.
Freshness와 Recrawl
웹은 계속 바뀌므로 한 번 수집하고 끝내지 않고 필요한 페이지를 적절한 주기로 다시 방문해야 합니다.
웹 페이지는 새로 생기고 수정되고 삭제되기 때문에 한 번 수집한 데이터는 시간이 지날수록 현실과 달라집니다. 검색 엔진이나 모니터링 시스템이라면 현재 상태를 반영하기 위해 페이지를 다시 방문해야 합니다. 이 작업을 Recrawl이라고 합니다.
안정성과 장애 대응
대규모 시스템에서는 실패가 예외가 아니라 일상이라는 관점으로 크롤러를 설계합니다.
좋은 대규모 크롤러라면 일부 서버가 고장 나도 전체 작업은 계속되어야 합니다. 크롤링 상태와 수집 결과를 지속적으로 저장하고, 실패한 작업은 다른 Worker가 이어받을 수 있게 설계합니다. 핵심은 일부 실패가 전체 실패로 확대되지 않게 만드는 것입니다.
확장 가능한 구조 만들기
처음에는 HTML만 수집하더라도 나중에 새로운 콘텐츠와 기능을 쉽게 추가할 수 있도록 설계합니다.
웹의 형태와 서비스 요구사항은 계속 바뀌기 때문입니다. 처음에는 HTML만 처리하다가 나중에는 PDF, PNG, 동영상, 웹 모니터링 기능이 필요해질 수 있습니다. 기존 시스템 전체를 뜯어고치지 않고 새로운 모듈을 붙일 수 있어야 유지보수가 쉬워집니다.
스파이더 트랩과 데이터 노이즈
웹에는 크롤러의 자원을 끝없이 소모시키거나 가치 없는 데이터를 대량으로 만들어내는 구조도 존재합니다.
스파이더 트랩은 크롤링 자원을 낭비시키는 대표적인 문제입니다. 예를 들어 /foo/bar/foo/bar/foo/bar/...처럼 경로가 계속 길어지면 크롤러는 매번 새로운 페이지라고 생각할 수 있습니다. 이런 구조에 빠지면 특정 사이트만 무한히 탐색하게 됩니다.
JavaScript 기반 웹과 현대적인 크롤링
HTML만 내려받아서는 보이지 않는 동적 콘텐츠를 어떻게 처리할지 이해합니다.
그럴 수 있습니다. 현대 웹사이트는 처음 받은 HTML에는 뼈대만 있고 JavaScript가 실행된 뒤 서버에서 데이터를 받아 실제 내용을 만드는 경우가 많습니다. 이런 페이지는 단순 HTTP 다운로드만으로는 사용자가 보는 최종 콘텐츠를 얻지 못할 수 있습니다.
전체 설계를 하나의 그림으로 연결하기
지금까지 배운 컴포넌트가 왜 존재하는지 하나의 시나리오로 다시 연결해 봅니다.
먼저 URL Frontier가 중요도와 호스트별 요청 제한을 고려해 처리할 URL 하나를 선택합니다. Downloader는 robots.txt와 DNS 정보를 확인해 페이지를 받고, Parser가 문서를 검증한 뒤 콘텐츠 중복 여부를 검사해 필요한 경우 저장합니다. 이후 URL Extractor가 새 링크를 뽑고 URL Filter와 방문 여부 검사를 거친 주소를 다시 Frontier에 넣으며, 이미 수집한 페이지는 Freshness 정책에 따라 나중에 Recrawl 대상으로 예약할 수 있습니다.
무엇을 방문할지 결정하는 문제, 안전하게 다운로드하는 문제, 쓸모 있는 것만 저장하는 문제, 언제 다시 방문할지 결정하는 문제의 결합입니다.