본문 바로가기

콩's AI

실시간 검색어 + 뉴스 검색 시스템 구현하기 (feat. 실패, 또 실패, 성공..)

반응형

 

 

 

🔍 실시간 검색어를 통해 뉴스 검색 시스템을 어떻게 구현할까?

실패와 실패를 거듭한 최종 결과물

🎯프로젝트 개요

실시간으로 화제가 되고 있는 키워드를 자동으로 수집하고, 해당 키워드와 관련된 최신 뉴스를 검색하는 시스템을 구현하고자 했습니다. 언뜻 간단해 보이는 이 프로젝트는 실제로는 여러 번의 실패와 시행착오를 거쳐야 했던 도전적인 과제였습니다.

🎯 프로젝트 목표
• 구글 트렌드에서 실시간 인기 검색어 수집
• 네이버 뉴스 API를 통한 관련 기사 검색
• 자동화된 뉴스 큐레이션 시스템 구축

첫 번째 시도: pytrends API의 좌절

🔧 pytrends란?

pytrends는 구글 트렌드의 비공식 Python API로, 구글 트렌드 데이터에 쉽게 접근할 수 있게 해주는 라이브러리였습니다. 많은 개발자들이 애용하던 도구였죠.

1 초기 계획: pytrends를 사용하여 실시간 트렌드 키워드를 간단하게 가져오기

💥 문제 발생

하지만 2025년 2월 이후로 pytrends가 작동하지 않는 상황이 발생했습니다. 조사 결과 다음과 같은 상황을 확인할 수 있었습니다:

🚨 pytrends 현재 상황
GitHub 이슈 트래커: 2025년 2월 이후로 동일한 404 오류가 지속적으로 발생
Stack Overflow: 2025년 2월 말 이후로도 동일한 문제가 계속 보고됨
해결 현황: 현재까지 공식적인 해결책이나 패치가 나오지 않음
대안 권고: Glimpse, Exploding Topics, SerpApi 등 다른 솔루션으로의 전환 권장

결국 첫 번째 접근 방법은 완전히 막다른 길에 도달했습니다. 이때부터 직접 웹 스크래핑을 고려하기 시작했습니다.

⚠️두 번째 시도: BeautifulSoup의 한계

🔍 BeautifulSoup 접근법

pytrends가 실패한 후, BeautifulSoup 라이브러리를 사용하여 구글 트렌드 페이지를 직접 스크래핑하는 방법을 시도했습니다.

🐍 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) # 결과: []

🤔 왜 실패했을까?

이 방법이 실패한 이유는 현대 웹의 동작 방식에 있었습니다:

1 정적 HTML만 수신: requests 라이브러리는 서버가 처음 보내주는 날것의 HTML(뼈대)만 가져옵니다.
2 JavaScript 미실행: 실제 검색어 목록은 페이지가 로딩된 후, 브라우저의 JavaScript가 구글 서버와 추가로 통신하여 동적으로 채워넣는 방식이었습니다.
3 동적 콘텐츠 부재: 따라서 BeautifulSoup으로 파싱한 HTML에는 우리가 원하는 트렌드 키워드가 존재하지 않았습니다.
💡 깨달음
현대의 많은 웹사이트는 단순한 HTML이 아닌, JavaScript를 통해 동적으로 콘텐츠를 생성합니다. 이런 사이트를 스크래핑하려면 실제 브라우저처럼 JavaScript를 실행할 수 있는 도구가 필요합니다.

최종 해결책: Selenium의 등장

🚀 Selenium이란?

Selenium은 웹 브라우저를 자동화하는 도구입니다. 단순한 HTML 요청기가 아니라 실제 웹 브라우저처럼 동작하여 JavaScript를 실행하고, 페이지가 완전히 로딩될 때까지 기다릴 수 있습니다.

🎉 Selenium의 장점
• 실제 브라우저 환경에서 동작
• JavaScript 실행 가능
• 동적 콘텐츠 로딩 대기 가능
• 사용자 상호작용 시뮬레이션 가능

🔧 구현 과정

Selenium을 사용한 구현 과정은 다음과 같습니다:

1 Chrome 브라우저 설정: 헤드리스 모드로 백그라운드에서 실행
2 페이지 접속: 구글 트렌드 페이지에 접속
3 로딩 대기: JavaScript가 데이터를 불러올 시간 확보
4 데이터 추출: 완전히 렌더링된 페이지에서 트렌드 키워드 추출

🔍완성된 코드 상세 분석

📦 필요한 라이브러리

🔧 라이브러리 임포트
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 데이터 처리

🌐 네이버 뉴스 검색 함수

📰 네이버 뉴스 API 함수
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)

