2편에서 네이버 뉴스 크롤링 중 겪은 차단을 “누적 요청량 기반 시간창 rate-limit”이라는 가설로 설명했다. 다만 그 결론 자체가 “오늘 하루 이미 900건 넘게 이 IP로 쐈다”는 조건 위에서 나온 것이라, 완전히 깨끗한 IP로 다시 확인해봐야 한다는 숙제가 남아 있었다. 그 뒤로 이 IP로는 사흘 동안 아무 요청도 보내지 않았다. 오늘, 그 사흘을 식힌 IP로 다시 확인해볼 차례가 왔다.
4차와 똑같은 조건, 다른 IP 상태 — 네이버 크롤링 재검증
커맨드는 4차와 완전히 동일했다. 진단용 가이드, 삼성전자+현대차 두 타깃, 실제 파이프라인 코드. 유일한 차이는 이 IP가 사흘 동안 완전히 쉬었다는 것뿐이었다.
완전 차단은 아니었다, 그런데
1단계(검색)는 이번엔 끝까지 완주했다. 22분 걸려서 고유 URL 8,628개를 발견했다 — 4차(완전 실패, URL 0개)와는 확실히 다른 결과였다. 처음엔 “이번엔 막히지 않았구나” 싶었다.
그런데 키워드 38개(38키워드 × 14개 날짜구간 = 532회 요청 시도)를 하나씩 까보니 그림이 달랐다.
| 결과 | 키워드 수 |
|---|---|
| 14/14구간 전부 403 | 35개 |
| 11/14구간 403(3개만 성공) | 2개(두 타깃 각각의 첫 번째 키워드, “로봇”) |
| 13/14구간 403(1개만 성공) | 1개 |
성공한 요청은 532건 중 딱 7건, 1.3%였다. 8,628개라는 URL 수는 이 7건이 하필 페이지네이션 캡(구간당 2,000건)까지 깊게 파고든 결과였다 — 겉보기 숫자만 보면 멀쩡해 보이지만, 사실상 거의 다 막혀 있었다.
”하루 지나면 풀린다”는 가설이 깨졌다 — 네이버 크롤링 IP 차단 해제 시간
4차(요청 1번째부터 100% 차단, 예외 없음)와 정확히 같지는 않다. 이번엔 실행 극초반 몇 건 — 정확히는 각 타깃의 첫 번째 키워드가 처리되던 순간 — 은 통과됐고, 그 직후부터 사실상 전부 막혔다.
이건 두 가지를 동시에 말해준다. 하나는 “하루 종일 테스트해서 IP가 지쳐있었다”는 설명이 깨졌다는 것 — 사흘을 완전히 식혔는데도 마찬가지 였으니까. 다른 하나는 원래 가설(누적 요청량 기반 시간창 차단)이 더 좁혀졌다는 것 — 완전히 식은 IP에서도, 이 실행 자체 안에서 수십~수백 건 규모의 요청만으로 순식간에 걸린다는 뜻이 됐다. 임계값이 애초에 아주 낮다는 이야기다. “하루 지나면 풀린다”보다는, “이 정도 규모의 배치를 한 번에 돌리면 거의 항상 초반에 걸린다”는 쪽이 실무적으로 더 중요한 결론이 됐다.
코드를 다시 보니, 딜레이도 재시도도 없었다
이 김에 실제 파이프라인 코드를 다시 확인했다. 이 검색 경로에는 요청 사이 딜레이가 단 한 군데도 없었다 — 페이지 사이도, 날짜구간 사이도, 키워드 사이도 전부 무지연이었다. 재시도 로직도 없어서, 403이 뜨면 그 즉시 포기하고 다음으로 넘어갈 뿐이었다. 게다가 두 타깃이 동시에 처리되니 요청이 겹치기까지 했다.
1~2편의 진단 스크립트들은 전부 이 파이프라인 코드와는 무관한 별도 스크립트였다는 걸 다시 떠올리게 됐다 — 그중 1편의 첫 실험만 의도적으로 1초 딜레이를 넣어봤을 뿐, 실제 운영 코드 자체는 애초에 딜레이도 백오프도 전혀 없는 상태로 계속 돌아가고 있었던 것이다.
이 사실이 계속 마음에 걸렸다. 원인 규명은 여전히 진행 중이었지만, 브레이크부터 달아보는 게 순서상 맞아 보였다.
딜레이와 백오프를 추가하다 — 네이버 크롤링 403 대응
두 가지를 코드에 더했다. 페이지 요청 전에 기본 1.5초 딜레이를 주는 것, 그리고 403이 뜨면 5초를 기다렸다가 재시도하고 그래도 안 되면 10초를 더 기다렸다가 한 번 더 재시도하는 것(최대 2회). 그래도 안 되면 그 페이지는 포기하고 넘어가도록 했다 — 기존과 동일하게, 다만 이번엔 최소한의 저항은 해보고 포기하는 식으로.
재검증 — 이번엔 일부러 더 빡빡한 조건으로
이 실험이 끝난 직후, IP가 식을 시간을 주지 않고 바로 같은 커맨드를 다시 돌렸다. 이미 데워진 IP에서도 5초 백오프가 통하는지 보는, 일부러 더 빡빡한 조건이었다.
재시도가 사실상 항상 성공했다
47분 동안 403이 579번 떴다. 그런데 그 579번 전부 1번째 재시도 (5초 대기 후)에서 성공했다. 2번째 재시도(10초 대기)까지 간 적도, 완전히 포기한 적도 단 한 번도 없었다.
“403이 뜨면 5초만 쉬어도 거의 항상 뚫린다”는 게 실측으로 확인된 순간이었다.
그런데 첫 키워드 하나도 못 끝냈다
문제는 속도였다. 47분 동안 38개 키워드 중 첫 번째 키워드 쌍 (“로봇”, 두 타깃 각각 하나씩)조차 다 끝내지 못했다.
“로봇”이 워낙 고빈도 키워드라, 한 날짜구간(30일)만으로도 캡(2,000건 = 200페이지)까지 페이지네이션이 깊게 들어간다. 그런데 그 200페이지 거의 매 페이지마다 403이 뜨고, 5초를 기다렸다가 재시도하는 게 사실상 필수 과정처럼 끼어들었다. 계산해보면 분당 12~13페이지 정도의 속도였고, 이 페이스로 38개 키워드 전체를 도는 데는 몇 시간이 걸릴 것으로 추정됐다. 더 이상 기다려봐야 의미 있는 새 정보가 나올 것 같지 않아 그 자리에서 멈췄다.
남는 생각
사흘을 기다린 건 “시간이 지나면 풀린다”는 가설을 검증하기 위해서였다. 결과는 그 가설을 반쯤 깼다 — 풀리긴 풀리는데, “풀린 상태”가 유지되는 시간이 기대보다 훨씬 짧았다. 완전히 새 상태로 시작해도, 코드에 브레이크가 하나도 없다면 몇 분 안에 다시 소진된다는 걸 그 자리에서 확인한 셈이다.
그래서 브레이크를 달았고, “고쳤다”의 기준을 다시 생각하게 됐다. 막히는 문제 자체는 분명히 고쳐졌다 — 재시도 성공률이 100%였으니까. 하지만 안 막히는 것과, 쓸 만한 속도로 도는 것은 서로 다른 문제였다. 5초라는 대가가 페이지 하나마다 거의 매번 붙으면, 아무리 재시도가 항상 성공해도 전체 작업은 사실상 못 쓰는 속도가 된다. 막힘을 우회하는 방법을 찾는 것과, 그 우회 비용이 감당할 만한 수준인지 확인하는 것은 분명히 다른 단계였고, 이번엔 그 두 단계 사이에서 걸렸다.