제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.19]
[강의 요약]
[Part 04. EDA/웹 크롤링/파이썬 프로그래밍_ Ch 07. Naver API] 강의 수강
클립 01~07까지 강의 수강하였음
🐢 100일 챌린지 🔥 : [▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰ ] 64/100일 (64%)
[클립 01~07까지 정리]
▶ 1. Naver Open API 개요, 블로그 검색
- urllib 모듈 개념
- urllib : HTTP 통신 프로토콜 기반 요청/응답 처리를 위한 표준 라이브러리
- urllib.request : 클라이언트 측 요청 생성 및 전송
- urllib.parse : URL 인코딩 및 파라미터 처리
[블로그 검색 API 호출 코드]
import os
import sys
import urllib.request
client_id = "발급받은 클라이언트ID"
client_secret = "발급받은 클라이언트Secret"
encText = urllib.parse.quote("파이썬")
url = "https://openapi.naver.com/v1/search/blog?query=" + encText # json 형식 요청
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()
print(response_body.decode("utf-8"))
else:
print("Error Code:" + str(rescode))
- urllib.parse.quote()로 한글 검색어를 URL 인코딩
- 헤더에 반드시 X-Naver-Client-Id와 X-Naver-Client-Secret을 넣어야 정상 응답을 받을 수 있다.
- 응답 상태 코드가 200이면 정상 응답, 아니라면 오류를 출력한다.
[응답 디코딩 코드]
print(response_body.decode("utf-8"))
바이트 형태로 받은 응답은 .decode("utf-8")을 통해 문자열로 변환하여 읽는다.
▶ 2. 책 검색 및 전문자료 API 호출
[책 검색 API 호출 코드]
import os
import sys
import urllib.request
client_id = "발급받은 클라이언트ID"
client_secret = "발급받은 클라이언트Secret"
encText = urllib.parse.quote("파이썬")
url = "https://openapi.naver.com/v1/search/book?query=" + encText
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()
print(response_body.decode("utf-8"))
else:
print("Error Code:" + str(rescode))
- 핵심 차이점은 url이 "book"으로 바뀐 것뿐이다.
- 응답 결과는 책 제목, 저자, 가격, ISBN 등의 정보가 포함된다.
[전문자료 검색 API 호출]
encText = urllib.parse.quote("파이썬")
url = "https://openapi.naver.com/v1/search/encyc?query=" + encText
전문자료도 동일하게 작동하며, 위키/백과사전 기반 콘텐츠가 결과로 반환된다.
▶ 3. 검색 API를 함수로 구조화
중복되는 Request → Header → Response 코드를 줄이기 위해 함수로 작성한다.
[공통 검색 요청 함수]
def naver_search(api_name, keyword):
import urllib.request
import json
client_id = "발급받은 ID"
client_secret = "발급받은 Secret"
encText = urllib.parse.quote(keyword)
url = f"https://openapi.naver.com/v1/search/{api_name}?query=" + encText
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)
if response.getcode() == 200:
return json.loads(response.read().decode("utf-8"))
else:
print("Error:", response.getcode())
return None
[사용 예시]
result_blog = naver_search("blog", "파이썬")
result_book = naver_search("book", "머신러닝")
result_encyc = naver_search("encyc", "인공지능")
- 이제 API 이름과 검색어만 바꾸면 손쉽게 다양한 도메인의 데이터를 가져올 수 있다.
[데이터 결과 구조 확인]
API 호출 결과는 JSON 형태이며, 주요 내용은 ['items'] 리스트에 포함되어 있다.
items = result_blog['items']
for item in items[:3]:
print(item['title'], item['link'])
- 각 아이템에는 title, description, link, pubDate(뉴스일 경우), author, isbn(책일 경우) 등의 정보가 포함된다.
▶ 4. 검색 결과를 pandas DataFrame으로 정리 및 저장
Naver API에서 받아온 데이터는 리스트 형태의 딕셔너리(items)로 구성되어 있어
이를 pandas.DataFrame으로 쉽게 변환할 수 있다.
[JSON → DataFrame 변환 코드]
import pandas as pd
items = result_blog['items'] # 예: 블로그 검색 결과
df = pd.DataFrame(items)
df.head()
- 리스트의 각 딕셔너리 항목이 행(row)으로 변환된다.
- 자동으로 딕셔너리의 키는 열(column)이 된다.
[열 정리 및 주요 컬럼 선택 코드]
검색 API는 응답 항목이 많기 때문에 우리가 관심 있는 항목만 추려내야 한다.
df = df[["title", "description", "link"]]
▶ 5. HTML 태그 제거 및 텍스트 정리
Naver API 결과에는 <b>, ", < 같은 HTML 태그나 엔티티가 포함되어 있다. 이를 제거해야 한다.
[정규표현식 기반 클리너 함수 코드]
import re
def clean_html(text):
cleanr = re.compile('<.*?>')
text = re.sub(cleanr, '', text)
text = re.sub('&[a-z]+;', '', text)
return text
- <b>파이썬</b> → 파이썬
- " → 제거됨
[적용한 코드]
df['title'] = df['title'].apply(clean_html)
df['description'] = df['description'].apply(clean_html)
이 과정을 거치면 시각적으로도 깔끔한 결과를 확인할 수 있다.
▶ 6. CSV 또는 Excel로 저장하기
[CSV로 저장하는 코드]
df.to_csv("naver_blog_search.csv", index=False, encoding='utf-8-sig')
- utf-8-sig 인코딩은 엑셀에서 한글이 깨지지 않도록 보장한다.
[Excel로 저장하는 코드]
df.to_excel("naver_blog_search.xlsx", index=False)
- pandas의 .to_excel()은 엑셀 파일로도 손쉽게 저장할 수 있다.
- 단, openpyxl 또는 xlsxwriter가 설치되어 있어야 한다.
▶ 7. 뉴스 제목/내용에서 명사 추출
[형태소 분석기 불러오기]
from konlpy.tag import Okt
okt = Okt()
- Okt : 트위터에서 파생된 한국어 형태소 분석기 (KoNLPy 제공)
- 명사, 동사, 조사 등을 구분해 주고 특히 명사 추출 기능이 강력하다.
[명사만 추출하는 함수 만들기]
def extract_nouns(text):
nouns = okt.nouns(text)
return [n for n in nouns if len(n) > 1]
- 한 글자짜리 명사는 노이즈가 많아 len(n) > 1 필터링으로 제거한다.
- 뉴스/블로그 제목에는 짧은 단어가 많기 때문에 유효하다.
[전체 뉴스 제목에서 명사 수집]
nouns = []
for line in df["title"]:
nouns.extend(extract_nouns(line))
- 한 줄씩 순회하면서 명사 리스트를 확장한다.
▶ 8. 키워드 빈도 분석
from collections import Counter
count = Counter(nouns)
top100 = dict(count.most_common(100))
- collections.Counter : 단어 빈도를 쉽게 계산할 수 있는 클래스
- most_common(100) : 상위 100개의 단어를 가져옴
▶ 9. 워드 클라우드 시각화
워드 클라우드는 단어의 빈도수를 크기로 표현하는 시각화다.
자주 등장한 단어일수록 크게 보인다.
from wordcloud import WordCloud
import matplotlib.pyplot as plt
wordcloud = WordCloud(
font_path='NanumGothic.ttf', # 한글 폰트 경로 지정 필요
background_color='white',
width=800,
height=400
).generate_from_frequencies(top100)
plt.figure(figsize=(15, 8))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()
- 기본적으로 워드클라우드는 영어 글꼴만 지원한다.
- 반드시 한글 폰트를 직접 지정해야 깨지지 않는다.
- NanumGothic.ttf는 네이버 나눔 폰트에서 제공한다.
▶ 10. 날짜 기반 뉴스량 시각화 (트렌드 분석)
뉴스/블로그 등 텍스트 데이터는 “무엇이 나왔는가” 뿐 아니라 "언제 많이 나왔는가”도 중요한 분석 지표다.
특정 키워드가 어떤 시점에 폭발적으로 언급되었는지를 보면, 사회적 반응이나 여론 흐름을 파악할 수 있다.
[날짜 컬럼 준비 코드]
df['pubDate'] = pd.to_datetime(df['pubDate'], format='%a, %d %b %Y %H:%M:%S +0900')
df['date'] = df['pubDate'].dt.date
- pubDate : 원래 문자열 형태의 날짜를 datetime 객체로 변환
- .dt.date : 연/월/일만 남긴 날짜형 컬럼 생성
[일자별 뉴스 건수 집계 코드]
date_counts = df['date'].value_counts().sort_index()
- .value_counts() : 날짜별로 몇 개의 뉴스가 있는지 세어준다.
- .sort_index() : 날짜 순으로 정렬한다.
[바 차트로 시각화 코드]
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
date_counts.plot(kind='bar', color='skyblue')
plt.title("일자별 뉴스/블로그 건수")
plt.xlabel("날짜")
plt.ylabel("건수")
plt.xticks(rotation=45)
plt.grid(axis='y')
plt.tight_layout()
plt.show()
- bar : 막대 그래프로 표현
- 날짜별 뉴스량의 증감이 한눈에 보인다.
- 특정 날짜에 이슈가 몰려 있는지를 바로 알 수 있다.
[라인 차트로 시각화 코드]
date_counts.plot(kind='line', marker='o')
- 선 그래프는 추세(트렌드)를 보여줄 때 더 직관적이다.
- 일별 뉴스 증가/감소 흐름을 연결된 선으로 관찰 가능하다.
[나의 생각 정리]
예전에 이렇게 사용해 본 것 같기도 하고...?
형태소 분석기랑 시각화까지 해본 기억은 있는 것 같은데 기억이 잘 안 난다.
[적용점]
API를 이용한 데이터 분석에서 사용
“이 글은 제로베이스 데이터 스쿨 주 3일반 강의 자료 일부를 발췌하여 작성되었습니다.”