본문으로 건너뛰기
네트워크 보안

웹 스크래핑 탐지 방법: 로그, IP 조회, 그리고 사각지대

액세스 로그에서 웹 스크래핑을 탐지하는 방법: CCBot, AhrefsBot, Tor 출구, 클라우드 서버의 실제 조회 결과와 추적한 Googlebot 사칭 사례, 그리고 IP로는 보이지 않는 것들.

작성자GeoIPHub 팀게시일읽는 시간35분 분량
끌려 나가는 데이터 타일 행의 추상 이미지, 웹 스크래핑을 나타냄

스크래퍼의 요청 하나는 그저 GET일 뿐입니다. 다른 로그 줄과 마찬가지로 상태 코드, 경로, User-Agent가 있습니다. 스크래핑은 수백 줄에 걸쳐, 그리고 네트워크 단위로 보아야 드러납니다. 클라우드 서버의 파이썬 스크립트, Puppeteer나 Playwright로 구동되는 헤드리스 브라우저, AI 학습용 크롤러, AhrefsBot 같은 SEO 크롤러, 또는 로테이팅 프록시를 기가바이트 단위로 파는 스크래핑 API가 모두 그 예입니다.

2026-10-08에 스크래퍼 유형의 IP 7개를 GeoIPHub API로 조회했습니다. 검증된 크롤러 4개(Googlebot, CCBot, ClaudeBot, AhrefsBot)는 모두 호스팅 네트워크에서 왔고 allow를 받았습니다. 일반 Linode 클라우드 서버는 10점으로 역시 allow였고, Tor 출구와 Mullvad VPN 서버는 둘 다 100점, block이었습니다. IP가 알려 주는 것은 네트워크입니다. 스크래핑 여부의 판단은 로그에서 나옵니다.

아래에서는 액세스 로그에서 스크래핑 봇을 탐지하는 방법, Googlebot이라고 주장하는 로그 한 줄의 추적, IP 데이터가 한계를 드러내는 지점, 그리고 확인한 결과를 허용, 요청 제한, 챌린지, 차단으로 대응시키는 방법을 다룹니다. IP 신호를 하나씩 먼저 보고 싶다면 허브 글 IP 기반 봇 탐지, 신호별 정리를 참고하십시오. 이 글은 그 신호를 스크래핑에 적용합니다.

밝은 막대로 표현된 추상적인 액세스 로그, 그중 일부가 기계적인 리듬으로 깜박이며 로그 속 스크래퍼 트래픽을 나타냄
스크래퍼는 다른 어떤 흔적보다 먼저 액세스 로그에 리듬을 남깁니다.

웹 스크래핑 탐지 방법: 속도, 경로, 클라이언트, 네트워크

웹 스크래핑을 탐지하려면 네 가지 신호군을 확인합니다. 얼마나 빠르게 요청하는가(속도), 무엇을 어떤 순서로 요청하는가(경로), 자신에 대해 무엇을 말하는가(클라이언트), 어디서 접속하는가(네트워크)입니다. OWASP는 스크래핑을 독립된 자동화 위협 OAT-011로 분류하고, 이를 "다른 곳에서 사용하기 위해 애플리케이션 콘텐츠 및/또는 기타 데이터를 수집하는 것"으로 정의합니다(OWASP Automated Threats). 이 정의는 의도에 관한 것이어서 눈에 보이지 않습니다. 눈에 보이는 것은 앞의 네 가지 신호군입니다.

  • 속도. IP별, 그리고 네트워크별 분당 요청 수입니다. 여기서 네트워크는 ASN, 더 세밀하게 묶으려면 IPv4의 /24와 IPv6의 /64를 뜻합니다. 스크래퍼는 종종 24시간 일정한 속도로 동작하는 반면, 사람은 몰아서 접속하고 잠도 잡니다.
  • 경로. 목록과 페이지네이션 URL을 순서대로 따라가기, 사이트맵을 위에서 아래로 읽기, 상품이나 가격 페이지만 요청하기, CSS, JavaScript, 이미지 요청이 전혀 없는 것입니다.
  • 클라이언트. User-Agent 주장, 없는 Accept-Language 헤더, 요청 사이에 유지되지 않는 쿠키, 자동화 표식입니다. 브라우저에서는 Chrome이 --headless나 --enable-automation으로 실행되면 navigator.webdriver가 true가 되지만(MDN), 작정한 스크래퍼는 이 값을 지웁니다. 엣지에서는 TLS 핑거프린트(JA3 또는 JA4)가 Chrome이라고 주장하는 User-Agent 뒤의 HTTP 라이브러리를 드러내는 경우가 많습니다.
  • 네트워크. IP 조회가 반환하는 정보입니다. API가 detection.is_hosting으로 표시하는 데이터센터(호스팅) IP, 검증된 크롤러, Tor, VPN, 스캐너가 해당합니다.