🎯 핵심 스크래핑 함수

🚀 Selenium 스크래핑 함수
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 ProCursor AI를 적극 활용했습니다. 전문 개발자가 아님에도 불구하고 만족스러운 결과를 얻을 수 있었던 것은 이러한 AI 도구들의 도움이 컸습니다.

🚀 AI 도구 활용의 장점
빠른 문제 해결: 각 단계에서 발생한 오류에 대한 즉각적인 해결책 제시
코드 최적화: 더 효율적이고 안정적인 코드 구조 제안
학습 효과: 코드의 동작 원리와 모범 사례를 함께 학습
시행착오 단축: 경험 부족으로 인한 불필요한 시행착오 최소화

🎯 AI와의 협업 프로세스

1 문제 정의: 현재 상황과 원하는 목표를 명확하게 AI에게 설명
2 해결책 모색: AI가 제시한 여러 방법 중 상황에 맞는 최적안 선택
3 단계별 구현: 복잡한 기능을 작은 단위로 나누어 차근차근 구현
4 디버깅과 최적화: 발생한 오류를 AI와 함께 분석하고 개선점 도출

📊실행 결과 및 성과

🎉 최종 결과물

완성된 시스템은 다음과 같은 기능을 성공적으로 수행합니다:

✅ 구현된 기능
• 구글 트렌드에서 실시간 인기 검색어 자동 수집
• 수집된 키워드별 네이버 뉴스 자동 검색
• HTML 태그 제거 및 깔끔한 결과 출력
• 오류 상황에 대한 안정적인 대체 방안 제공

📈 기술적 성취

🏆 프로젝트를 통해 얻은 것
웹 스크래핑 기술: 정적 스크래핑의 한계와 동적 스크래핑의 필요성 이해
Selenium 활용법: 브라우저 자동화 도구의 실전 활용 경험
API 통합: 여러 서비스의 API를 연동하는 방법 습득
문제 해결 능력: 여러 번의 시행착오를 통한 체계적 문제 해결 경험
🏆실제 결과!
• 구글 스프레드 시트와 github Action을 활용하여 실시간 검색어를 매 시간 자동화하는데 성공!

🔮결론 및 향후 계획

📝 프로젝트 회고

이번 프로젝트는 계획했던 것보다 훨씬 도전적인 과정이었습니다. pytrends API의 중단부터 BeautifulSoup의 한계, 그리고 최종적으로 Selenium을 통한 해결까지의 여정은 현대 웹 개발의 복잡성을 직접 체험할 수 있는 귀중한 경험이었습니다.

💡 핵심 교훈
단순한 문제도 복잡할 수 있다: 겉보기에 간단해 보이는 작업도 실제로는 여러 기술적 제약이 존재
대안책의 중요성: 하나의 방법이 막혔을 때 다양한 접근법을 시도하는 유연성
AI 도구의 가치: 전문성 부족을 AI 도구로 보완하여 원하는 결과 달성 가능
지속적인 학습: 기술 환경의 변화에 발맞춰 새로운 해결책을 모색하는 자세

🚀 향후 개발 계획

현재 시스템을 기반으로 다음과 같은 발전 방향을 계획하고 있습니다:

1 자동화 시스템 구축: 정기적으로 실행되어 블로그에 자동으로 포스팅하는 스케줄러 개발
2 데이터 저장 및 분석: 수집된 데이터를 데이터베이스에 저장하고 트렌드 분석 기능 추가
3 다양한 소스 통합: 구글 트렌드 외에 다른 플랫폼의 실시간 데이터도 수집
4 사용자 인터페이스 개발: 웹 기반의 사용자 친화적인 대시보드 구축

📚 추가 학습 계획

이 프로젝트를 통해 발견한 학습 포인트들을 바탕으로 다음 영역들을 더 깊이 공부할 예정입니다:

🎯 학습 목표
웹 크롤링 고급 기법: 더 효율적이고 안정적인 스크래핑 방법
API 설계 및 개발: 수집한 데이터를 다른 서비스에서도 활용할 수 있도록 API 제공
클라우드 배포: AWS, GCP 등 클라우드 환경에서의 자동화 시스템 운영
모니터링 및 알림: 시스템 상태 모니터링 및 이상 상황 알림 기능

🎊마무리

같은 문제로 고민하고 계신 분들께 이 글이 도움이 되기를 바라며, 궁금한점 있으시면 언제든 댓글로 남겨주세요! 🚀

 

반응형

⚠️ 광고 차단 프로그램 감지

애드블록, 유니콘 등 광고 차단 확장 프로그램을 해제하거나
화이트리스트에 추가해주세요.