# task-475.1 보고서: 인포키워드 Step 5 광고 감지 오탐 수정

## 작업 내용

"전립선 비대증" 키워드 분석 시 네이버 블로그탭 TOP 10 결과가 전부 광고로 오탐되는 문제를 수정했습니다.

### 원인 분석
1. `_is_ad()` 함수의 `[추가 2]` 코드가 모든 `span/div/em` 요소에서 "광고" 텍스트를 전수 검색 → 블로그 본문 발췌에 "광고"라는 단어가 포함된 비광고 결과를 광고로 오탐
2. 네이버 블로그탭 실제 광고 라벨은 SVG 벡터 이미지로 렌더링되어 `get_text()`로 추출 불가능
3. `search_blogs()`가 광고를 건너뛰지 않고 TOP N에 포함시킴

### 수정 내용

**1. `_is_ad()` 정밀화 (worker/crawler/blog_search.py)**
- 제거: `[추가 2]` "광고" 텍스트 전수 검색 (오탐 원인)
- 제거: `[추가 3]` `_AD_CLASSES` 셋 기반 CSS 클래스 변형 감지 (기존 체크와 중복)
- 추가: `[추가 5]` `data-power-content-url` 속성 감지
- 유지: `_fe_view_power_content` 클래스, `integration_66.naver` 도메인, `adcr/ader.naver.com` 리다이렉트, `articleSourceJSX_adtag` heatmap-target

**2. `search_blogs()` 광고 건너뛰기 (worker/crawler/blog_search.py)**
- 광고 결과를 건너뛰고 비광고 결과만으로 TOP N 채움 (cafe_search.py와 동일 패턴)
- 비광고 결과 기준으로 rank 재부여
- 비광고 결과가 top_n 미만일 때 logger.warning() 출력

**3. analyzer.py Step 5 is_ad 방어코드**
- 광고가 이미 제외된 상태로 들어오므로 `ad_blogs`는 항상 빈 리스트
- 방어 코드로 유지 (기존 로직 변경 없음)

## 생성/수정 파일 목록
- 수정: `worker/crawler/blog_search.py` - _is_ad() 정밀화, search_blogs() 광고 건너뛰기
- 생성: `worker/tests/test_blog_search.py` - 9개 테스트 케이스 (TDD RED→GREEN)

## 테스트 결과
- 전체 테스트: **18/18 통과** (blog_search 9건 + contract 9건)
- TDD: RED(3 fail) → GREEN(9 pass) 확인
- pyright: 6개 에러 (모두 기존 에러, 수정 전 8개에서 2개 감소)
  - BeautifulSoup 타입 어노테이션 관련 기존 이슈 (본 작업 범위 외)

## 검증 기준 체크
- [x] `_is_ad()` 정밀화: "광고" 텍스트 전수 검색 제거, 정확한 신호만 사용
- [x] `search_blogs()` 광고 건너뛰기: 비광고 결과만 TOP N에 포함
- [x] 비광고 결과가 광고로 오탐되지 않음 (test_is_ad_ignores_ad_text_in_content)
- [x] 기존 테스트 전체 통과
- [ ] "전립선 비대증" 키워드 실제 크롤링 검증 (서버 기동 필요, 아누 확인 필요)

## 머지 판단
- **머지 필요**: Yes
- **브랜치**: task/task-475.1-dev1
- **워크트리 경로**: /home/jay/projects/InfoKeyword/.worktrees/task-475.1-dev1
- **머지 의견**: 모든 테스트 통과, 코드 변경 범위 최소화(blog_search.py만 수정), 기존 테스트 회귀 없음. 실 서버 기동 후 "전립선 비대증" 키워드 검증 권장.

## 버그
- 없음

## 비고
- pyright 기존 에러 6건은 BeautifulSoup의 `Tag.get()` 반환 타입 관련. 본 작업과 무관하며 전체 코드베이스 차원의 타입 어노테이션 개선 필요.