웹 스크래핑 탐지가 어려운 이유는 모든 신호에 무해한 쌍둥이가 있기 때문입니다. 오리진을 가져가는 CDN, 업타임 모니터, 하나의 NAT 주소 뒤에 있는 사무실, RSS 리더는 모두 한 축에서는 이상해 보입니다. 스크래핑이라는 판단은 신호들이 서로 일치할 때 성립합니다.

신호스크래퍼의 모습무해한 유사 사례
IP 또는 네트워크별 요청 속도몇 시간 동안 1~2초마다 일정하게 요청사무실 NAT, CGNAT, CDN 또는 모니터링 서비스
페이지 순서page=1, 2, 3 … 순서대로, 또는 파일 순서 그대로의 사이트맵검색 결과를 넘겨 보는 사람, 단 페이지 수는 훨씬 적음
에셋HTML만 요청, CSS, JS, 이미지 없음피드 리더, 링크 미리보기, 텍스트 브라우저
세션 깊이한 세션에서 수천 페이지내부 QA 크롤링 또는 자사 SEO 감사 도구
User-Agent해당 크롤러가 쓰지 않는 네트워크에서 온 크롤러 이름최근 며칠 사이에 추가된 대역의 실제 크롤러
네트워크데이터센터, Tor 또는 VPN 출구기업 VPN, AI 쇼핑 에이전트, 클라우드에서 호스팅되는 도구

내 웹사이트가 스크래핑당하는지 확인하는 방법: 먼저 액세스 로그를 읽으십시오

웹사이트가 스크래핑당하는지 확인하려면 액세스 로그를 네트워크별로 묶어, 많은 페이지를 순서대로 가져오면서 브라우저가 불러오는 에셋은 전혀 요청하지 않는 클라이언트를 찾으십시오. 바깥에서 보이는 징후가 먼저 나타나는 경우가 많습니다. 상품 설명이나 가격이 다른 사이트에 등장하거나, 전환은 그대로인데 목록 페이지의 대역폭과 서버 비용이 늘어납니다. 외부에서 확인하려면 페이지의 특징적인 문장을 따옴표로 묶어 검색해 보고, 가격을 바꾼 뒤 몇 시간 안에 비교 사이트에 같은 가격이 다시 나타나는지 살피십시오. 누가 했는지는 로그가 알려 줍니다.

combined 형식의 액세스 로그에서는 다음과 같이 보입니다. 아래는 실제 트래픽이 아닌 예시 값입니다. 45.33.32.156은 Linode에 있는 Nmap의 공개 테스트 호스트이며 이 요청을 보낸 적이 없습니다. 실제 방문자의 IP는 게시할 수 없으므로 "클라우드 서버"의 대역으로 사용했습니다.

GeoIPHub API
# illustrative values, not real traffic 45.33.32.156 - - [08/Oct/2026:03:14:07 +0000] "GET /products?page=34 HTTP/1.1" 200 48211 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 45.33.32.156 - - [08/Oct/2026:03:14:08 +0000] "GET /products?page=35 HTTP/1.1" 200 47960 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 45.33.32.156 - - [08/Oct/2026:03:14:10 +0000] "GET /products?page=36 HTTP/1.1" 200 48377 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 45.33.32.156 - - [08/Oct/2026:03:14:11 +0000] "GET /products?page=37 HTTP/1.1" 200 48102 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 45.33.32.156 - - [08/Oct/2026:03:14:13 +0000] "GET /products?page=38 HTTP/1.1" 200 47815 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 45.33.32.156 - - [08/Oct/2026:03:14:14 +0000] "GET /products?page=39 HTTP/1.1" 200 48290 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

눈에 띄는 점이 세 가지 있습니다. 페이지가 새벽 3시에 1~2초 간격으로 하나씩 올라갑니다. 리퍼러가 없고 그 사이에 .css나 .js 요청이 단 하나도 없습니다. 그리고 클라이언트는 자신을 Googlebot이라고 부르는데, 이 부분은 다음 섹션에서 검증합니다.

