Skip to content

feat: 네이버 플레이스 크롤링 안정성, 성능 개선 - #160

Merged
Wcwdfu merged 3 commits into
developfrom
feature/naver-place-apollo-crawler
Aug 13, 2026
Merged

Wcwdfu merged 3 commits into
developfrom
feature/naver-place-apollo-crawler

Conversation

@Wcwdfu

@Wcwdfu Wcwdfu commented Aug 13, 2026 •

Copy link
Copy Markdown
Member

개요

이번 변경은 크게 네이버 식당 갱신 크롤 과정 개선과 테스트 실행 체계 표준화 두 부분으로 구성됩니다.

  1. 네이버 식당 크롤링시 graphQL을 파싱해 크롤링 하려던 시도가 안되는 원인을 찾아 해결했습니다.
  2. 기존 테스트 실행 체계가 적절하지 못했음을 인지하고, 개선했습니다.

1. 네이버 식당 갱신 크롤 과정 개선

기존 로직

  • 네이버 플레이스의 home/menu HTML 응답을 받은 뒤, 난독화된 CSS 선택자를 이용해 DOM에서 식당 기본 정보와 메뉴를 추출했습니다.
  • 식당 하나를 처리할 때마다 Playwright 브라우저·컨텍스트를 새로 생성했고, 식당 사이에 3~5초 랜덤 대기가 있었습니다.
  • 메뉴 데이터 유무와 관계없이 메뉴 화면 로딩에 의존하는 구간이 있었습니다.
  • 그리드 탐색 실패가 빈 결과로 처리될 수 있었고, 캡차와 일반 실패를 구분하지 못해 이미 수집한 진행 상태를 명확하게 보존하기 어려웠습니다.
  • 그리드 수집 실패 시 원인과 관계없이 일정 간격으로 자동 재시도했기 때문에, 네이버의 크롤링 방지용 캡차가 발생한 경우에도 성공 가능성이 낮은 요청을 반복했습니다.
  • 구역 크롤 작업의 동시 실행 제한이 없어 여러 작업이 동시에 브라우저를 사용할 수 있었습니다.

개선 로직

  • HTML에 포함되어 브라우저로 전달되는 window.__APOLLO_STATE__ 캐시를 먼저 파싱해 이름, 주소, 전화번호, 좌표, 이미지, 메뉴 등을 추출합니다.
  • Apollo 캐시가 없거나 일부 필드가 비어 있을 때만 기존 DOM 추출을 필드 단위 fallback으로 사용합니다.
  • Apollo 캐시에 메뉴 데이터가 있으면 메뉴 화면을 열지 않고, 메뉴 데이터가 없을 때만 기존 DOM 메뉴 추출을 수행합니다.
  • 구역 작업 하나에서는 Playwright 브라우저·컨텍스트를 재사용하고 식당별 페이지만 분리하며, 식당 사이의 3~5초 랜덤 대기를 제거했습니다.
  • 네이버의 캡차를 풀거나 우회하지 않고 보안 인증 화면을 감지하면 자동 재시도를 즉시 중단합니다. 캡차는 세션이나 요청 주기에 대한 제한이 유지되는 동안 짧은 간격으로 다시 요청해도 같은 실패가 반복될 가능성이 높기 때문입니다.
  • 캡차 발생 시 작업을 CAPTCHA_REQUIRED 상태로 전환하고, 완료된 그리드와 발견한 placeId를 체크포인트로 보존합니다. 이후 사용자가 어드민 화면의 실패 그리드부터 재시도 버튼을 눌러 새 브라우저 세션에서 멈춘 그리드부터 직접 재개할 수 있도록 했습니다.
  • 캡차가 아닌 일시적인 그리드 탐색 오류에 대해서만 제한된 자동 재시도를 유지하고, 재시도 소진 시 빈 결과로 숨기지 않고 명시적인 실패로 처리합니다.
  • 동시에 실행할 수 있는 구역 크롤 작업과 Playwright 브라우저를 1개로 제한했습니다.
  • 운영 크롤러와 테스트 크롤러가 동일한 그리드 기본값을 사용하도록 공통 상수로 정리했습니다.

속도 비교

