네이버 API만으로 블로그 200개, 쇼핑 상품 정보를 한 번에 뽑아낼 수 있다는 거 알았어요?
인증 설정부터 실제 코드까지 손 가는 대로 따라 하면 자동화 스크립트 완성이거든요.
https://developers.naver.com/docs/common/openapiguide/apilist.md
반드시 필요한 인증 정보 설정
API 호출할 때마다 HTTP 헤더에 두 개 값을 넣어야 해요.
X-Naver-Client-Id: qvF9HUvh7pf5Gb8gUp3R
X-Naver-Client-Secret: Ph9yV5lCQ8
이 두 줄 없으면 403 오류만 떨어지니까 개발자센터에서 먼저 내 애플리케이션 설정에서 '검색 API' 활성화 확인하고 시작하세요.
세 가지 주요 API 엔드포인트
블로그 검색, 쇼핑 검색, 트렌드 분석—이 셋이 전부예요.
| 기능 | 엔드포인트 | 응답 형식 | 언제 쓰나 |
|---|---|---|---|
| 블로그 검색 | /v1/search/blog.json |
JSON | 블로그 포스트·URL 수집 |
| 쇼핑 검색 | /v1/search/shop.json |
JSON | 상품명·가격·링크 수집 |
| 트렌드 분석 | /v1/datalab/search |
JSON | 키워드 검색량 추이 |
블로그·쇼핑 검색 실전 코드
import urllib.request
import json
CLIENT_ID = "qvF9HUvh7pf5Gb8gUp3R"
CLIENT_SECRET = "Ph9yV5lCQ8"
def search_naver_api(query, api_type="blog", display=10, start=1, sort="date"):
"""
네이버 검색 API 호출
api_type: "blog" 또는 "shop"
sort: "sim"(정확도) / "date"(날짜순)
"""
encText = urllib.parse.quote(query)
url = f"https://openapi.naver.com/v1/search/{api_type}.json?query={encText}&display={display}&start={start}&sort={sort}"
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id", CLIENT_ID)
request.add_header("X-Naver-Client-Secret", CLIENT_SECRET)
response = urllib.request.urlopen(request)
rescode = response.getcode()
if rescode == 200:
response_body = response.read()
return json.loads(response_body.decode('utf-8'))
else:
print(f"Error Code: {rescode}")
return None
# 사용 예시
result = search_naver_api("맛집", "blog", display=10, sort="date")
print(result)
한 번에 100개만 가져올 수 있으니까, 200개가 필요하면 두 번 호출하는 게 핵심이에요.
데이터 200개 수집하기
def collect_200_items(keyword, api_type="blog"):
"""특정 키워드로 200개 데이터 수집"""
all_items = []
# 1차: 1~100번째
result1 = search_naver_api(keyword, api_type, display=100, start=1, sort="date")
if result1 and 'items' in result1:
all_items.extend(result1['items'])
print(f"1차 수집: {len(result1['items'])}개")
# 2차: 101~200번째
result2 = search_naver_api(keyword, api_type, display=100, start=101, sort="date")
if result2 and 'items' in result2:
all_items.extend(result2['items'])
print(f"2차 수집: {len(result2['items'])}개")
print(f"총 수집: {len(all_items)}개")
return all_items[:200]
# 사용 예시
items = collect_200_items("광저우", "blog")