이런 클라이언트를 찾는 데 로그 플랫폼은 필요하지 않습니다. 다음 한 줄짜리 명령은 표준 combined 로그에서 동작하니, 먼저 가장 바쁜 한 시간 분량에 실행해 보십시오.

GeoIPHub API
# Busiest client IPs awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20 # Busiest IPv4 /24 networks (rotating scrapers often stay inside one block) awk '{split($1,o,"."); print o[1]"."o[2]"."o[3]".0/24"}' access.log | sort | uniq -c | sort -rn | head -20 # Busiest User-Agents awk -F'"' '{print $6}' access.log | sort | uniq -c | sort -rn | head -20 # Clients with more than 100 page requests and zero asset requests awk '{ if ($7 ~ /\.(css|js|png|jpe?g|webp|svg|woff2?)(\?|$)/) a[$1]++; else p[$1]++ } END { for (ip in p) if (!(ip in a) && p[ip] > 100) print p[ip], ip }' access.log | sort -rn

출력은 다음 목록에 따라 검토하십시오.

  • 요청된 페이지. 바쁜 클라이언트가 목록, 가격, 검색 결과, 사이트맵에 집중되어 있습니까?
  • IP별, 그다음 네트워크별 요청 속도. IP를 보강한 뒤 ASN별 요청 수를 합산하십시오. 한 ASN 안의 호스팅 주소 50개가 같은 페이지를 따라가고 있다면 동일한 행위자일 가능성이 높습니다.
  • 세션 깊이. 장바구니, 로그인, 검색창 사용 없이 세션당 수백 페이지를 요청합니다.
  • 순서. 페이지네이션이나 사이트맵 URL을 순차적으로 가져옵니다.
  • 에셋. HTML만 요청하고 CSS, JavaScript, 글꼴, 이미지는 요청하지 않습니다.
  • 크롤러 주장. Googlebot, Bingbot, GPTBot, ClaudeBot User-Agent는 모두 IP로 검증할 목록에 올립니다.
  • 자동화 표식. 라이브러리 User-Agent(python-requests, curl, Go-http-client)와 헤드리스 브라우저의 흔적입니다.

스크래퍼 IP 주소: 실제 GeoIPHub 조회 결과

스크래퍼 IP 주소는 몇 가지 네트워크 유형으로 나뉘며, 조회는 어느 유형인지를 알려 줄 뿐 그 요청이 스크래퍼였는지는 알려 주지 않습니다. GeoIPHub 조회에서 검증된 크롤러는 0~23점(allow)이었고, Tor와 VPN 출구는 100점(block)이었습니다. 2026-10-08에 유형별로 익명 조회를 한 번씩, 4초 간격으로 실행했습니다.

GeoIPHub API
curl -s https://api.geoiphub.com/v1/lookup/18.97.14.81
IP봇 유형네트워크(ASN)주요 플래그fraud_scorerecommended_actiondetection_methods
18.97.14.81크롤러(카테고리: archiver)Amazon AMAZON-AES (AS14618)is_hosting: true, crawler.name: CCBot, verified: true0allowdatacenter_ip, rdns_hosting, verified_crawler
216.73.216.10크롤러(카테고리: ai)Amazon AMAZON-02 (AS16509)is_hosting: true, crawler.name: ClaudeBot, verified: true0allowdatacenter_ip, no_ptr_datacenter, verified_crawler
5.39.1.230크롤러(카테고리: seo)OVH (AS16276)crawler.name: AhrefsBot, verified: true, is_abusive: true23allowabusive_listed, datacenter_blocklisted, no_ptr_datacenter, verified_crawler
192.178.4.40크롤러(카테고리: search_engine)Google (AS15169)crawler.name: Googlebot, verified: true0allowdatacenter_ip, no_ptr_datacenter, verified_crawler
45.33.32.156일반 클라우드 서버Akamai Connected Cloud, Linode (AS63949)is_hosting: true, crawler.name: none10allowdatacenter_ip
185.220.101.47Tor 출구Stiftung Erneuerbare Freiheit (AS60729)is_tor: true, is_spammer: true100blocktor_exit, datacenter_blocklisted, rdns_tor, known_spammer
185.213.155.73상용 VPN31173 Services AB (AS39351)is_vpn: true, vpn_provider: Mullvad, vpn_confidence: 95100blockknown_vpn_server, wireguard_open, datacenter_with_vpn_proxy, no_ptr_datacenter

