스크래퍼는 내 노트북에서 작동했지만, 서버에 배포하자 즉시 403 오류가 발생했습니다.
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으로 파싱하려다 발생하는 혼란스러운 파싱 오류를 방지할 수 있습니다.