스크래퍼는 내 노트북에서 작동했지만, 서버에 배포하자 즉시 403 오류가 발생했습니다.

발행: (2026년 3월 31일 PM 11:46 GMT+9)
3 분 소요
원문: Dev.to

Source: Dev.to

무엇이 문제였는가

대상 사이트가 User-Agent 헤더를 검사하고 있었습니다. 제 노트북에서는 다른 작업에 Playwright를 사용하고 있었고 프로필에 전역적으로 일반 브라우저 User-Agent를 설정했기 때문에 요청에 정상적인 브라우저 User-Agent가 포함되었습니다.

새로 설치한 Ubuntu 서버에서는 기본 Python requests User-Agent를 사용했습니다:

python-requests/2.31.0

사이트는 이를 거부하고 모든 요청에 대해 403 Forbidden을 반환했습니다.

해결 방법

요청 헤더에 커스텀 User-Agent를 추가했습니다:

import requests

headers = {
    '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'
}

response = requests.get('https://example.com/products', headers=headers)

if response.status_code == 200:
    # Parse the data
    products = response.json()
else:
    print(f"Failed: {response.status_code}")

이 변경으로 사이트가 다시 200 OK를 반환하기 시작했습니다.

때때로 중요한 다른 요소들

User-Agent 외에도 일부 사이트는 다음을 확인합니다:

  • Referer 헤더 – 요청을 허용하려면 유효한 Referer가 필요할 수 있습니다.

    headers = {
        'User-Agent': 'Mozilla/5.0...',
        'Referer': 'https://example.com/'
    }
  • Accept 헤더 – 실제 브라우저는 다양한 Accept 헤더를 보냅니다.

    headers = {
        'User-Agent': 'Mozilla/5.0...',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.5',
        'Accept-Encoding': 'gzip, deflate, br'
    }

대부분의 경우 적절한 User-Agent만 설정하면 충분합니다. 그렇지 않을 때는 이러한 추가 헤더를 넣으면 보통 문제가 해결됩니다.

팁: 응답을 파싱하기 전에 항상 response.status_code를 확인하세요. 이렇게 하면 오류 페이지(예: 403)를 JSON으로 파싱하려다 발생하는 혼란스러운 파싱 오류를 방지할 수 있습니다.

0 조회
Back to Blog

관련 글

더 보기 »