sgkstudio.
엔지니어링

무한 스크롤 크롤링, 종료 로그를 믿었더니 실제론 10배가 있었다

무한 스크롤 크롤링에서 수집 프로그램이 스스로 찍은 '바닥 도달'이라는 종료 로그를 그대로 믿었다가, 실제로는 열 배 넘는 게시물을 두고 온 사실을 뒤늦게 알았다. 특정 계정 하나가 24건에서 멈춘 것을 보고 '프로필 화면 스크롤로는 과거 글을 전부 가져올 수 없다'고 판정해 분석 보고서에까지 한계로 적었지만, 같은 시스템 안에 이미 400일 넘게 운영해 온 계정을 3회 만에 전량 수집한 사례가 두 건 있었다. 파라미터만 바꿔 다시 실행하자 253건이 나왔고, 스크롤 횟수 제한을 더 늘리자 1,902건까지 나왔다.

2026-09-11종료 로그 신뢰 → 24건에서 수집 중단, 재실행 시 69스크롤·253건(10배)이웃 계정 대조 — 계정 B 1,832건/427일·계정 C 2,884건/425일, 각 3회 실행으로 전량 수집표본 재수집 재현 — 스크롤 상한 600으로 1,902건·2025년 1월 13일 게시물까지 확보, 표본 41건→220건으로 판정치 재산정

왜 게시물 24건에서 자동 수집이 멈췄나

무한 스크롤 크롤링에서 계정 하나가 유독 24건에서 멈추는 사고가 있었다. 여기서 무한 스크롤 크롤링이란 브라우저 화면을 자동으로 계속 내리면서 새로 나타나는 게시물을 그때그때 긁어 모으는 수집 방식을 말한다. SGK 스튜디오는 소셜미디어에 올라오는 글을 자동으로 모아 콘텐츠 소재로 쓰는 수집 시스템을 운영하는데, 같은 방식으로 여러 계정을 긁어 오다가 이 계정 하나에서만 문제가 드러났다.

수집 프로그램이 스스로 남긴 종료 로그에는 이렇게 적혀 있었다 — '종료: 바닥 도달(높이·수집 4회 연속 정체, 5스크롤)'. 화면을 다섯 번 내리는 동안 새 게시물도, 화면 높이 변화도 네 번 연속 없었으니 더 내려도 나올 게 없다고 판단해 멈췄다는 뜻이다.

이 로그 문장을 그대로 읽고 '프로필 화면을 스크롤하는 방식으로는 이 계정의 과거 글을 전부 가져올 수 없다'고 판정했다. 그 판정은 분석 보고서에까지 한계 사항으로 적혔다. 문제는 이 계정이 몇 주 전에 막 생긴 신규 계정이 아니라, 몇 달 넘게 팔로우해 온 활동 계정이었다는 점이다.

이 시스템은 계정 하나당 하루 한두 번씩 자동으로 돌아가며, 계정별로 수집한 게시물 수를 계속 누적해 저장한다. 다른 계정들은 대체로 수백에서 수천 건 단위로 쌓이는데, 이 계정만 24건에서 더 늘지 않고 멈춰 있는 상태가 눈에 띄었다. 숫자 하나가 유독 작다는 사실 자체는 눈에 보였지만, 그 작은 숫자가 '원래 그런 계정'인지 '수집이 잘못된 결과'인지는 로그만 봐서는 구분되지 않았다.

처음에는 무한 스크롤 수집의 구조적 한계라고 판단했다

24건이라는 숫자와 도구가 찍은 '바닥 도달'이라는 문구를 나란히 놓으면 결론은 자연스러워 보였다. 스크롤을 다섯 번 내려도 새 글이 안 나오면 이 계정은 원래 게시물이 그만큼밖에 없거나, 있어도 프로필 화면에서는 더 못 긁는 구조라고 보는 쪽이 합리적으로 느껴졌다.

그래서 이 한계를 그대로 분석 리포트에 옮겨 적었다. '프로필 스크롤로는 과거 글을 못 가져온다'는 문장이 그렇게 만들어졌다. 도구가 낸 결과를 의심 없이 사실로 승격시킨 순간이었다.

이 판정에 반박이 나왔다 — 이미 다른 계정 두 곳에서 같은 방식으로 게시물을 전량 수집한 사례가 있다는 지적이었다. 같은 도구, 같은 수집 방식인데 왜 유독 이 계정만 24건에서 멈췄는지를 다시 확인해야 했다.