이는 하루 동안의 개별 조회일 뿐 벤치마크가 아니며, 대역이 바뀌면 값도 달라집니다. 알려진 한계가 하나 있습니다. Googlebot과 AhrefsBot 행의 no_ptr_datacenter는 크롤러 측이 아니라 저희 데이터의 문제입니다. 일부 크롤러 대역에서는 역방향 DNS가 정상적으로 조회되는데도 API에 PTR 레코드가 저장되어 있지 않습니다(192.178.4.40은 crawl-192-178-4-40.googlebot.com으로 확인됩니다). ClaudeBot IP의 경우 이 신호는 정확합니다. 역방향 DNS가 없습니다.

다음은 CCBot 응답을 줄여서 실은 것으로, 값은 실제이며 중첩 구조도 원본 그대로입니다.

GeoIPHub API
{ "ip": "18.97.14.81", "asn": { "asn": 14618, "org": "AMAZON-AES - Amazon.com, Inc.", "asn_type": "hosting" }, "detection": { "is_hosting": true, "is_vpn": false, "is_tor": false }, "threat": { "is_crawler": true, "crawler": { "verified": true, "name": "CCBot", "operator": "CommonCrawl", "category": "archiver", "verification_method": "ip_range_list" } }, "scoring": { "fraud_score": 0, "recommended_action": "allow", "detection_methods": ["datacenter_ip", "rdns_hosting", "verified_crawler"] } }

Common Crawl의 자체 크롤러는 AWS에서 실행되는데도 0점입니다. 이 IP는 Common Crawl이 ccbot.json 파일로 공개하는 18.97.14.80/29 대역에 속하며, 스코어링의 검증된 크롤러 보정값(−28.5)이 데이터센터 신호를 상쇄합니다. GeoIPHub는 이렇게 Google, Bing, OpenAI, Anthropic, Common Crawl, Ahrefs 등의 공식 크롤러 대역 피드 19개를 확인합니다. CCBot이나 GPTBot처럼 AI 모델에 데이터를 공급하는 크롤러가 페이지를 읽도록 허용할지는 정책의 문제입니다. 조회가 확정해 주는 것은 그 크롤러가 누구인가뿐입니다.

AhrefsBot은 의외의 결과였습니다. 검증은 통과했습니다(5.39.1.230은 Ahrefs의 공개 크롤러 대역에 있는 5.39.1.224/27에 속합니다). 그러나 is_abusive: true와 methods의 abusive_listed도 함께 나와 점수는 23점, 여전히 allow였습니다. 어느 목록이 플래그를 붙였는지는 추적하지 못했습니다. 어느 쪽이든 교훈은 같습니다. "검증됨"은 크롤러가 누구인지를 알려 줄 뿐, 그 크롤러를 원하는지는 알려 주지 않습니다. 경쟁사의 백링크 보고서를 위해 사이트를 지도화하는 SEO 크롤러도 스크래핑을 하는 것이며, 단지 신원을 밝혔을 뿐입니다.

스크래핑 로그의 크롤러 사칭: 한 줄을 추적하다

User-Agent에는 Googlebot이라고 되어 있지만 클라우드 서버에서 온 요청은 검증되지 않은 주장입니다. GeoIPHub는 해당 IP가 Google 대역에 속하지 않는다는 점은 알려 줄 수 있지만, 조회 쪽은 헤더를 볼 수 없으므로 User-Agent와의 비교는 여러분의 코드에서 이루어집니다. 예시 로그의 네 번째 줄인 45.33.32.156, GET /products?page=37, User-Agent Googlebot/2.1을 따라가 봅니다.

  1. IP를 조회합니다. 실제 조회는 ASN 63949, Akamai Connected Cloud(Linode), detection.is_hosting: true, threat.crawler.name: "none", verified: false, fraud_score 10, allow, methods ["datacenter_ip"]를 반환했습니다.
  2. 주장을 비교합니다. 코드에서 User-Agent 토큰을 threat.crawler.verified 및 threat.crawler.name과 대조합니다.
  3. 판단합니다. UA는 Googlebot이라고 하지만 IP는 어떤 Google 대역에도 없습니다. 따라서 "Googlebot으로 검증되지 않음"입니다. 요청을 제한하거나 챌린지를 거십시오. 챌린지(CAPTCHA 또는 JavaScript 확인)는 API의 step_up 액션에 따라 취하는 조치입니다. 가짜라고 단정하지는 마십시오. 저희 데이터에서는 범위 파일을 매일 가져오고 조회 데이터베이스도 매일 재구축하므로, 새로 추가된 Google 대역이 검증되기까지 최대 이틀 정도 걸릴 수 있습니다.
  4. 대조군을 확인합니다. 192.178.4.40의 진짜 Googlebot은 verified: true, name: "Googlebot", verification_method: "ip_range_list", 점수 0을 반환했습니다.

