feat: 초기 프로젝트 설정 및 LunchPick 앱 구현
LunchPick(오늘 뭐 먹Z?) Flutter 앱의 초기 구현입니다. 주요 기능: - 네이버 지도 연동 맛집 추가 - 랜덤 메뉴 추천 시스템 - 날씨 기반 거리 조정 - 방문 기록 관리 - Bluetooth 맛집 공유 - 다크모드 지원 기술 스택: - Flutter 3.8.1+ - Riverpod 상태 관리 - Hive 로컬 DB - Clean Architecture 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
173
doc/04_api/naver_short_url_guide.md
Normal file
173
doc/04_api/naver_short_url_guide.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# 네이버 단축 URL 자동 처리 가이드
|
||||
|
||||
## 개요
|
||||
네이버 단축 URL(naver.me)에서 식당 정보를 자동으로 추출하는 통합 기능 가이드입니다.
|
||||
이제 단축 URL 입력 시 자동으로 최적의 식당 정보를 가져옵니다.
|
||||
|
||||
## 구현된 기능
|
||||
|
||||
### 1. 단축 URL 자동 처리 플로우
|
||||
1. 단축 URL 리다이렉션
|
||||
2. Place ID 추출 (10자리 숫자)
|
||||
3. `pcmap.place.naver.com/restaurant/{ID}/home`에서 한글 텍스트 추출
|
||||
4. 추출된 상호명으로 네이버 로컬 검색 API 호출
|
||||
5. Place ID가 일치하는 결과 우선 선택 (없으면 첫 번째 결과)
|
||||
6. 정확한 식당 정보로 Restaurant 객체 생성
|
||||
|
||||
### 2. 주요 메서드
|
||||
|
||||
#### NaverApiClient
|
||||
```dart
|
||||
// 단축 URL을 최종 URL로 변환
|
||||
Future<String> resolveShortUrl(String shortUrl)
|
||||
|
||||
// Place ID로 한글 텍스트 추출
|
||||
Future<Map<String, dynamic>> fetchKoreanTextsFromPcmap(String placeId)
|
||||
```
|
||||
|
||||
#### NaverMapParser
|
||||
```dart
|
||||
// 단축 URL 전용 향상된 파싱 메서드
|
||||
Future<Restaurant> _parseWithLocalSearch(
|
||||
String placeId,
|
||||
String finalUrl,
|
||||
double? userLatitude,
|
||||
double? userLongitude,
|
||||
)
|
||||
```
|
||||
- 단축 URL 감지 시 자동으로 향상된 파싱 실행
|
||||
- 로컬 검색 API를 통한 정확한 정보 획득
|
||||
|
||||
## 테스트 방법
|
||||
|
||||
### 1. 예제 테스트 실행
|
||||
```bash
|
||||
# test/naver_short_url_example.dart 파일 수정
|
||||
# shortUrl 변수에 실제 네이버 단축 URL 입력
|
||||
|
||||
# 테스트 실행
|
||||
flutter test test/naver_short_url_example.dart
|
||||
```
|
||||
|
||||
### 2. 출력 예시
|
||||
```
|
||||
========== 네이버 단축 URL 한글 추출 테스트 ==========
|
||||
입력 URL: https://naver.me/xxxxxx
|
||||
|
||||
✓ 리다이렉션 완료
|
||||
최종 URL: https://map.naver.com/p/entry/place/1234567890
|
||||
|
||||
✓ Place ID 추출 완료
|
||||
ID: 1234567890
|
||||
|
||||
【한글 텍스트 리스트】
|
||||
① 맛있는 식당
|
||||
② 서울특별시 강남구 테헤란로 123
|
||||
③ 한식
|
||||
④ 영업시간 월요일
|
||||
⑤ 전화번호
|
||||
...
|
||||
|
||||
【추가 추출 정보】
|
||||
📍 JSON-LD 상호명: 맛있는 식당
|
||||
```
|
||||
|
||||
### 3. 앱에서 사용 시
|
||||
AddRestaurantDialog에서 네이버 URL 입력 시 자동으로 디버깅 로그가 출력됩니다.
|
||||
|
||||
## 한글 리스트 분석 방법
|
||||
|
||||
### 상호명 찾기
|
||||
- 보통 리스트 상단(인덱스 0-5)에 위치
|
||||
- JSON-LD 또는 Apollo State에서 추출된 상호명 우선 확인
|
||||
- 카테고리나 주소가 아닌 독립적인 이름
|
||||
|
||||
### 주소 찾기
|
||||
- "서울", "경기", "인천" 등 지역명이 포함된 텍스트
|
||||
- "구", "동", "로", "길" 등의 주소 키워드 포함
|
||||
- 보통 상호명 다음에 위치
|
||||
|
||||
### 기타 정보
|
||||
- 카테고리: "한식", "중식", "카페" 등
|
||||
- 영업시간: "영업시간", "오전", "오후" 포함
|
||||
- 전화번호: 숫자와 하이픈 패턴
|
||||
|
||||
## 필터링된 UI 텍스트
|
||||
다음과 같은 UI 관련 텍스트는 자동으로 필터링됩니다:
|
||||
- 로그인, 메뉴, 검색, 지도, 리뷰
|
||||
- 네이버, 플레이스
|
||||
- 영업시간, 전화번호 (라벨)
|
||||
- 더보기, 접기, 펼치기
|
||||
- 기타 일반적인 UI 텍스트
|
||||
|
||||
## 주의사항
|
||||
1. 네트워크 상황에 따라 지연이 발생할 수 있습니다
|
||||
2. 429 에러(Rate Limit) 발생 시 잠시 후 재시도하세요
|
||||
3. 웹 환경에서는 CORS 프록시를 통해 요청됩니다
|
||||
|
||||
## 네이버 로컬 검색 API 연동
|
||||
|
||||
### API 응답 형식
|
||||
네이버 로컬 검색 API는 **JSON 형식**으로 응답합니다:
|
||||
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"title": "<b>상호명</b>",
|
||||
"link": "https://map.naver.com/...",
|
||||
"category": "한식>갈비",
|
||||
"description": "설명",
|
||||
"telephone": "02-1234-5678",
|
||||
"address": "서울특별시 강남구",
|
||||
"roadAddress": "서울특별시 강남구 테헤란로 123",
|
||||
"mapx": "1269784147",
|
||||
"mapy": "375665805"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 첫 번째 한글 텍스트로 검색
|
||||
추출된 한글 텍스트의 첫 번째 항목(상호명으로 추정)을 사용하여 네이버 로컬 검색 API를 호출할 수 있습니다.
|
||||
이를 통해 정확한 식당 정보를 검증할 수 있습니다.
|
||||
|
||||
### 사용 예시
|
||||
```dart
|
||||
// 첫 번째 한글 텍스트로 검색
|
||||
final firstKoreanText = koreanTexts.first;
|
||||
final searchResults = await apiClient.searchLocal(
|
||||
query: firstKoreanText,
|
||||
display: 5,
|
||||
);
|
||||
|
||||
// 결과 확인
|
||||
for (final result in searchResults) {
|
||||
print('상호명: ${result.title}');
|
||||
print('주소: ${result.roadAddress}');
|
||||
print('Place ID: ${result.link}');
|
||||
}
|
||||
```
|
||||
|
||||
## 아키텍처 개선 사항
|
||||
|
||||
### 1. 코드 구조 개선
|
||||
- **NaverHtmlExtractor**: HTML 파싱 로직을 별도 클래스로 분리
|
||||
- **중복 코드 제거**: NaverApiClient에서 HTML 파싱 메서드 제거
|
||||
- **관심사 분리**: API 호출, HTML 파싱, 데이터 처리를 명확히 분리
|
||||
|
||||
### 2. 자동화된 처리
|
||||
- 단축 URL 입력 시 자동으로 최적의 식당 정보 추출
|
||||
- Place ID 매칭을 통한 정확도 향상
|
||||
- 사용자 개입 없이 완전 자동 처리
|
||||
|
||||
### 3. UI/UX 개선
|
||||
- AddRestaurantDialog에 JSON 형식으로 결과 표시
|
||||
- 각 필드 수정 가능
|
||||
- 시각적으로 개선된 레이아웃
|
||||
|
||||
## 향후 개선 방향
|
||||
1. 머신러닝을 통한 상호명 추출 정확도 향상
|
||||
2. 더 많은 메타데이터 추출 (리뷰, 평점 등)
|
||||
3. 오프라인 캐싱 지원
|
||||
4. 다른 지도 서비스 지원 추가
|
||||
Reference in New Issue
Block a user