이 판단을 어떻게 확인하려 했나

확인 수단은 세 가지였다. 첫째, 같은 시스템 안에 이미 저장돼 있는 다른 계정들의 수집 결과를 열어 대조하는 것 — 반박이 사실이라면 옆 폴더에 이미 증거가 있어야 했다. 둘째, 같은 계정 안에서 프로필 게시물 말고 다른 경로(답글 목록)로 수집한 데이터가 있는지 확인하는 것 — 같은 계정을 다른 길로 긁었을 때도 24건 근처에서 멈추는지를 보면 계정 자체의 문제인지 경로의 문제인지 가릴 수 있었다. 셋째, 스크롤 관련 파라미터만 바꿔서 같은 계정을 다시 수집해 보는 것 — 결과가 똑같이 24건 근처에서 멈추면 구조적 한계가 맞고, 다르게 나오면 판정 로직 쪽 문제였다.

세 가지 모두 새로운 도구나 별도 계측 장비가 필요 없었다. 이미 쌓여 있는 원본 데이터를 세어 보고, 같은 프로그램을 파라미터만 바꿔 다시 돌리면 되는 확인이었다. 문제는 그동안 이 세 가지 중 어느 것도 실행하지 않은 채 도구의 종료 문구만 보고 결론을 냈다는 점이다.

같은 시스템 안에 이미 반증이 있었다

첫 번째 확인에서 바로 반증이 나왔다. 옆 폴더에 이미 두 계정의 전량 수집 기록이 있었다 — 계정 B는 427일치 1,832건, 계정 C는 425일치 2,884건이었다. 계정 B의 수집 기간은 2024년 8월 25일부터 2026년 8월 11일까지였다. 둘 다 딱 3회 실행만으로 이 분량을 모았고, 한 번 실행에서 계정 B는 1,026건, 계정 C는 1,442건을 긁어 온 적도 있었다. '프로필 스크롤로는 과거 글을 다 못 가져온다'는 판정과 정면으로 배치되는 기록이 바로 옆에 있었는데, 대조를 안 한 것이다.

두 번째 확인도 같은 방향을 가리켰다. 문제가 된 계정 A의 답글 수집 경로는 같은 실행에서 6월 10일부터 8월 15일까지, 67일치 307건을 정상적으로 수집한 상태였다. 계정이 신생 계정이라 원래 글이 적은 것도 아니었고, 도구가 이 계정을 다루는 능력 자체가 없는 것도 아니었다. 유독 프로필 화면을 스크롤하는 경로 하나만 끊긴 것이었다.

세 번째 확인에서는 파라미터만 바꿔 계정 A를 다시 수집했다. 결과는 69스크롤 동안 253건 — 처음 멈췄던 24건의 10배였다. 같은 계정, 같은 프로그램, 같은 방식인데 스크롤을 다섯 번에서 멈출지 예순아홉 번까지 갈지에 따라 결과가 10배 차이 났다. 계정에는 문제가 없었다. 문제는 언제 멈출지를 정하는 판정 로직 쪽에 있었다.

진짜 원인은 자동 종료 판정 하나였다

수집 프로그램은 화면 높이가 늘지 않고 새 게시물도 안 나오는 상태가 1.8초 간격으로 4회, 즉 7.2초 연속되면 '더 내릴 게 없다'고 판단하고 수집을 끝낸다. 문제는 소셜미디어 피드가 항상 같은 속도로 로딩되지 않는다는 점이다. 어느 순간 피드 로딩이 이 7.2초보다 느려지면, 실제로는 게시물이 더 남아 있는데도 프로그램은 바닥에 닿았다고 착각하고 멈춘다.

이 원인을 증명하는 가장 직접적인 증거는 같은 명령이 실행마다 다른 결과를 낸다는 사실 자체였다. 첫 실행은 5스크롤에서 멈췄고, 파라미터를 바꾼 재실행은 69스크롤까지 갔다. 계정도, 프로그램 코드도 그대로였는데 결과만 달랐다면, 남은 변수는 '그 순간 피드가 얼마나 빨리 로딩됐는가' 하나뿐이다. 종료 문구인 '바닥 도달'은 실제 관측이 아니라, 정해 둔 시간 안에 변화가 없었다는 사실 하나를 도구가 스스로 해석해 낸 주장이었던 셈이다.