Google은 같은 확인을 직접 하는 두 가지 방법을 문서화하고 있습니다. IP의 역방향 DNS 조회 후 호스트 이름을 정방향 조회하는 방법, 또는 common-crawlers.json 같은 공개 범위 파일과 대조하는 방법입니다(Google Search Central). 코드에서의 비교는 다음과 같습니다.

GeoIPHub API
// Map User-Agent tokens to the crawler names the API returns. // They don't always match: OpenAI's "ChatGPT-User" comes back as "ChatGPTUser". const CRAWLER_NAMES = { "Googlebot": "Googlebot", "GPTBot": "GPTBot", "CCBot": "CCBot", "ClaudeBot": "ClaudeBot", "AhrefsBot": "AhrefsBot", "ChatGPT-User": "ChatGPTUser", }; async function classifyRequest(ip, userAgent) { const res = await fetch(`https://api.geoiphub.com/v1/lookup/${ip}`, { headers: { "x-api-key": process.env.GEOIPHUB_API_KEY }, }); const { threat, scoring } = await res.json(); const token = Object.keys(CRAWLER_NAMES).find((t) => userAgent.includes(t)); if (token) { const ok = threat.crawler.verified && threat.crawler.name === CRAWLER_NAMES[token]; return ok ? "allow_crawler" : "unverified_crawler_claim"; // rate-limit or challenge } return scoring.recommended_action; // allow, review, step_up or block }

점수는 allow인데 패턴은 스크래퍼인 경우가 바로 이것입니다. IP만 놓고 보면 이 요청은 10점, allow입니다. 클라우드 서버라는 사실은 그 자체로는 약한 신호이기 때문입니다. 스크래핑이라는 판단은 점수가 볼 수 없는 세 가지에서 나옵니다. UA 불일치, 일정한 요청 속도, 페이지를 하나씩 따라가는 움직임입니다. Google의 전체 절차는 역방향 DNS와 Google 범위 파일로 Googlebot 검증하기를, GPTBot, ClaudeBot, 서명된 에이전트는 IP, 역방향 DNS, Web Bot Auth로 AI 크롤러 검증하기를 참고하십시오.

IP 데이터가 놓치는 것: 주거용 프록시와 실제 브라우저

IP 데이터는 주거용 또는 모바일 프록시를 거치는 스크래퍼를 놓칩니다. GeoIPHub는 주거용 프록시를 탐지하지 않으며, is_residential_proxy 필드는 ASN에 기반한 대략적인 추정이므로 신호가 없는 것으로 취급하십시오. 주거용 프록시 네트워크는 각 요청을 누군가의 가정 회선을 거쳐 보냅니다. IP 계층에서는 요청이 그 가정처럼 보입니다. 일반 ISP, 실제 도시, 호스팅 플래그 없음, 깨끗한 점수입니다.

로테이션은 상황을 더 어렵게 만듭니다. 풀이 요청마다 새로운 가정용 IP를 줄 수 있으므로 IP별 카운터는 올라가지 않습니다. 모바일 프록시는 실제 휴대폰과 통신사 IP를 공유하며, IPv6 스크래퍼는 새로운 네트워크를 건드리지 않고도 /64 전체를 순환할 수 있습니다.

실제 브라우저가 두 번째 사각지대입니다. 사무실이나 가정 회선에서 Chrome을 구동하는 Playwright 스크립트는 옆자리 사람과 같은 IP, 같은 TLS 핸드셰이크, 같은 에셋을 보냅니다. 일부 헤드리스 구성은 스스로를 드러내지만, 잘 조정된 구성은 그렇지 않습니다.

이런 스크래퍼를 여전히 드러내는 것은 요청 전반에 걸친 패턴입니다.