이렇게 하면 start를 1과 101로 나눠서 호출하는 거예요. 최대 1000까지 가능하니까 필요하면 start를 301, 401 이런 식으로 계속 늘려도 돼요.
API 응답 데이터 구조
블로그 응답
{
"lastBuildDate": "Mon, 26 Sep 2016 10:39:37 +0900",
"total": 8714891,
"start": 1,
"display": 10,
"items": [
{
"title": "블로그 포스트 제목",
"link": "https://blog.naver.com/...",
"description": "내용 요약",
"bloggername": "블로거 이름",
"bloggerlink": "블로그 주소",
"postdate": "20251208"
}
]
}
쇼핑 응답
{
"items": [
{
"title": "상품명",
"link": "https://shopping.naver.com/...",
"image": "이미지 URL",
"lprice": "최저가",
"hprice": "최고가",
"mallName": "쇼핑몰명",
"productId": "상품ID",
"productType": "1"
}
]
}
title 필드에 <b> 태그가 붙어 있을 수 있으니까, 저장할 때 replace('<b>', '').replace('</b>', '') 로 제거해두면 깔끔해요.
트렌드 분석 API (데이터랩)
키워드별 검색량 추이를 보고 싶으면 이 API를 써요. POST 방식이라 좀 다르긴 한데 구조는 간단해요.
import requests
import json
def get_trend_data(keywords, start_date, end_date, time_unit="date"):
"""
키워드별 검색량 추이 조회
Args:
keywords: 키워드 리스트 (예: ["맛집", "카페"])
start_date: 시작일 (예: "2025-01-01")
end_date: 종료일 (예: "2025-12-31")
time_unit: "date", "week", "month"
"""
url = "https://openapi.naver.com/v1/datalab/search"
body = {
"startDate": start_date,
"endDate": end_date,
"timeUnit": time_unit,
"keywordGroups": [
{
"groupName": "그룹1",
"keywords": keywords
}
]
}
headers = {
"X-Naver-Client-Id": CLIENT_ID,
"X-Naver-Client-Secret": CLIENT_SECRET,
"Content-Type": "application/json"
}
response = requests.post(url, json=body, headers=headers)
if response.status_code == 200:
return response.json()
else:
print(f"Error: {response.status_code}")
return None
# 사용 예시
trend_data = get_trend_data(
keywords=["광저우", "중국여행"],
start_date="2025-01-01",
end_date="2025-12-31",
time_unit="month"
)
print(json.dumps(trend_data, ensure_ascii=False, indent=2))
주의할 점: API 제약사항
딱 4가지만 기억하면 돼요.
- 기간 검색 안 됨: API 자체에 기간 필터링 파라미터가 없어요. sort=date로 최신순 정렬하고 필요하면 나중에 필터링하세요.
- display 최대 100개: 한 번에 100개씩만 가져올 수 있어요.
- start 최대 1000: 1~1000 범위만 지원해요.
- 일일 한도: 검색 API는 25,000회, 데이터랩은 1,000회예요.
전체 파이프라인 통합 코드
import urllib.request
import json
import hashlib
from datetime import datetime
CLIENT_ID = "qvF9HUvh7pf5Gb8gUp3R"
CLIENT_SECRET = "Ph9yV5lCQ8"
def search_naver(query, api_type="blog", display=100, start=1, sort="date"):
"""네이버 검색 API 호출"""
encText = urllib.parse.quote(query)
url = f"https://openapi.naver.com/v1/search/{api_type}.json?query={encText}&display={display}&start={start}&sort={sort}"

request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id", CLIENT_ID)
request.add_header("X-Naver-Client-Secret", CLIENT_SECRET)
try:
response = urllib.request.urlopen(request)
return json.loads(response.read().decode('utf-8'))
except Exception as e:
print(f"Error: {e}")
return None
def collect_200(keyword, api_type="blog"):
"""200개 데이터 수집"""
all_items = []
for start in [1, 101]:
result = search_naver(keyword, api_type, display=100, start=start, sort="date")
if result and 'items' in result:
all_items.extend(result['items'])
print(f"수집 완료: {len(result['items'])}개 (start={start})")
print(f"총 수집: {len(all_items)}개")
return all_items[:200]
def convert_to_schema(items, keyword, platform="naver_blog"):
"""API 응답을 통합 스키마로 변환"""
result = []
for item in items:
title = item.get('title', '').replace('<b>', '').replace('</b>', '')
desc = item.get('description', '').replace('<b>', '').replace('</b>', '')
postdate = item.get('postdate', '')
if len(postdate) == 8:
postdate = f"{postdate[:4]}-{postdate[4:6]}-{postdate[6:8]} 00:00:00"
converted = {
"keyword": keyword,
"platform": platform,
"content_id": hashlib.md5(item.get('link', '').encode()).hexdigest(),
"title": title,
"content_text": desc,
"post_date": postdate,
"url": item.get('link', ''),
"author": item.get('bloggername', ''),
"platform_specific_data": {
"naver": {
"blogger_name": item.get('bloggername', ''),
"bloggerlink": item.get('bloggerlink', '')
}
}
}
result.append(converted)
return result
def save_to_file(data, filename):
"""JSON 파일로 저장"""
with open(filename, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"✅ 저장 완료: {filename}")
def main():
keyword = "광저우"
print(f"🔍 '{keyword}' 검색 시작...")
items = collect_200(keyword, "blog")
if not items:
print("❌ 데이터를 수집하지 못했습니다.")
return
schema_data = convert_to_schema(items, keyword)
filename = f"naver_{keyword}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
save_to_file(schema_data, filename)
print(f"📊 총 {len(schema_data)}개 데이터 수집 완료!")
if __name__ == "__main__":
main()
자주 묻는 것들
Q: 기간별로 2025년 1월~3월만 수집할 수 있나? A: 아뇨, API 자체에 기간 필터링이 없어요. sort=date로 최신순 정렬 후 응답받은 데이터를 후처리해서 필터링하세요.
Q: 200개 이상 원하면? A: start를 1→101→201→301→... 식으로 늘려서 호출하면 돼요. 최대 1000까지 가능합니다.
Q: 403 에러가 자꾸 나요. A: 개발자센터 > 내 애플리케이션 > API 설정에서 '검색'이 정말 활성화되어 있는지 확인하세요. 대기열 상태면 사용 불가예요.
Q: 블로그에서 공감·댓글 수도 함께 수집할 수 있나?
A: API는 검색 결과만 주니까 개별 블로그 URL을 크롤링해서 따로 가져와야 해요. BeautifulSoup으로 .u_likeit_count 같은 선택자를 파싱하면 됩니다.
네이버 API만으로는 한계가 있지만, 이 방법으로 블로그·쇼핑 데이터를 깔끔하게 자동화할 수 있


댓글 0