고쳤다고 생각한 뒤에도 왜 또 틀렸나

253건을 확보한 뒤 새로운 판정이 나왔다. 8월 7일부터 게시물이 폭증하고 그 이전은 산발적이니, 계정 A는 실제로 8월 7일 무렵 운영을 시작한 지 열흘 남짓 된 계정이라는 결론이었다. 이번에도 반박이 나왔다 — 이 계정을 팔로우한 지 이미 몇 달이 지났다는 지적이었다.

다시 들여다보니 8월만 게시물이 조밀하고 그 이전이 한 달에 한 건 수준으로 드문 것은 활동 패턴이 아니라 여전히 다 못 긁었다는 증거였다. 같은 계정의 답글 수집 경로가 이미 6월 10일부터 조밀하게 잡히고 있었다는 반증이 데이터 안에 그대로 있었는데, 이번에도 대조를 안 한 채 253건을 전량으로 단정한 것이다.

스크롤 상한을 600으로 올려 세 번째로 다시 수집하자 1,902건이 나왔고, 그중 가장 오래된 게시물은 2025년 1월 13일 것이었다. '불완전한 표본을 전량으로 단정하는' 같은 실수를 연속으로 두 번 반복한 셈이다. 24건을 253건으로 고친 것으로 끝났다고 여긴 순간이, 다음 오판의 출발점이었다.

같은 계정을 파라미터만 바꿔 세 차례 재수집한 결과를 나타낸 막대그래프. 1차 24건(5스크롤에서 종료), 2차 253건(69스크롤), 3차 1,902건(스크롤 상한 600).
같은 계정, 파라미터만 바꿔 다시 돌린 수집 건수 — 24건 → 253건 → 1,902건

무한 스크롤 종료 조건과 저장 방식을 어떻게 고쳤나

실제로 바꾼 것은 두 가지다. 첫째, 종료 판정 기준을 느슨하게 늦췄다 — 정체 판정 횟수를 4회에서 6회로 늘리고, 멈추기 직전에 8초의 유예 시간을 한 번 더 두어 그래도 화면에 변화가 없을 때만 진짜 바닥으로 확정하게 했다. 오판의 대가가 컸기 때문이다 — 계정 하나를 실제로는 사흘치 데이터만 보고 '전량'이라고 부르게 되는 셈이니, 조금 늦게 멈추더라도 참는 쪽으로 기울였다.

둘째, 수집한 게시물을 분석용 파일로 옮기는 단계에서 저장 방식을 고쳤다. 원래는 계정 하나를 분석할 때마다 통합 저장 파일 전체를 덮어쓰는 방식이었는데, 이 때문에 다른 계정의 분해 결과가 통째로 사라지는 사고가 있었다 — 실제로 계정 하나만 다시 분석했다가 다른 계정에서 이미 뽑아 둔 341건이 같은 날 두 차례나 사라진 적이 있다. 이제는 계정 단위로 병합해 저장하도록 고쳐, 한 계정을 다시 처리해도 다른 계정의 결과가 지워지지 않는다.

종료 판정 기준 변경 전후 코드 비교. 이전에는 정체 4회 연속(7.2초)이면 즉시 종료했고, 이후에는 정체 6회로 늘리고 종료 직전 8초 유예를 추가해 유예 후에도 변화 없을 때만 종료를 확정한다.
종료 판정 기준을 얼마나 늦췄나 — 정체 4회 즉시 종료에서 6회 + 8초 유예로

표본이 열 배 늘어나자 무엇이 달라졌나

표본 크기가 41건에서 220건으로 늘어나자, 그 표본으로 계산하던 값들도 함께 바뀌었다. 좋아요 중앙값은 31에서 43으로 올라갔고, 좋아요 10개 미만인 게시물의 비율은 37%에서 25%로 내려갔다. 가장 좋아요가 많았던 게시물의 수치는 350에서 678로 거의 두 배가 됐다. 감정을 직접 드러내는 표현으로 시작하는 게시물의 좋아요 중앙값은(표본 12건 기준) 113에서 310으로 뛰었다.

표본이 41건일 때와 220건일 때 각각 계산한 값을 비교한 표. 좋아요 중앙값 31에서 43, 좋아요 10개 미만 비율 37%에서 25%, 좋아요 최대값 350에서 678, 감정선언형 게시물 좋아요 중앙값(n=12) 113에서 310.
표본 크기가 바뀌자 달라진 값 — 41건 표본 vs 220건 표본

