일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 자동화
- 강화학습
- 생성형AI
- AI 기술
- 딥러닝
- LLM
- 인공지능
- tts
- LORA
- 실시간 렌더링
- 일론 머스크
- 오픈소스
- 메타
- 우분투
- 확산 모델
- 강화 학습
- 자연어 처리
- ai 챗봇
- PYTHON
- 멀티모달
- 3d 재구성
- OpenCV
- 오블완
- 휴머노이드 로봇
- ChatGPT
- 트랜스포머
- OpenAI
- 오픈AI
- 티스토리챌린지
- AI
- Today
- Total
AI 탐구노트
뉴스 타이틀 추출 및 워드 클라우드 생성기 만들기 본문
벚꽃이 지고 대신 본격적인 녹음이 몰려오는 시기가 되었습니다. 반팔 옷을 입고 밖을 나서도 그닥 이상하게 보이지 않을 정도로 날씨도 따뜻해졌구요. 덕분에 강가나 공원을 거니는 사람들도 많이 늘었습니다. 각자 다들 어떤 생각을 하며, 어떤 것에 관심을 두고 살고 있을까 하며 궁금해 하다가 문든 이런 생각이 떠올랐습니다.
"요즘 사람들은 어떤 뉴스에 주목하고 있을까?"
"언론은 어떤 주제, 어떤 소재로 우리의 관심을 끌려고 하고 있을까?"
국내에서는 대선 레이스가 막 시작되었죠. 각 언론사의 국내 기사들이 관련 기사들을 많이 싣고 있는 것 같습니다. 해외 뉴스는 미국 트럼프 대통령의 예상치 못한 행보들 때문에 하루가 멀다하고 정 반대되는 전망과 의견들이 쏟아지기도 하죠. 시간만 많다면 하나씩 들여다보며 기자들의 시각을 공부하는 좋은 경험이 될 수 있겠지만 실 생활은 그렇게 여유롭지 못하죠.
포털의 뉴스 페이지를 들여다보기
각 언론사의 뉴스들을 일일이 해당 언론사 홈페이지를 방문해서 볼 순 없습니다. 시간과 노력이 너무 많이 들기 때문이죠. 하지만 다행히도 각 언론사의 주요 뉴스들은 거의 대부분 포털의 뉴스 페이지에 올라옵니다. 이들 가운데 어떤 것은 메인을 장식하고 또 어떤 것은 아예 사람들의 눈에 띄지도 않지만 말입니다.
일단은 한군데서 살펴볼 수 있는 방법은 있는 셈이니 시작은 좋습니다. 그 뒤에 또 한 가지 좋은 점은... 검색 엔진 노출률을 높이기 위해 뉴스의 제목도 내용이 전하려는 키워드를 포함하고 있는 경우가 많다는 것입니다. 물론 사람들의 어그로를 끌기 위해 전혀 관련없는 혹은 관련이 아주아주 쪼~끔 있는 자극적인 제목을 사용하는 경우도 있긴 합니다. 하지만 그런지 않은 경우가 더 많죠.
그래서, 뉴스의 세부 내용 전체가 아니라 제목만 잘 분석해도 대략적인 흐름을 파악할 수 있을거란 생각이 들었습니다.
네이버 포털의 뉴스 페이지
네이버 포털의 뉴스 페이지는 특정 섹션 (카테고리)로 구분되어 있습니다. '정치', '경제', '사회', '생활/문화', '세계', 그리고 'IT/과학'이죠. 이 각각에는 카테고리 별 뉴스들이 잔뜩 들어 있죠. 이 정보들을 이제부터 추출해서 활용해 보겠습니다.
뉴스 페이지 카테고리 별 기사 타이틀 추출
전체 작업은 다음과 같은 과정을 거치게 됩니다.
1. 네이버 뉴스에서 기사 제목 수집하기
- 네이버 뉴스의 메인 페이지나 특정 섹션(예: 정치, 경제 등)에서 HTML 파싱을 통해 제목만 추출
- Python을 사용해서 requests, BeautifulSoup 라이브러리로 쉽게 접근 가능
2. 제목 데이터 전처리하기
- 불필요한 특수문자 제거
- 너무 짧은 단어 제거 (예: 조사, 접속사 등)
- 한글 형태소 분석을 통해 명사만 추출하기 (konlpy 라이브러리 추천)
- 불용어 처리
3. 워드 클라우드 생성하기
- 단어 빈도를 계산
- WordCloud 라이브러리를 이용해 이미지 생성
- 인기 단어를 한눈에 시각화
4. 웹 UI 화면 생성
- Gradio를 이용한 간단한 웹 앱 생성
프로그램 구현 세부 작업
1️⃣ 뉴스 제목, 작성 시간, 언론사 정보 추출하기
메인 뉴스나 특정 섹션(예를 들면 정치, 사회, 경제 같은 곳)에서 기사의 제목만 추출하는 작업이 필요합니다. 복잡할 것 같지만 다행히도, 뉴스 페이지의 HTML 구조를 살펴보면 제목들이 정리된 태그를 찾을 수 있습니다. 이걸 requests와 BeautifulSoup라는 파이썬 라이브러리를 써서 쉽게 가져올 수 있죠.
대략 다음과 같은 코드가 사용됩니다. 해당 뉴스 페이지의 소스에서 뉴스 기사 관련 태그를 찾아 추출하고, 작성 시간과 언론사 정보를 추출하는 작업이 포함됩니다.
def scrape_category_news(category_url, category_name):
res = requests.get(category_url, headers=headers)
soup = BeautifulSoup(res.text, "html.parser")
news_items = []
articles = soup.select("div.sa_text")
for article in articles:
try:
a_tag = article.select_one("a")
if not a_tag:
continue
title = a_tag.get_text(strip=True)
link = a_tag["href"]
press_tag = article.select_one(".sa_text_press")
time_tag = article.select_one(".sa_text_datetime")
press = press_tag.get_text(strip=True) if press_tag else "언론사 없음"
time_info = parse_relative_time(time_tag.get_text(strip=True)) if time_tag else today
news_items.append({
"title": title,
"link": link,
"press": press,
"date": time_info,
"category": category_name
})
except Exception as e:
print(f"에러 발생: {e}")
continue
return news_items
2️⃣ 추출된 정보로 워드 클라우드 만들기
제목을 추출하고 나서 이를 가지고 먼저 Okt를 이용해 한글 형태소 분석을 진행합니다. 이후 제목 가운데 명사만 추출하고 글자수가 너무 짧은 단어도 걸러내고 필터링을 위한 불용어를 적용하는 작업도 진행합니다. 워드 클라우드를 생성하는 코드는 대략 다음과 같습니다.
def generate_wordcloud(news_list, category="전체", top_n=100):
if not news_list:
return None
okt = Okt()
plt.rcParams['font.family'] = 'NanumGothic'
titles = " ".join([news['title'] for news in news_list])
nouns = okt.nouns(titles)
nouns = [n for n in nouns if len(n) > 1]
stopwords = {"뉴스", "보도", "기사", "속보", "오늘", "내일"}
nouns = [n for n in nouns if n not in stopwords]
counter = Counter(nouns)
most_common_words = dict(counter.most_common(top_n))
wordcloud = WordCloud(
font_path="/usr/share/fonts/truetype/nanum/NanumGothic.ttf",
width=800,
height=400,
background_color="white",
colormap="tab10"
).generate_from_frequencies(most_common_words)
save_dir = "wordclouds"
os.makedirs(save_dir, exist_ok=True)
safe_category = category.replace("/", "-")
filename = f"{save_dir}/wordcloud_{safe_category}_{datetime.now().strftime('%Y%m%d%H%M%S')}.png"
wordcloud.to_file(filename)
return filename
3️⃣ Web UI로 구현하기
Web UI는 가장 익숙한 Gradio를 이용합니다. 크게는 카테고리를 선택하도록 하고, 작업은 기사 제목을 추출하는 것과 워드 클라우드 생성하는 것 가운데 선택적으로 할 수 있도록 했습니다. 약간 뒤죽박죽 섞인 것 같긴 하지만, 사용하려는 목적에는 딱 부합합니다. Gradio UI 관련 코드는 대략 다음과 같습니다.
with gr.Blocks() as demo:
gr.Markdown("# 📰 뉴스 워드클라우드 생성기")
with gr.Row():
category_dropdown = gr.Dropdown(
choices=["All", "정치", "경제", "사회", "생활/문화", "세계", "IT/과학"],
label="카테고리 선택",
value="All"
)
action_buttons = gr.Radio(
choices=["기사 제목 추출", "워드 클라우드 생성"],
label="실행할 작업 선택"
)
with gr.Row():
top_n_slider = gr.Slider(10, 200, value=100, step=10, label="워드클라우드 단어 수(Top N)")
search_checkbox = gr.Checkbox(label="기사 검색 기능 활성화", value=True)
run_button = gr.Button("실행")
table_output = gr.HTML(label="기사 목록", visible=False)
image_output = gr.Image(label="워드클라우드 결과", visible=False)
with gr.Row(visible=True) as search_area:
search_box = gr.Textbox(label="검색어 입력")
search_button = gr.Button("검색")
search_result = gr.HTML(label="검색 결과")
run_button.click(
fn=process,
inputs=[category_dropdown, action_buttons, top_n_slider, search_checkbox],
outputs=[table_output, image_output, search_area]
)
search_button.click(
fn=search_news,
inputs=[search_box],
outputs=[search_result]
)
demo.launch()
구현 프로그램 결과물 확인
위 과정을 거쳐 만들어진 코드입니다. 몇 차례 시행착오를 거치면서 기능도 일부는 추가되었습니다.
1️⃣ 기사 제목 추출
카테고리는 All과 각 세부 카테고리를 선택할 수 있도록 했습니다. 추출된 제목들 기준으로 검색 기능을 추가했고 기사 작성 언론사와 작성일자, 그리고 실제 뉴스의 링크를 제목에 걸었습니다.
2️⃣ 워드 클라우드
워드 클라우드는 사용하게 될 단어의 수를 지정해 단순하게 혹은 복잡하게 보일 수 있도록 해 봤습니다. 워드 클라우드에 적용할 마스크 기능도 구현은 되어 있는데 파일을 지정하지 않으면 기본은 아래와 같이 직사각형으로 나오도록 해 두었습니다. 원래 목적 자체가 예쁘게 보이는게 아니라 전반적인 흐름을 파악하기 위한 것이니 이 정도면 되지 않나 싶습니다.
아래 내용을 보면 경제 분야에서는 트럼프로 인한 관세 전쟁 및 국가 별 협상, 패권 전쟁, 환율 등이 가장 큰 이슈가 되고 있는 모습이고 중간중간 부동산 관련 내용들이 보입니다.
아래는 '사회' 카테고리를 했을 때 나온 내용입니다. 가장 많이 보도되고 있는 내용은 '난동', '흉기' 같은 부정적인 내용이 주를 이루고 있습니다. 사람 사는 세상이 다 이렇진 않을텐데 미담 기사들은 다 어디로 가고 유독 이런 것들이 더 많이 눈에 띌까 싶었습니다. 언론사에서 상시 모니터링을 하고 있는 쪽이 경찰, 검찰 쪽의 강력계 쪽이라 그럴까요? 아니면 기사를 읽는 사람들이 자극적인 폭력/사건/사고 관련 기사에 더 많이 끌리기 때문일까요? 어쩌면 서로 상승 작용을 하고 있는 것일지도 모르겠습니다.
워드 클라우드는 세상을 들여다보는 만능 안경은 아닙니다. 모든 이슈를 다 알 수 있는 것도 아니구요. 게다가 이번에 한 것은 뉴스의 세부 내용과는 무관하게 제목만 가지고 해 본 것입니다. 하지만, 이렇게 작고 손쉬운 시도에서조차 어떤 키워드가 부각되고 있고, 얼론의 시선이 어느 쪽을 향하고 있는지 자볍게 훑어볼 수 있는 기회가 된다는 것은 한편으론 흥미롭게 느껴졌습니다.
'DIY 테스트' 카테고리의 다른 글
자신만의 폰트 제작 - 2) MX-Font를 이용해 자신만의 손글씨 만들기 (0) | 2025.05.13 |
---|---|
영상 기반 강물의 표면 유속 측정 (0) | 2025.05.04 |
감성과 기능을 더한 틀린 그림 찾기 게임, 바이브 코딩으로 구현하다 (2) | 2025.04.25 |
로컬 LLM과 LM Studio API 기능을 이용한 간단한 어플리케이션 (0) | 2025.04.17 |
DeepSite로 만든 사다리타기 게임, 저도 Vibe Coding 한번 해봤습니다 (1) | 2025.04.15 |