설명
User-Agent 헤더는 웹에서 가장 오래된 식별 수단 중 하나입니다. 클라이언트가 보내는 모든 HTTP 요청에는 클라이언트 소프트웨어(브라우저 또는 라이브러리), 버전, 운영체제, 그리고 종종 렌더링 엔진까지 명시하는 `User-Agent:` 라인이 포함됩니다. 서버는 이를 콘텐츠 협상(모바일 대 데스크톱 레이아웃), 분석, 그리고 점점 더 봇 탐지에 활용합니다.
스크래핑에서 User-Agent는 가장 쉽게 실수할 수 있는 신호입니다. 일반적인 HTTP 라이브러리의 기본 User-Agent(`python-requests/2.31.0`, `axios/1.5.0`, `okhttp/4.10.0`)는 명백한 단서가 됩니다. Playwright와 Puppeteer의 기본 User-Agent조차 `HeadlessChrome`을 포함하고 있어 안티봇 시스템이 즉시 이를 탐지합니다.
가장 단순한 해결책은 모든 요청에 Chrome UA를 설정하는 것입니다. 문제는 User-Agent만으로는 충분하지 않다는 점입니다. 최신 핑거프린팅 기술은 UA를 `sec-ch-ua` 클라이언트 힌트, TLS 핑거프린트, JavaScript navigator 객체, Accept-Language 헤더와 상호 대조합니다. Chrome UA를 설정하면서도 Python의 TLS 핸드셰이크를 그대로 노출하면 기본 UA를 그대로 두는 것보다 오히려 더 큰 위험 신호가 됩니다.
작동 방식
클라이언트가 서버에 연결을 열면, 요청 라인에는 헤더가 포함됩니다. `User-Agent` 라인도 그중 하나입니다. 서버는 이를 파싱하거나(또는 단순히 기록하고) 보이는 내용에 따라 요청을 라우팅합니다. Windows에서 최신 Chrome User-Agent는 다음과 같습니다: `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36`. 'Mozilla/5.0' 접두사는 역사적인 것으로, 모든 브라우저가 레거시 호환성을 위해 이를 전송합니다.
실제 브라우저는 최신 HTTP에서 구조화된 브라우저/버전/플랫폼 데이터를 전달하는 `sec-ch-ua`('Sec-CH-UA' 클라이언트 힌트) 헤더도 전송합니다. 안티봇 시스템은 이를 User-Agent 문자열과 비교하여 불일치를 표시합니다. 따라서 User-Agent 로테이션은 일관된 `sec-ch-ua-*` 업데이트 및 일치하는 TLS 지문과 함께 이루어져야 합니다.