비교 조건은 다음과 같습니다.

  • 5개 구역별로 고정된 네이버 식당 placeId 10개를 같은 순서로 상세 수집
  • 기존 방식: 식당별 브라우저 생성 + DOM 중심 추출 + 식당 사이 3~5초 랜덤 대기
  • 개선 방식: 브라우저·컨텍스트 재사용 + Apollo 우선 추출 + 랜덤 대기 제거
구역 기존 방식 개선 방식 시간 단축
건입~중문 240.2초 49.0초 79.6%
중문~어대 252.6초 39.5초 84.4%
후문 238.3초 64.1초 73.1%
정문 247.5초 38.1초 84.6%
구의역 231.1초 55.3초 76.1%
  • 5개 구역 총 소요 시간: 20분 10초 → 4분 6초
  • 구역당 평균 소요 시간: 4분 2초 → 49초
  • 전체 소요 시간 기준: 79.7% 단축

이 벤치마크는 구역별 고정 식당 10개의 상세 수집 성능을 비교한 결과입니다. 전체 구역의 모든 식당을 수집하는 운영 시간은 네이버 응답 속도, 식당 수, 재시도 및 캡차 발생 여부에 따라 달라질 수 있습니다.

2. 테스트 실행 체계 표준화

소형·중형 테스트 구분은 유지하되, Gradle·IntelliJ·GitHub Actions가 같은 태스크와 결과 경로를 사용하도록 실행 구조를 정리했습니다.

기존 구조

  • 기본 Gradle test 태스크가 비활성화되어 있었습니다.
  • 소형 테스트를 별도 smallTest 태스크로 다시 정의했고, 중형 테스트 source set과 실행 태스크 이름도 middleTest로 달랐습니다.
  • 이 구조 때문에 IntelliJ에서 표준 테스트 실행 시 테스트 이벤트를 받지 못하거나, 테스트 트리와 개별 통과 결과가 표시되지 않는 경우가 있었습니다.
  • CI가 별도 태스크명과 결과 경로를 사용해 로컬 실행 방식과 어긋나 있었습니다.

개선 구조

  • 소형 테스트는 Gradle 표준 test 태스크를 그대로 사용합니다.
  • 중형/통합 테스트는 integrationTest source set과 동일한 이름의 integrationTest 태스크로 실행합니다.
  • check 실행 시 소형 테스트 후 중형 테스트가 이어서 실행되도록 연결했습니다.
  • 불필요한 smallTest, middleTest 별칭 태스크는 제거했습니다.
  • IntelliJ의 Gradle 테스트 러너가 표준 테스트 이벤트를 받아 테스트 트리와 클래스·메서드별 성공 여부를 표시할 수 있도록 했습니다.
  • 개발 환경의 Testcontainers 호환을 위해 Docker API 버전을 테스트 리소스에 명시하고, 통합 테스트에서 사용하지 않는 크롤러 주소에는 테스트용 값을 추가했습니다.
  • GitHub Actions도 :server:kustaurant:test, :server:kustaurant:integrationTest를 실행하고 각각의 표준 XML 결과 경로를 게시하도록 수정했습니다.

PR 유형

어떤 변경 사항이 있나요?

  • 새로운 기능 추가
  • 버그 수정
  • 사용자 UI 디자인 변경
  • 코드에 영향을 주지 않는 변경사항(오타 수정, 변수명 변경 등)
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 테스트 추가, 테스트 리팩토링
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • AI Review Request

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 70f22518-9e98-4418-9163-741eb143517c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

🧪 소형(단위) 테스트 결과

119 tests   119 ✅  2s ⏱️
 31 suites    0 💤
 31 files      0 ❌

Results for commit 16b57da.

@github-actions

Copy link
Copy Markdown

🚀 중형(통합) 테스트 결과

9 tests   9 ✅  0s ⏱️
1 suites  0 💤
1 files    0 ❌

Results for commit 16b57da.

@Wcwdfu Wcwdfu changed the title feat: 네이버 플레이스 크롤링 안정성 개선 feat: 네이버 플레이스 크롤링 안정성, 성능 개선 Aug 13, 2026
@Wcwdfu
Wcwdfu marked this pull request as ready for review August 13, 2026 07:03
@Wcwdfu
Wcwdfu merged commit f1b7ad9 into develop Aug 13, 2026
4 checks passed
@Wcwdfu Wcwdfu self-assigned this Aug 13, 2026
@Wcwdfu
Wcwdfu deleted the feature/naver-place-apollo-crawler branch August 13, 2026 07:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant