제로베이스 데이터 취업 파트타임/100일 챌린지_일일 학습 일지

제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.19]

김뚱입니다 2025. 5. 19. 23:23

[강의 요약]

[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>, &quot;, &lt; 같은 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> → 파이썬
  • &quot; → 제거됨

 

[적용한 코드]

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일반 강의 자료 일부를 발췌하여 작성되었습니다.”