본문 바로가기
Python

Django로 뉴스 분석 웹앱 만들기 (입력 → 분석 → 결과 출력)

by ramzee 2025. 4. 13.

0. 이 글은 누구를 위한 글인가요?

  • VS Code에서 Django 설치, 서버 실행까지는 해봤어요.
  • 이제 사용자가 키워드를 입력하고, 결과를 웹에서 보여주는 기능을 만들고 싶어요.
  • views, urls, templates의 구조와 연결 흐름이 궁금해요!

1. 실습 목표

단계기능
1사용자 키워드 입력 폼 만들기
2입력된 키워드를 views.py에서 처리
3뉴스 수집 + 감성 분석 + 요약 적용
4결과를 웹페이지에 출력

2. Django 앱 생성 및 설정

2-1. analyzer 앱 생성
python manage.py startapp analyzer
2-2. settings.py 설정

# config/settings.py
INSTALLED_APPS = [
    ...
    'analyzer',
]
2-3. 기본 폴더 구조

my_django_project/
├── config/
├── analyzer/
│   ├── views.py
│   ├── urls.py  ← 직접 생성
│   └── templates/analyzer/
│        ├── form.html
│        └── result.html

3. URL 설정

3-1. analyzer/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('result/', views.result, name='result'),
]
3-2. config/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('analyzer.urls')),
]

4. HTML 템플릿

4-1. form.html

<!DOCTYPE html>
<html>
<head><title>뉴스 분석기</title></head>
<body>
  <h1>뉴스 키워드 분석</h1>
  <form method="POST" action="{% url 'result' %}">
    {% csrf_token %}
    <label for="keyword">검색할 키워드를 입력하세요:</label>
    <input type="text" id="keyword" name="keyword" required>
    <button type="submit">분석 시작</button>
  </form>
</body>
</html>
4-2. result.html

<!DOCTYPE html>
<html>
<head><title>분석 결과</title></head>
<body>
  <h1>뉴스 분석 결과</h1>
  <p><strong>입력 키워드:</strong> {{ keyword }}</p>
  <table border="1">
    <tr>
      <th>제목</th>
      <th>감성</th>
      <th>요약</th>
    </tr>
    {% for row in results %}
    <tr>
      <td>{{ row.title }}</td>
      <td>{{ row.sentiment }}</td>
      <td>{{ row.summary }}</td>
    </tr>
    {% endfor %}
  </table>
</body>
</html>

5. views.py 작성 (analyzer/views.py)


from django.shortcuts import render
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from transformers import BartTokenizer, BartForConditionalGeneration
import torch
import torch.nn.functional as F
import requests
from bs4 import BeautifulSoup

# 모델 로딩
sa_tokenizer = AutoTokenizer.from_pretrained("beomi/KcELECTRA-base")
sa_model = AutoModelForSequenceClassification.from_pretrained("beomi/KcELECTRA-base")
sum_tokenizer = BartTokenizer.from_pretrained("digit82/kobart-summarization")
sum_model = BartForConditionalGeneration.from_pretrained("digit82/kobart-summarization")

def collect_titles(keyword, pages=1):
    headers = {'User-Agent': 'Mozilla/5.0'}
    titles = []
    for page in range(1, pages + 1):
        start = (page - 1) * 10 + 1
        url = f"https://search.naver.com/search.naver?where=news&query={keyword}&start={start}"
        res = requests.get(url, headers=headers)
        soup = BeautifulSoup(res.text, 'html.parser')
        for a in soup.select("a.news_tit"):
            titles.append(a.get_text())
    return titles[:10]

def get_sentiment(text):
    inputs = sa_tokenizer(text, return_tensors="pt", truncation=True)
    with torch.no_grad():
        logits = sa_model(**inputs).logits
    pred = torch.argmax(F.softmax(logits, dim=1)).item()
    return ['부정', '중립', '긍정'][pred]

def summarize(text, max_len=40):
    input_ids = sum_tokenizer.encode(text, return_tensors='pt', truncation=True)
    output_ids = sum_model.generate(input_ids, max_length=max_len, num_beams=4, early_stopping=True)
    return sum_tokenizer.decode(output_ids[0], skip_special_tokens=True)

def index(request):
    return render(request, 'analyzer/form.html')

def result(request):
    if request.method == 'POST':
        keyword = request.POST['keyword']
        titles = collect_titles(keyword)
        results = []
        for t in titles:
            sentiment = get_sentiment(t)
            summary = summarize(t)
            results.append({'title': t, 'sentiment': sentiment, 'summary': summary})
        return render(request, 'analyzer/result.html', {'keyword': keyword, 'results': results})

6. 실행 및 출력 예시


python manage.py runserver
- 브라우저에서 접속: http://127.0.0.1:8000
입력 예시

입력 키워드: 인공지능

출력 예시
제목감성요약
AI가 바꾸는 미래 일자리긍정AI가 일자리를 변화시킨다
AI 범죄 경고부정AI 관련 위험성 제기