봇이라고 밝히니 통과했다 — 브라우저인 척해서 차단당한 18일

봇이라고 밝히니 통과했다 — 브라우저 User-Agent 위장과 Cloudflare 403 실측

건물 하나를 떠올려 보자. 택배 기사는 그냥 들여보내는데 방문객처럼 굴면 신분증을 내고 방문 목적을 적어야 한다. 그 건물에서는 제복을 벗는 쪽이 빨리 들어간다.

내 수집기는 18일 동안 정문 앞에 서 있었다. 브라우저인 척하는 User-Agent를 달고 있었기 때문이다. 그 한 줄을 지우자 차단이 풀렸다.

결론부터 적는다. 대응책은 자기가 언제부터 쓸모없어졌는지 말해 주지 않는다.

차단을 피하려고 넣어둔 UA 위장이 그랬고, 실패를 놓치지 않으려고 넣어둔 장치도 그랬다. 신호는 28번 다 울렸고 그걸 18일 동안 읽지 않은 사람은 나다.

누가 읽으면 좋은가

외부 사이트를 긁는 코드를 굴려본 사람. 차단을 피하려고 헤더를 손봐본 적이 있는 사람. 그리고 “실패하면 에러가 나니까 알게 되겠지”라고 생각해 본 사람.

수집기가 조용히 0을 반환하는 걸 본 적이 있다면 절반은 아는 이야기다. 나머지 절반은 조용하지 않았는데도 못 봤다는 쪽이다.

위장을 지우니 403이 200이 됐다

먼저 증상부터 살펴보자. 트렌드 수집기의 소스 두 곳이 죽어 있었다.

Threads와 Product Hunt다. 둘 다 r.jina.ai라는 같은 경로를 지나간다.

마지막으로 정상 수집된 실행은 7월 29일이다. Threads 135건, Product Hunt 16건이 들어왔다.

다음 날부터 둘 다 0이 됐다. 8월 16일까지 28회 연속이다.

원인을 좁히려고 같은 URL에 헤더만 바꿔 던져 봤다. 같은 시각, 같은 주소다.

보낸 User-Agent 응답
Mozilla/5.0 ... Chrome/131.0.0.0 Safari/537.36 403
curl 기본 UA 200
빈 UA 200
trend-scout/0.2 200

403 응답 본문의 첫 줄은 이랬다. <title>Just a moment...</title> — Cloudflare가 자바스크립트 챌린지를 걸 때 내보내는 화면이다.

즉 브라우저처럼 보이는 클라이언트한테만 검문이 붙는다. 브라우저라고 주장했으니 자바스크립트를 돌려서 증명하라는 요구다.

내 수집기는 그걸 못 한다. 반대로 봇이라고 밝힌 요청은 그냥 지나갔다.

UA를 비브라우저로 바꾸고 다시 돌렸다. Threads 0건이 59건, Product Hunt 0건이 13건이 됐다.

그 위장은 7월 29일까지 통했다

여기서 기록 하나를 꺼내야 한다. 5월에 봇 차단을 정리한 글을 썼고, 거기 표에 이런 행이 있다.

브라우저(Browser) / User-Agent, Sec-CH-UA, canvas·WebGL·폰트 지문, navigator.webdriver / undetected-chromedriver, Playwright steal…

표는 계층, 무엇을 검사하나, 보통 쓰이는 우회 방법 세 열로 돼 있다. User-Agent는 가운데 열, 그러니까 검사받는 쪽에 있고 우회 방법 열에 적힌 건 브라우저를 더 정교하게 흉내 내는 도구들이었다. 그 계층의 답은 더 그럴듯한 브라우저가 되는 쪽이었다.

그런데 그게 틀린 선택이었나? 7월 29일까지는 그 위장이 실제로 통했다.

135건과 16건이 그 증거다. 바뀐 건 판단이 아니라 조건이다.

Cloudflare가 언제 무엇을 바꿨는지는 모른다. 7월 29일과 30일 사이라는 것만 안다. Jina 쪽 변경인지 Cloudflare 쪽 변경인지도 구분하지 못했다.

에러는 28번 났다. 그런데 안 읽혔다

여기서 같은 구조가 한 번 더 나온다. UA 위장이 만료를 안 알렸듯, 실패를 잡으려고 넣어둔 장치도 자기 출력이 읽히는지는 알리지 않았다.

6월에 같은 수집기가 0건을 낸 적이 있다. 그때 이렇게 적었다.

만약 실패를 삼키고 빈 목록을 반환했다면, 며칠 뒤 “요즘 Product Hunt가 한산하네” 하고 넘어갔을 거다.

빈 목록을 반환하지 않았으니 괜찮다는 뜻이었다. 실제로 코드는 조용하지 않았다. 28회 실행 전부 실패를 기록했다.

처음엔 그 기록이 원인을 안 담아서 파서 문제처럼 읽혔고, 8월 11일에 손봐서 HTTP 403 after 3 attempts라고 원인까지 남게 했다.

그런데도 18일이 걸렸다. “며칠”이 아니었다.

이유를 두 군데서 찾았다. 하나는 리포트 구조다.