표본이 좁을 때 계산한 숫자는 방향까지 바뀔 수 있다는 사실을 이 표가 보여준다. 24건이나 253건짜리 표본으로 이 계정의 특성을 결론 내렸다면, 그 결론은 계정 A가 아니라 '아직 다 못 긁은 계정 A의 일부'를 설명했을 가능성이 크다.

같은 실수를 막기 위해 무엇을 바꿨나

이번 사고에서 남은 교훈은 하나다 — 도구가 화면에 찍는 판정 문구는 관측이 아니라 그 도구의 주장이다. '바닥 도달'이라는 문구는 사람이 직접 눈으로 확인한 사실이 아니라, 정해 둔 조건(정체 4회·7.2초)이 충족됐다고 프로그램이 스스로 해석해 낸 결과에 불과했다.

종료 판정을 사실로 승격하기 전에 거쳐야 했던 확인 3가지를 정리한 표. 같은 시스템 안의 반례 확인(이웃 계정 두 곳이 각각 1,832건·2,884건을 3회 실행만으로 이미 전량 수집), 같은 계정의 다른 수집 경로 비교(답글 수집 경로가 67일치 307건 정상 수집), 파라미터를 바꿔 재현(24건이 253건, 다시 1,902건).
종료 판정을 사실로 승격하기 전에 거쳐야 했던 확인 3가지

이 문구를 사실로 승격시키기 전에 확인할 수 있는 수단은 이미 세 가지가 다 있었다 — 같은 시스템 안의 반례, 같은 계정의 다른 수집 경로, 파라미터를 바꾼 재현. 이번 사고에서는 셋 다 있었는데 하나도 쓰지 않은 채 결론부터 냈고, 그 결과가 두 번 연속된 오판으로 이어졌다. 지금은 이 세 가지를 도구의 종료 판정을 그대로 믿기 전에 반드시 거치는 확인 절차로 삼고 있다.

이 절차를 세워 두고 나서 다시 보니, 처음부터 필요했던 것은 새로운 계측 장비나 더 정교한 판정 로직이 아니었다. 이미 손에 쥔 데이터를 옆으로 한 번 더 넓혀 보는 습관 하나였다. 같은 폴더 안에 있는 다른 계정의 결과를 열어 보는 데는 몇 분이 걸리지 않았는데, 그 몇 분을 아끼려다 두 번의 잘못된 판정과 그걸 정정하는 데 든 시간을 더 많이 썼다.

이 사례에서 남는 것

무한 스크롤 크롤링을 다루다 보면 '언제 멈출지'를 정하는 로직이 수집 결과 자체보다 훨씬 더 큰 영향을 미친다는 사실을 알게 된다. 이번 사고는 계정 하나에서 우연히 걸린 타이밍 문제였지만, 같은 판정 로직을 쓰는 다른 계정에서도 언제든 재현될 수 있는 구조였다. 게시물 수가 유난히 적게 나오는 계정을 발견하면, 그 숫자를 그대로 믿기 전에 옆 계정과 대조하고 다른 수집 경로와 비교하고 파라미터를 바꿔 재현해 보는 절차부터 거친다.

비슷한 문제로 웹 스크래핑에서 원본 주소가 세 군데에서 따로 사라지고 있었던 사례를 웹 스크래핑 URL 누락 사고에 정리해 두었다. 이번 사례와 함께 보면 '데이터 수집 파이프라인의 결함은 한 곳이 아니라 여러 곳에 나뉘어 숨어 있을 때가 많다'는 공통점이 보인다.

홈페이지 제작이나 챗봇 구축뿐 아니라, 이런 자동 수집·자동화 파이프라인을 직접 설계하고 검증해야 하는 업무가 있다면 상담에서 이야기를 나눌 수 있다.

같은 방식으로 우리 업무를 재보고 싶다면

이 글에 쓴 계측·판정·자동화는 저희가 실제로 매일 돌리는 방식 그대로입니다. 어떤 작업을 자동화할 수 있고 어디를 사람이 잡아야 하는지, 현재 업무 흐름을 놓고 같이 짚어 드립니다.

새 글이 올라오면 알려 드립니다

이런 계측 기록을 새로 쓰면 메일로 한 통 보냅니다. 광고나 판촉은 보내지 않습니다.