스크래퍼 구성IP가 보여 주는 것그래도 드러나는 단서
로테이팅 주거용 프록시일반 ISP, 깨끗한 점수하나의 페이지 순서, 하나의 타이밍 리듬, 하나의 핑거프린트를 공유하는 다수의 IP
모바일 프록시실제 휴대폰과 공유되는 통신사 IP어떤 휴대폰 사용자도 만들지 않는 세션 깊이와 경로 순서
/64 안에서의 IPv6 로테이션요청마다 새로운 주소주소별이 아닌 /64별로 요청 수를 집계
가정이나 사무실 회선의 헤드리스 브라우저평범한 액세스 네트워크자동화 표식, TLS 핑거프린트, 쿠키 연속성 없음
모든 링크를 따라가는 스크래퍼사용하는 네트워크가 무엇이든숨겨진 링크에 대한 요청: CSS로 숨겨 어떤 방문자도 볼 수 없는 링크이므로, 이를 요청하는 것은 링크를 무작정 따라가는 클라이언트

숨겨진 링크를 설치한다면 그 경로를 robots.txt에서 disallow하십시오. 그러면 이 파일을 따르는 크롤러는 그 링크를 건드리지 않습니다. IP 옆에 놓이는 계층을 더 깊이 다루는 글이 두 편 있습니다. 기기 핑거프린팅과 IP 인텔리전스가 함께 쓸 때 가장 효과적인 이유, 그리고 조회로 무엇을 볼 수 있고 볼 수 없는지는 주거용 프록시 사기 탐지에서 확인하십시오.

스크래핑 vs 크롤링 vs API 악용

크롤링은 신원을 밝히고 검증할 수 있으며, 스크래핑은 콘텐츠나 데이터를 가져가면서 신원을 밝히지 않는 경우가 많고, API 악용은 약관이나 한도를 넘어 엔드포인트를 스크립트로 호출하는 것입니다. 이 셋을 가르는 선은 기술이 아니라 행동과 신원입니다. Googlebot과 가격 스크래퍼가 같은 클라우드에서 같은 HTTP 라이브러리를 쓸 수도 있습니다.

트래픽 유형대상신원 표시 방식확인할 것
크롤링검색 색인, 아카이브 또는 AI 모델을 위한 페이지이름이 있는 User-Agent와 공개된 IP 대역운영자의 대역에 속하는 IP, robots.txt 준수 여부
스크래핑가격, 목록, 기사 같은 특정 콘텐츠나 데이터브라우저 UA 또는 빌려 쓴 크롤러 이름인 경우가 많음요청 속도, 페이지 순서, 빠진 에셋, UA와 검증된 크롤러의 비교
API 악용사이트 뒤에 있는 경우가 많은 JSON 엔드포인트API 키, 세션 토큰 또는 없음키별, 네트워크별 호출 수, 일반적인 앱 흐름을 벗어난 엔드포인트

AhrefsBot이 보여 주듯 검증된 크롤러도 스크래핑을 할 수 있고, 스크래퍼도 크롤러처럼 보일 수 있습니다. 그래서 다음 섹션은 검증된 크롤러만 허용하는 것으로 시작합니다.

검색 크롤러를 막지 않고 웹 스크래핑을 방지하는 방법

