크롤링을 처음 돌릴 때 가장 당황스러운 순간은 브라우저에서는 페이지가 잘 열리는데, 파이썬 코드로만 요청하면 갑자기 막히는 경우입니다. 저도 같은 주소를 직접 열면 정상인데 requests.get()으로 접근했을 때 403 Forbidden이나 429 Too Many Requests가 반복되어, 코드가 틀린 줄 알고 한참 헤맸습니다. 이번 글은 그때 제가 실제로 점검한 순서와, 어떻게 요청을 조금 더 자연스럽게 바꿨더니 차단 빈도가 줄었는지를 중심으로 정리한 기록입니다. 403은 서버가 요청을 이해했지만 처리하지 않겠다는 뜻이고, 429는 일정 시간 안에 너무 많은 요청을 보냈다는 뜻입니다. requests는 헤더를 직접 dict로 넘겨 설정할 수 있어 이런 상황에서 기본 점검에 적합합니다.
브라우저는 되는데 코드만 막히던 이유
처음 크롤링 코드를 작성했을 때는 매우 단순했습니다. requests.get()으로 페이지를 불러오고, 응답이 오면 바로 HTML을 파싱하는 방식이었습니다. 그런데 이상하게도 같은 주소를 브라우저에 입력하면 페이지가 잘 열리는데, 파이썬 코드로 요청하면 403 오류가 뜨는 경우가 반복됐습니다. 조금 더 요청을 빠르게 보내면 이번에는 429 오류까지 함께 발생했습니다. 이때부터 문제는 주소가 아니라 “서버가 내 요청을 어떻게 판단하느냐”에 있다는 점을 알게 됐습니다.
403 Forbidden은 서버가 요청을 이해했지만 접근을 허용하지 않겠다는 의미입니다. 즉, 페이지가 존재하지 않는 것이 아니라 현재 요청 방식이 허용되지 않는 상태입니다. 반면 429 Too Many Requests는 짧은 시간 안에 요청이 과도하게 들어와 서버가 속도 제한을 건 상황에 가깝습니다. 둘은 숫자는 다르지만, 실제 크롤링 현장에서는 함께 묶어서 봐야 할 때가 많습니다. 브라우저 요청처럼 보이지 않거나, 지나치게 빠른 속도로 반복 요청하면 두 오류가 연달아 나타나기 쉽기 때문입니다.
제가 처음 실수한 부분도 바로 여기였습니다. 브라우저는 기본적으로 다양한 헤더 정보를 함께 보내지만, 파이썬 기본 요청은 상대적으로 단순합니다. 또한 반복문 안에서 쉬지 않고 여러 페이지를 연속 요청하면 서버 입장에서는 자동화된 비정상 접근처럼 보일 수 있습니다. 결국 문제는 “코드가 틀렸다”기보다 “요청이 너무 비어 있거나 너무 빨랐다”는 데 있었습니다. 이 글에서는 복잡한 우회 방법보다, 먼저 가장 기본적인 요청 형태를 정리하는 방식으로 접근했습니다.

User-Agent와 요청 간격 조절로 해결한 방법
가장 먼저 적용한 방법은 User-Agent 설정이었습니다. 처음에는 이 한 줄이 정말 차이를 만들까 싶었지만, 실제로는 생각보다 효과가 있었습니다. User-Agent는 서버에 “어떤 환경에서 요청을 보내는가”를 알려주는 정보입니다. 브라우저는 이 값을 자연스럽게 포함해서 요청하지만, 단순한 코드 요청은 상대적으로 비어 있게 보일 수 있습니다. 그래서 requests를 사용할 때 최소한의 헤더를 직접 넣어 주는 것만으로도 응답 상태가 달라질 수 있습니다.

이 코드에서 핵심은 세 가지입니다. 첫째, headers에 User-Agent를 넣어 요청을 너무 비정상적으로 보이지 않게 만드는 점입니다. 둘째, timeout을 넣어 응답이 지연될 때 코드가 오래 멈추지 않도록 한 점입니다. 셋째, time.sleep(1)로 다음 요청 전 잠시 쉬게 하여 서버에 과도한 부담을 주지 않도록 한 점입니다. 저는 이 세 가지를 적용한 뒤부터 첫 요청에서 바로 403이 발생하는 빈도가 줄었고, 여러 페이지를 연속 수집할 때 429가 뜨는 횟수도 확실히 감소했습니다.
여기서 중요한 것은 무조건 많은 헤더를 흉내 내는 것이 아니라, 필요한 최소 수준으로 요청을 정리하는 것입니다. 또한 429가 발생했을 때는 더 빠르게 재시도하기보다 요청 간격을 늘리고 호출 수를 줄이는 방향으로 수정해야 합니다. 초보자일수록 이 부분에서 조급해지기 쉬운데, 실제로는 속도를 늦추는 쪽이 더 빨리 해결됩니다. 결국 크롤링은 얼마나 복잡한 코드를 쓰느냐보다, 서버와 무리 없이 통신하는 기본 습관을 갖추는 것이 더 중요했습니다.
403과 429는 파싱 문제가 아니라 요청 방식 문제인 경우가 많습니다
이번 작업을 하면서 가장 크게 느낀 점은, 크롤링 오류가 발생했을 때 곧바로 HTML 구조나 선택자부터 의심할 필요는 없다는 사실입니다. 브라우저에서는 잘 보이는데 코드만 막힌다면, 우선 요청 헤더와 요청 속도를 먼저 점검하는 편이 훨씬 효율적입니다. 특히 403과 429는 초보자도 자주 겪는 오류이지만, 원인을 한 축으로 묶어서 보면 해결 방향이 생각보다 단순합니다. 브라우저처럼 보이게 만들고, 너무 빠르게 요청하지 않는 것입니다.
이번 글에서 사용한 방식은 화려하지 않지만 실무적으로 가장 먼저 적용해 볼 만한 방법입니다. User-Agent를 넣고, 필요한 헤더를 최소한으로 정리하고, 요청 사이에 쉬는 시간을 두는 것만으로도 차단 빈도는 충분히 줄어들 수 있습니다. 그리고 이 과정은 단순히 오류를 피하는 기술이 아니라, 사이트에 무리를 주지 않으면서 안정적으로 데이터를 가져오는 기본 태도이기도 합니다. 저는 이제 새로운 사이트를 크롤링할 때마다 파싱보다 먼저 요청 방식부터 점검하는 습관을 들이고 있습니다.