플랫폼별 섹션은 수집된 항목에서 만들어진다. 0건인 플랫폼은 섹션 자체가 안 생기고 합계 줄에도 안 나온다. 사라진 것이 사라졌다고 말해 주는 자리가 없었다.

다른 하나는 진단 습관이다. Threads와 Product Hunt가 같은 날 동시에 죽었다. 공통 경로가 있다는 신호였는데 둘을 따로 봤다.

그런데 여기서 멈추면 안 된다. 실패 내역 자체는 28번 다 리포트에 찍혀 나왔다. 헤더에 안 세워졌을 뿐 아래쪽에는 403이 매번 적혀 있었다.

구조를 고쳐도 안 읽으면 결과가 같다는 뜻이다. 앞의 두 가지로만 정리하면 그 부분이 빠진다.

정리하면 이렇다. 실패를 드러내는 것과 그 실패가 읽히는 것은 다른 문제다. 앞쪽은 6월에 갖췄고 뒤쪽은 비어 있었다.

그래서 무엇을 바꿨나

수집기에서 고친 건 UA 위장 제거 두 건이다. Reddit 재시도와 계정 순서 회전도 손봤는데 이 글의 주제와는 별개다. 저장소 테스트는 122건 통과에서 131건 통과가 됐고 실패 2건은 이번 변경 전부터 있던 것으로 여기서 다룬 내용과 무관하다.

더 중요한 건 리포트에 넣은 한 줄이다.

🚨 무수집 플랫폼: reddit, x_twitter — 0건 수집

0건인 플랫폼 이름을 머리말에 그대로 세운다. 수집이 0이면 이름조차 안 남던 자리다. 수정 후 첫 실행에서 바로 두 곳을 잡아냈다.

다만 이 장치의 사거리는 짧다. 0건일 때만 울리기 때문이다. 절반으로 줄어드는 식이면 그냥 침묵한다.

이번 만료는 절벽이라 잡혔고, 서서히 줄어드는 경우까지 잡는지는 아직 모른다.

우회를 하나 넣을 때마다 만료를 알려 줄 자리도 같이 만들어 두려고 한다. 이번엔 그 자리가 없어서 18일이 걸렸다.

Q&A

Q. 그냥 UA 하나 잘못 넣은 것 아닌가. 일반화할 게 있나?

A. 절반은 맞다. 넣은 시점에는 옳은 선택이었고 실제로 통했다. 그러니 “UA를 위장하지 마라”가 교훈이 될 수는 없다.

이번 건에서 남는 건 다른 쪽이다. 우회 수단은 상대가 바뀌면 만료되는데, 만료 시점을 알려 주는 건 우회 코드 자신이 아니었다.

Q. 그럼 브라우저 UA를 빼면 차단이 풀리나?

A. 그렇게 읽지 마라. 확인한 건 r.jina.ai 앞단 한 경로뿐이다.

다른 사이트, 다른 CDN에 같은 규칙이 적용되는지는 보지 않았다. Googlebot 위장 같은 다른 UA도 시험하지 않았다.

Q. 무엇부터 확인하면 되나?

A. 최근 리포트나 대시보드를 열고 두 가지를 보면 된다. 값이 0인 항목이 이름으로 남는지, 그리고 지난 실행 수치와 나란히 보이는지다.

0일 때 행이 사라지는 구조는 정상 0과 사망을 구분하지 못한다. 앞쪽만 갖추면 이번 같은 절벽은 잡히고 서서히 줄어드는 쪽은 놓친다. 내 리포트가 지금 딱 그 상태다.

한계

Reddit의 403은 왜 429가 아니라 403인지 아직 모른다. 재시도는 회복 패턴을 보고 붙인 대응이지 원인 규명이 아니고, 검증 실행에서는 403이 아니라 429가 떠서 그 경로를 타지도 못했다.

Threads 키워드 6개는 200을 받고도 0건인데 차단인지 결과가 없는 건지 확정하지 못했다.

다음 정기 실행에서 볼 것은 두 가지다. 수집 수치가 유지되는지, 그리고 Reddit이 403을 맞았을 때 재시도가 실제로 회복하는지. 뒤쪽은 아직 실전에서 확인하지 못했고 저장소에 커밋도 하지 않았다.

관련 글

저자 — Jason 황재승. cd4761.blogspot.com에서 개발 자동화와 AI 도구 운영 기록을 쓴다. 8년 차 프론트엔드. 이 글의 수치는 2026-08-16에 직접 실행해 얻은 것이고, 확인하지 못한 것은 확인하지 못했다고 적었다. (갱신: 2026-08-17)

태그: #웹수집 #UserAgent #Cloudflare #봇차단 #자동화 #트렌드수집 #운영기록 #모니터링

댓글

이 블로그의 인기 게시물

맥 스튜디오 M4 Max 128GB 로컬 LLM 4개 속도 비교 — gemma4·llama3.3·qwen3 실측

Opus 5는 더 잘 쓰고, 더 AI답게 쓴다 — 세 모델 첫날 실측

Claude Opus 4.7 출시 총정리 — 뭐가 달라졌고 지금 써야 하나