검색 크롤러를 막지 않고 웹 스크래핑을 방지하려면 검증된 크롤러를 먼저 허용하고, 그다음 네트워크 단위로 요청을 제한하고 브라우저처럼 행동하지 않는 클라이언트에 챌린지를 걸며, 확인된 것만 차단하십시오. GeoIPHub의 점수 구간이 IP 측면의 기준을 줍니다. 25점까지 allow, 50점까지 review, 75점까지 step_up, 75점 초과는 block입니다. 순서가 중요합니다. 데이터센터를 일괄 차단하는 규칙을 먼저 적용했다면 위 표의 Googlebot, CCBot, ClaudeBot, AhrefsBot이 모두 걸렸을 것입니다. 네 곳 모두 호스팅 네트워크에서 왔기 때문입니다.

  1. 검증된 크롤러를 허용합니다. threat.crawler.verified가 true이고 crawler.name이 User-Agent 토큰과 일치하는 경우입니다. 그런 다음 크롤러별로 자체 정책을 적용하십시오. AI 크롤러의 경우 GPTBot, OAI-SearchBot, ChatGPT-User 비교 글에서 AI 검색에는 남은 채로 학습만 차단하는 방법을 설명합니다.
  2. IP 규칙을 재사용합니다. 점수 구간, Tor 처리, 프리픽스별 요청 제한은 스크래퍼에도 다른 봇과 똑같이 적용되며 허브 글에서 다룹니다. 호스팅에는 AI 에이전트, 기업 프록시, 자사 도구도 포함되므로 데이터센터 IP는 차단 사유가 아니라 가중치가 있는 입력값으로 취급하십시오(데이터센터 IP 주소란 무엇인가 참고).
  3. 스크래퍼가 노리는 페이지에 ASN별 요청 제한을 겁니다. 한 호스팅 업체를 돌아가며 쓰는 풀은 어떤 IP별 한도 아래에도 머물지만, 목록, 검색, 가격 페이지의 ASN별 카운터는 이를 합산합니다. 서로 무관한 많은 고객이 하나의 ASN을 공유하므로 대형 클라우드에는 더 높은 상한을 주십시오.
  4. 페이지네이션에 상한을 두고 전체 목록은 로그인 뒤에 둡니다. 익명 방문자에게는 정해진 수의 목록 페이지만 제공하십시오. 계정 벽은 각 스크래퍼를 셀 수 있고 폐쇄할 수 있는 계정으로 바꿔 줍니다.
  5. 페이지가 호출하는 JSON 엔드포인트에 키별 할당량을 둡니다. 스크래퍼는 HTML을 건너뛰고 그 뒤의 API를 직접 호출하는 경우가 많으므로, 키나 세션 토큰을 발급하고 키별 호출 수에 상한을 두십시오.
  6. 봇 관리 또는 WAF 계층을 추가합니다. TLS 핑거프린트와 엣지의 JavaScript 확인처럼 로그에 담기지 않는 클라이언트 신호를 위한 것입니다.
  7. 주거용 트래픽에는 행동 규칙을 사용합니다. IP가 아무것도 알려 주지 못하는 영역입니다.

대응은 사다리를 이룹니다. 허용, 요청 제한, 챌린지, 차단입니다. 일부 사이트는 의심되는 스크래퍼에 대한 응답을 늦추는 타피트(tarpit)를 쓰거나, 이미 분류한 트래픽에 변조된 가격 같은 미끼 콘텐츠를 제공하기도 합니다. 분류가 틀리면 둘 다 대가를 치르므로, 어차피 차단할 트래픽에만 사용하십시오.

신호기본 조치
User-Agent가 일치하는 threat.crawler.verified허용한 뒤 크롤러별 정책 적용
크롤러 User-Agent, crawler.name이 "none"요청 제한 또는 챌린지
한 ASN의 IP 20개 이상에서 같은 페이지 순서ASN 요청 제한 후 챌린지
HTML만, 100페이지 이상, CSS나 JS 없음IP가 무엇이든 챌린지
사람에게 보이지 않는 링크에 대한 요청해당 클라이언트 차단
일반 ISP, 깨끗한 점수, 스크래퍼 같은 패턴행동 규칙과 핑거프린트

IP만으로 판단하는 행(Tor, 릴레이, 스캐너, IPv6 프리픽스)은 IP 기반 봇 탐지 가이드의 조치 매핑을 사용하십시오.

그렇다면 robots.txt는 어떨까요? 요청할 뿐 강제하지는 않습니다. 로봇 배제 표준인 RFC 9309는 그 규칙이 "접근 권한 부여의 한 형태가 아니다"라고 밝힙니다(RFC 9309). 이를 따르는 크롤러에는 robots.txt를 유지하고, 나머지는 모두 서버에서 강제하십시오. AI 크롤러 차단 가이드는 nginx와 Express 코드로 그 강제 계층을 보여 줍니다.

어제의 로그에서 시작하십시오. 에셋을 하나도 불러오지 않은 가장 바쁜 클라이언트 50개를 추출해 각각을 무료 IP 조회에 붙여 넣고(키 없이 분당 30회, 무료 키가 있으면 하루 1,500회), 위 조회 표의 유형으로 분류하십시오. 남는 것, 즉 바쁘면서 일반 가정용 네트워크에 있는 클라이언트가 다음에 행동 규칙을 적용할 대상입니다.

자주 묻는 질문

GPTBot이나 CCBot 같은 AI 스크래퍼는 어떻게 차단하나요?

