🔍 실시간 검색어를 통해 뉴스 검색 시스템을 어떻게 구현할까?
실패와 실패를 거듭한 최종 결과물
📋 목차
🎯프로젝트 개요
실시간으로 화제가 되고 있는 키워드를 자동으로 수집하고, 해당 키워드와 관련된 최신 뉴스를 검색하는 시스템을 구현하고자 했습니다. 언뜻 간단해 보이는 이 프로젝트는 실제로는 여러 번의 실패와 시행착오를 거쳐야 했던 도전적인 과제였습니다.
• 구글 트렌드에서 실시간 인기 검색어 수집
• 네이버 뉴스 API를 통한 관련 기사 검색
• 자동화된 뉴스 큐레이션 시스템 구축
❌첫 번째 시도: pytrends API의 좌절
🔧 pytrends란?
pytrends는 구글 트렌드의 비공식 Python API로, 구글 트렌드 데이터에 쉽게 접근할 수 있게 해주는 라이브러리였습니다. 많은 개발자들이 애용하던 도구였죠.
💥 문제 발생
하지만 2025년 2월 이후로 pytrends가 작동하지 않는 상황이 발생했습니다. 조사 결과 다음과 같은 상황을 확인할 수 있었습니다:
• GitHub 이슈 트래커: 2025년 2월 이후로 동일한 404 오류가 지속적으로 발생
• Stack Overflow: 2025년 2월 말 이후로도 동일한 문제가 계속 보고됨
• 해결 현황: 현재까지 공식적인 해결책이나 패치가 나오지 않음
• 대안 권고: Glimpse, Exploding Topics, SerpApi 등 다른 솔루션으로의 전환 권장
결국 첫 번째 접근 방법은 완전히 막다른 길에 도달했습니다. 이때부터 직접 웹 스크래핑을 고려하기 시작했습니다.
⚠️두 번째 시도: BeautifulSoup의 한계
🔍 BeautifulSoup 접근법
pytrends가 실패한 후, BeautifulSoup 라이브러리를 사용하여 구글 트렌드 페이지를 직접 스크래핑하는 방법을 시도했습니다.
import requests
from bs4 import BeautifulSoup
# 구글 트렌드 페이지에 요청
url = "https://trends.google.com/trending?geo=KR&hours=4"
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# 트렌드 키워드를 찾으려 시도... 하지만 빈 결과
keywords = soup.find_all('div', class_='mZ3RIc')
print(keywords) # 결과: []
🤔 왜 실패했을까?
이 방법이 실패한 이유는 현대 웹의 동작 방식에 있었습니다:
현대의 많은 웹사이트는 단순한 HTML이 아닌, JavaScript를 통해 동적으로 콘텐츠를 생성합니다. 이런 사이트를 스크래핑하려면 실제 브라우저처럼 JavaScript를 실행할 수 있는 도구가 필요합니다.
✅최종 해결책: Selenium의 등장
🚀 Selenium이란?
Selenium은 웹 브라우저를 자동화하는 도구입니다. 단순한 HTML 요청기가 아니라 실제 웹 브라우저처럼 동작하여 JavaScript를 실행하고, 페이지가 완전히 로딩될 때까지 기다릴 수 있습니다.
• 실제 브라우저 환경에서 동작
• JavaScript 실행 가능
• 동적 콘텐츠 로딩 대기 가능
• 사용자 상호작용 시뮬레이션 가능
🔧 구현 과정
Selenium을 사용한 구현 과정은 다음과 같습니다:
🔍완성된 코드 상세 분석
📦 필요한 라이브러리
import time # 페이지 로딩 대기를 위한 시간 제어
from selenium import webdriver # 웹 브라우저 자동화
from selenium.webdriver.chrome.service import Service # Chrome 드라이버 서비스
from webdriver_manager.chrome import ChromeDriverManager # Chrome 드라이버 자동 관리
from bs4 import BeautifulSoup # HTML 파싱을 위한 라이브러리
import requests # 네이버 뉴스 API 호출용
import json # JSON 데이터 처리
🌐 네이버 뉴스 검색 함수
def search_naver_news(keyword, client_id, client_secret):
# API 키 유효성 검사
if not client_id or not client_secret or "YOUR_CLIENT_ID" in client_id:
return None
# 네이버 뉴스 검색 API 엔드포인트
search_url = "https://openapi.naver.com/v1/search/news.json"
# API 요청 헤더 (인증 정보 포함)
headers = {
"X-Naver-Client-Id": client_id,
"X-Naver-Client-Secret": client_secret
}
# 검색 매개변수 설정
params = {
"query": keyword, # 검색 키워드
"display": 5, # 결과 개수 (최대 5개)
"start": 1, # 시작 위치
"sort": "sim" # 정렬 방식 (sim: 관련도순)
}
try:
# API 요청 실행
response = requests.get(search_url, headers=headers, params=params)
return response.json()['items'] if response.status_code == 200 else None
except:
return None
🧹 HTML 태그 제거 함수
def remove_html_tags(text):
# 정규표현식을 사용하여 HTML 태그 제거
import re
return re.sub(re.compile('<.*?>'), '', text)
🎯 핵심 스크래핑 함수
def scrape_with_selenium():
"""
Selenium을 사용하여 JavaScript가 렌더링된 후의 페이지를 스크래핑합니다.
"""
url = "https://trends.google.com/trending?geo=KR&hours=4"
# Chrome 옵션 설정 (창을 띄우지 않고 백그라운드에서 실행)
options = webdriver.ChromeOptions()
options.add_argument('headless') # 브라우저 창 숨김
options.add_argument('window-size=1920x1080') # 윈도우 크기 설정
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36")
# 웹 드라이버 설정 및 실행
try:
print("🔍 Selenium으로 Chrome 브라우저를 실행합니다...")
# Chrome 드라이버 자동 설치 및 서비스 시작
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)
print(f" - URL 접속 시도: {url}")
driver.get(url) # 페이지 접속
# JavaScript가 데이터를 로드할 시간을 넉넉하게 줍니다
print(" - JavaScript 데이터 로딩 대기 중 (5초)...")
time.sleep(5) # 5초 대기
# 로딩이 완료된 페이지의 소스를 가져옵니다
html_source = driver.page_source
print("✅ 페이지 소스 가져오기 성공!")
# 브라우저 종료
driver.quit()
# BeautifulSoup으로 파싱
soup = BeautifulSoup(html_source, 'lxml')
# 트렌드 키워드가 포함된 테이블 찾기
table_body = soup.find('tbody', jsname='cC57zf')
if not table_body:
print("❌ 전체 테이블('tbody[jsname=cC57zf]')을 찾지 못했습니다.")
return None
# 테이블의 각 행(tr) 찾기
rows = table_body.find_all('tr')
if len(rows) == 0:
print("❌ 경고: 행(tr)이 0개입니다. 페이지 구조가 변경되었거나 로딩 시간이 더 필요할 수 있습니다.")
return None
# 각 행에서 키워드 추출
keywords = []
for row in rows:
# 키워드가 포함된 div 요소 찾기
keyword_div = row.find('div', class_='mZ3RIc')
if keyword_div:
keyword = keyword_div.get_text(strip=True)
keywords.append(keyword)
print(f"✅ Selenium 스크래핑 성공! ({len(keywords)}개 키워드 발견)")
return keywords
except Exception as e:
print(f"❌ Selenium 실행 중 오류 발생: {e}")
if 'driver' in locals() and driver:
driver.quit() # 오류 발생 시에도 브라우저 정리
return None
🎮 메인 실행 부분
if __name__ == "__main__":
# ----------------- 설정 -----------------
NAVER_CLIENT_ID = "YOUR_CLIENT_ID" # 네이버 개발자센터에서 발급받은 클라이언트 ID
NAVER_CLIENT_SECRET = "YOUR_CLIENT_SECRET" # 네이버 개발자센터에서 발급받은 클라이언트 시크릿
# ----------------------------------------
print("=" * 50)
print("🚀 실시간 검색어 기반 뉴스 검색 시스템을 시작합니다. (Selenium 사용)")
print("=" * 50)
# Selenium 스크래핑 함수 호출
trending_keywords = scrape_with_selenium()
# 스크래핑 실패 시 대체 키워드 사용
if not trending_keywords:
print(" -> 스크래핑 실패. 대체 키워드를 사용합니다.")
trending_keywords = ['오늘 날씨', '환율', '코스피']
# 검색 대상 키워드 출력
print("\n--- [ 검색 대상 키워드 ] ---")
for i, keyword in enumerate(trending_keywords):
print(f"{i+1}. {keyword}")
print("-" * 29 + "\n")
# 각 키워드에 대해 뉴스 검색 실행
for i, keyword in enumerate(trending_keywords):
print(f"▶ [{i+1}/{len(trending_keywords)}] '{keyword}' 관련 뉴스 검색...")
# 네이버 뉴스 API 호출
news_items = search_naver_news(keyword, NAVER_CLIENT_ID, NAVER_CLIENT_SECRET)
if news_items:
# 검색된 뉴스 항목들 출력
for j, item in enumerate(news_items):
title = remove_html_tags(item['title']) # HTML 태그 제거
link = item['link']
print(f" 📰 {j+1}. {title} ({link})")
else:
print(f" -> 관련 뉴스를 찾을 수 없거나 API 호출에 실패했습니다.")
print("-" * 50)
time.sleep(0.5) # API 호출 간격 조절
print("\n✅ 모든 작업이 완료되었습니다.")
💡 코드의 핵심 포인트
• 헤드리스 브라우저: 화면에 브라우저 창을 띄우지 않고 백그라운드에서 실행
• 동적 대기: JavaScript 실행을 위한 충분한 로딩 시간 확보
• 예외 처리: 각 단계별로 세밀한 오류 처리 및 대체 방안 제공
• 자원 관리: 브라우저 드라이버의 안전한 종료 보장
🤖AI 도구의 활용
이 프로젝트를 완성하는 과정에서 Gemini Pro와 Cursor AI를 적극 활용했습니다. 전문 개발자가 아님에도 불구하고 만족스러운 결과를 얻을 수 있었던 것은 이러한 AI 도구들의 도움이 컸습니다.
• 빠른 문제 해결: 각 단계에서 발생한 오류에 대한 즉각적인 해결책 제시
• 코드 최적화: 더 효율적이고 안정적인 코드 구조 제안
• 학습 효과: 코드의 동작 원리와 모범 사례를 함께 학습
• 시행착오 단축: 경험 부족으로 인한 불필요한 시행착오 최소화
🎯 AI와의 협업 프로세스
📊실행 결과 및 성과
🎉 최종 결과물
완성된 시스템은 다음과 같은 기능을 성공적으로 수행합니다:
• 구글 트렌드에서 실시간 인기 검색어 자동 수집
• 수집된 키워드별 네이버 뉴스 자동 검색
• HTML 태그 제거 및 깔끔한 결과 출력
• 오류 상황에 대한 안정적인 대체 방안 제공
📈 기술적 성취
• 웹 스크래핑 기술: 정적 스크래핑의 한계와 동적 스크래핑의 필요성 이해
• Selenium 활용법: 브라우저 자동화 도구의 실전 활용 경험
• API 통합: 여러 서비스의 API를 연동하는 방법 습득
• 문제 해결 능력: 여러 번의 시행착오를 통한 체계적 문제 해결 경험
• 구글 스프레드 시트와 github Action을 활용하여 실시간 검색어를 매 시간 자동화하는데 성공!