먼저 robots.txt로 시작합니다. GPTBot과 CCBot은 모두 robots.txt를 따르므로, 해당 토큰에 Disallow 규칙을 두면 스스로 신원을 밝히는 크롤러는 멈춥니다. robots.txt는 요청일 뿐 접근 제어가 아니므로(RFC 9309는 그 규칙이 접근 권한 부여의 한 형태가 아니라고 밝힙니다) 서버에서도 직접 강제해야 합니다. 각 크롤러를 공개된 IP 대역으로 검증하고, 그 대역 밖에서 해당 이름을 쓰는 클라이언트는 미검증으로 취급하십시오. OpenAI는 역할이 서로 다른 여러 봇을 운영합니다. ChatGPT 검색에 계속 노출되려면 어느 봇을 차단해야 하는지는 GPTBot vs OAI-SearchBot vs ChatGPT-User 글에서 설명합니다.

분당 몇 건의 요청부터 스크래핑인가요?

모든 사이트에 통하는 기준 수치는 없습니다. 평소 하루의 정상 사용자 기준선을 IPv4는 /24, IPv6는 /64 단위로 직접 측정한 다음, 그 기준을 크게 넘는 네트워크를 살펴보십시오. 요청 속도만으로는 사무실 NAT, CGNAT, 모니터링 서비스도 걸리므로, 페이지를 순서대로 가져오면서 에셋은 요청하지 않을 때에 한해 높은 요청 속도를 스크래핑으로 판단하십시오.

웹 스크래핑을 완전히 막을 수 있나요?

막을 수 없습니다. 브라우저가 렌더링할 수 있는 것은 끈질긴 스크래퍼도 복사할 수 있으며, 주거용 프록시와 실제 브라우저를 쓰는 경우도 마찬가지입니다. 목표는 스크래핑을 느리고, 비싸고, 눈에 띄게 만드는 것입니다. 크롤러를 검증하고, 네트워크 단위로 요청을 제한하고, 브라우저처럼 행동하지 않는 클라이언트에는 챌린지를 걸고, 가치가 높은 데이터는 로그인이나 API 키 뒤에 두십시오.

데이터센터 IP를 차단하면 스크래핑이 멈추나요?

부분적으로만 멈춥니다. 저렴한 클라우드 서버에서 돌아가는 스크래퍼는 막지만, 먼저 허용해 두지 않으면 검증된 크롤러도 함께 차단됩니다. 2026-10-08에 실시한 조회에서 AWS의 CCBot은 0점(allow), 진짜 Googlebot도 0점(allow)이었고 둘 다 호스팅 네트워크였습니다. 일반 Linode 서버는 10점으로 역시 allow여서 점수만으로는 차단되지 않습니다. 주거용 프록시를 빌려 쓰는 스크래퍼는 데이터센터 차단을 완전히 통과합니다.

IP 조회로 어떤 IP가 스크래퍼인지 알 수 있나요?

알 수 없습니다. 조회가 알려 주는 것은 네트워크 유형과 위험도, 즉 검증된 크롤러, 데이터센터 서버, Tor 출구, VPN 중 무엇인가입니다. 그 IP가 실제로 사이트를 스크래핑하는지는 로그에서 판단합니다. 요청 속도, 가져오는 페이지의 순서, 에셋을 불러오는지 여부, 그리고 User-Agent가 조회로 검증된 크롤러와 일치하는지를 보십시오.

스크래퍼가 주거용 프록시를 쓰는지 어떻게 알 수 있나요?

IP만으로는 알 수 없으며, GeoIPHub도 주거용 프록시를 탐지하지 않습니다. 하나의 세션 패턴을 공유하는 다수의 일반 가정용 IP를 찾으십시오. 같은 페이지 순서, 요청 간 같은 간격, 같은 에셋 누락, 비슷한 TLS 또는 기기 핑거프린트가 단서입니다. 스크래퍼를 드러내는 것은 개별 주소가 아니라 주소 전체에 걸친 패턴입니다.

작성자

GeoIPHub 팀

GeoIPHub API를 만드는 팀

GeoIPHub IP 인텔리전스 API와 스캐너를 만드는 GeoIPHub 팀이 작성했습니다. 초안은 AI의 도움을 받아 준비하고 팀이 편집합니다. API 예시는 예시용으로 표시된 경우를 제외하고 라이브 API에 대한 실제 조회 결과입니다.

이 글 공유하기
더 많은 글

관련 글