🔮결론 및 향후 계획
📝 프로젝트 회고
이번 프로젝트는 계획했던 것보다 훨씬 도전적인 과정이었습니다. pytrends API의 중단부터 BeautifulSoup의 한계, 그리고 최종적으로 Selenium을 통한 해결까지의 여정은 현대 웹 개발의 복잡성을 직접 체험할 수 있는 귀중한 경험이었습니다.
• 단순한 문제도 복잡할 수 있다: 겉보기에 간단해 보이는 작업도 실제로는 여러 기술적 제약이 존재
• 대안책의 중요성: 하나의 방법이 막혔을 때 다양한 접근법을 시도하는 유연성
• AI 도구의 가치: 전문성 부족을 AI 도구로 보완하여 원하는 결과 달성 가능
• 지속적인 학습: 기술 환경의 변화에 발맞춰 새로운 해결책을 모색하는 자세
🚀 향후 개발 계획
현재 시스템을 기반으로 다음과 같은 발전 방향을 계획하고 있습니다:
📚 추가 학습 계획
이 프로젝트를 통해 발견한 학습 포인트들을 바탕으로 다음 영역들을 더 깊이 공부할 예정입니다:
• 웹 크롤링 고급 기법: 더 효율적이고 안정적인 스크래핑 방법
• API 설계 및 개발: 수집한 데이터를 다른 서비스에서도 활용할 수 있도록 API 제공
• 클라우드 배포: AWS, GCP 등 클라우드 환경에서의 자동화 시스템 운영
• 모니터링 및 알림: 시스템 상태 모니터링 및 이상 상황 알림 기능
🎊마무리
같은 문제로 고민하고 계신 분들께 이 글이 도움이 되기를 바라며, 궁금한점 있으시면 언제든 댓글로 남겨주세요! 🚀
'콩's AI' 카테고리의 다른 글
🚀 Gemini CLI 출시! 개발자 필수템 등극? 사용법부터 장점까지 (0) | 2025.06.27 |
---|---|
대학생 필수 AI 도구 추천 10선 | 2025년 학업 효율 끝판왕 (4) | 2025.06.26 |
🎓 구글 제미나이(Gemini) 학생 계정으로 15개월 무료(40만원 혜택) 사용하기! (4) | 2025.06.16 |
🏗️ Cursor AI로 10분만에 만드는 GUI 프로그램 : 건축물대장 3편 (1) | 2025.06.16 |
🏗️ Cursor AI로 10분만에 만드는 GUI 프로그램 : 건축물대장 2편 (1) | 2025.06.16 |