Capítulo 12: Proyecto: Agregador de Noticias
12.4 Construcción de la Interfaz de Usuario
En esta sección, nos centraremos en la construcción de la interfaz de usuario (UI) para el chatbot agregador de noticias. La UI es crucial ya que permite a los usuarios interactuar con el chatbot y acceder a los artículos de noticias. Crearemos una interfaz web utilizando Flask, un marco web ligero para Python. Esta interfaz permitirá a los usuarios solicitar actualizaciones de noticias, ver resúmenes y explorar artículos de noticias categorizados.
12.4.1 Configuración de Flask
Primero, necesitamos instalar Flask si aún no lo hemos hecho:
pip install Flask
A continuación, configuremos la estructura básica de nuestra aplicación Flask.
from flask import Flask, request, jsonify, render_template
from nlp_engine import preprocess_text, categorize_article
from summarizer import summarize_text, abstractive_summarize_text
from news_fetcher import fetch_news
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/get_news', methods=['POST'])
def get_news():
category = request.form.get('category')
articles = fetch_news(category)
return jsonify(articles)
@app.route('/summarize', methods=['POST'])
def summarize():
article = request.form.get('article')
summary_type = request.form.get('summary_type')
if summary_type == 'extractive':
summary = summarize_text(article)
else:
summary = abstractive_summarize_text(article)
return jsonify({'summary': summary})
if __name__ == '__main__':
app.run(debug=True)
En este script, definimos las rutas básicas para nuestra aplicación Flask:
- La ruta
home
renderiza la página de inicio. - La ruta
get_news
obtiene artículos de noticias basados en la categoría seleccionada. - La ruta
summarize
resume un artículo dado utilizando ya sea el resumen extractivo o el abstractivo.
12.4.2 Creación de Plantillas HTML
A continuación, crearemos plantillas HTML para renderizar las páginas web. Usaremos Bootstrap para el diseño y así crear una interfaz visualmente atractiva y receptiva.
templates/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<a href="${article.url}" target="_blank" class="list-group-item list-group-item-action">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
</a>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
</script>
</body>
</html>
En esta plantilla HTML, creamos un formulario simple para seleccionar la categoría de noticias y un div para mostrar los artículos de noticias obtenidos. Usamos jQuery para manejar el envío del formulario y actualizar dinámicamente la página con los artículos de noticias obtenidos.
12.4.3 Integración de Resumen y Categorización
Para permitir a los usuarios ver resúmenes y categorizar artículos, necesitamos agregar funcionalidad adicional tanto en el frontend como en el backend.
app.py (continuación):
@app.route('/categorize', methods=['POST'])
def categorize():
article = request.form.get('article')
category = categorize_article(article)
return jsonify({'category': category})
@app.route('/summarize_article', methods=['POST'])
def summarize_article():
article = request.form.get('article')
summary_type = request.form.get('summary_type')
if summary_type == 'extractive':
summary = summarize_text(article)
else:
summary = abstractive_summarize_text(article)
return jsonify({'summary': summary})
# Updated HTML template to include summarization and categorization
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<div class="list-group-item">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
<button class="btn btn-secondary btn-sm mt-2" onclick="summarizeArticle('${article.content}')">Summarize</button>
<div class="summary mt-2" id="summary-${article.title}"></div>
</div>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
function summarizeArticle(article) {
const summaryType = 'extractive'; // or 'abstractive'
$.post('/summarize_article', { article: article, summary_type: summaryType }, function(data) {
$('#summary-' + article.title).html('<p>' + data.summary + '</p>');
});
}
</script>
</body>
</html>
En esta plantilla actualizada, añadimos botones para resumir cada artículo. La función summarizeArticle
envía una solicitud al endpoint /summarize_article
y muestra el resumen dentro de la página.
12.4.4 Categorización de Artículos
Integraremos la funcionalidad de categorización para categorizar automáticamente los artículos de noticias en diferentes temas.
nlp_engine.py (continuación):
# Define function to categorize article
def categorize_article(article):
bow = dictionary.doc2bow(nltk.word_tokenize(article.lower()))
topics = lda_model.get_document_topics(bow)
sorted_topics = sorted(topics, key=lambda x: x[1], reverse=True)
topic_index = sorted_topics[0][0]
topic_terms = lda_model.show_topic(topic_index, topn=4)
topic_keywords = [term[0] for term in topic_terms]
return topic_keywords
Esta función utiliza el modelo LDA entrenado para categorizar el artículo en temas basados en las palabras clave más relevantes.
Aplicación Flask Actualizada:
@app.route('/categorize_article', methods=['POST'])
def categorize_article_route():
article = request.form.get('article')
category = categorize_article(article)
return jsonify({'category': category})
# HTML template for categorizing articles
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<div class="list-group-item">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
<button class="btn btn-secondary btn-sm mt-2" onclick="categorizeArticle('${article.content}')">Categorize</button>
<div class="category mt-2" id="category-${article.title}"></div>
<button class="btn btn-secondary btn-sm mt-2" onclick="summarizeArticle('${article.content}')">Summarize</button>
<div class="summary mt-2" id="summary-${article.title}"></div>
</div>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
function summarizeArticle(article) {
const summaryType = 'extractive'; // or 'abstractive'
$.post('/summarize_article', { article: article, summary_type: summaryType }, function(data) {
$('#summary-' + article.title).html('<p>' + data.summary + '</p>');
});
}
function categorizeArticle(article) {
$.post('/categorize_article', { article: article }, function(data) {
$('#category-' + article.title).html('<p>' + data.category.join(', ') + '</p>');
});
}
</script>
</body>
</html>
En esta plantilla actualizada, añadimos botones para categorizar cada artículo. La función categorizeArticle
envía una solicitud al endpoint /categorize_article
y muestra la categoría dentro de la página.
En esta sección, construimos la interfaz de usuario para el chatbot agregador de noticias. Utilizamos Flask para crear una interfaz web, permitiendo a los usuarios solicitar actualizaciones de noticias, ver resúmenes y categorizar artículos de noticias.
Creamos plantillas HTML con Bootstrap para un diseño receptivo y visualmente atractivo. El frontend interactúa con el backend para obtener artículos de noticias, resumirlos y categorizarlos en diferentes temas.
12.4 Construcción de la Interfaz de Usuario
En esta sección, nos centraremos en la construcción de la interfaz de usuario (UI) para el chatbot agregador de noticias. La UI es crucial ya que permite a los usuarios interactuar con el chatbot y acceder a los artículos de noticias. Crearemos una interfaz web utilizando Flask, un marco web ligero para Python. Esta interfaz permitirá a los usuarios solicitar actualizaciones de noticias, ver resúmenes y explorar artículos de noticias categorizados.
12.4.1 Configuración de Flask
Primero, necesitamos instalar Flask si aún no lo hemos hecho:
pip install Flask
A continuación, configuremos la estructura básica de nuestra aplicación Flask.
from flask import Flask, request, jsonify, render_template
from nlp_engine import preprocess_text, categorize_article
from summarizer import summarize_text, abstractive_summarize_text
from news_fetcher import fetch_news
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/get_news', methods=['POST'])
def get_news():
category = request.form.get('category')
articles = fetch_news(category)
return jsonify(articles)
@app.route('/summarize', methods=['POST'])
def summarize():
article = request.form.get('article')
summary_type = request.form.get('summary_type')
if summary_type == 'extractive':
summary = summarize_text(article)
else:
summary = abstractive_summarize_text(article)
return jsonify({'summary': summary})
if __name__ == '__main__':
app.run(debug=True)
En este script, definimos las rutas básicas para nuestra aplicación Flask:
- La ruta
home
renderiza la página de inicio. - La ruta
get_news
obtiene artículos de noticias basados en la categoría seleccionada. - La ruta
summarize
resume un artículo dado utilizando ya sea el resumen extractivo o el abstractivo.
12.4.2 Creación de Plantillas HTML
A continuación, crearemos plantillas HTML para renderizar las páginas web. Usaremos Bootstrap para el diseño y así crear una interfaz visualmente atractiva y receptiva.
templates/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<a href="${article.url}" target="_blank" class="list-group-item list-group-item-action">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
</a>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
</script>
</body>
</html>
En esta plantilla HTML, creamos un formulario simple para seleccionar la categoría de noticias y un div para mostrar los artículos de noticias obtenidos. Usamos jQuery para manejar el envío del formulario y actualizar dinámicamente la página con los artículos de noticias obtenidos.
12.4.3 Integración de Resumen y Categorización
Para permitir a los usuarios ver resúmenes y categorizar artículos, necesitamos agregar funcionalidad adicional tanto en el frontend como en el backend.
app.py (continuación):
@app.route('/categorize', methods=['POST'])
def categorize():
article = request.form.get('article')
category = categorize_article(article)
return jsonify({'category': category})
@app.route('/summarize_article', methods=['POST'])
def summarize_article():
article = request.form.get('article')
summary_type = request.form.get('summary_type')
if summary_type == 'extractive':
summary = summarize_text(article)
else:
summary = abstractive_summarize_text(article)
return jsonify({'summary': summary})
# Updated HTML template to include summarization and categorization
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<div class="list-group-item">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
<button class="btn btn-secondary btn-sm mt-2" onclick="summarizeArticle('${article.content}')">Summarize</button>
<div class="summary mt-2" id="summary-${article.title}"></div>
</div>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
function summarizeArticle(article) {
const summaryType = 'extractive'; // or 'abstractive'
$.post('/summarize_article', { article: article, summary_type: summaryType }, function(data) {
$('#summary-' + article.title).html('<p>' + data.summary + '</p>');
});
}
</script>
</body>
</html>
En esta plantilla actualizada, añadimos botones para resumir cada artículo. La función summarizeArticle
envía una solicitud al endpoint /summarize_article
y muestra el resumen dentro de la página.
12.4.4 Categorización de Artículos
Integraremos la funcionalidad de categorización para categorizar automáticamente los artículos de noticias en diferentes temas.
nlp_engine.py (continuación):
# Define function to categorize article
def categorize_article(article):
bow = dictionary.doc2bow(nltk.word_tokenize(article.lower()))
topics = lda_model.get_document_topics(bow)
sorted_topics = sorted(topics, key=lambda x: x[1], reverse=True)
topic_index = sorted_topics[0][0]
topic_terms = lda_model.show_topic(topic_index, topn=4)
topic_keywords = [term[0] for term in topic_terms]
return topic_keywords
Esta función utiliza el modelo LDA entrenado para categorizar el artículo en temas basados en las palabras clave más relevantes.
Aplicación Flask Actualizada:
@app.route('/categorize_article', methods=['POST'])
def categorize_article_route():
article = request.form.get('article')
category = categorize_article(article)
return jsonify({'category': category})
# HTML template for categorizing articles
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<div class="list-group-item">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
<button class="btn btn-secondary btn-sm mt-2" onclick="categorizeArticle('${article.content}')">Categorize</button>
<div class="category mt-2" id="category-${article.title}"></div>
<button class="btn btn-secondary btn-sm mt-2" onclick="summarizeArticle('${article.content}')">Summarize</button>
<div class="summary mt-2" id="summary-${article.title}"></div>
</div>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
function summarizeArticle(article) {
const summaryType = 'extractive'; // or 'abstractive'
$.post('/summarize_article', { article: article, summary_type: summaryType }, function(data) {
$('#summary-' + article.title).html('<p>' + data.summary + '</p>');
});
}
function categorizeArticle(article) {
$.post('/categorize_article', { article: article }, function(data) {
$('#category-' + article.title).html('<p>' + data.category.join(', ') + '</p>');
});
}
</script>
</body>
</html>
En esta plantilla actualizada, añadimos botones para categorizar cada artículo. La función categorizeArticle
envía una solicitud al endpoint /categorize_article
y muestra la categoría dentro de la página.
En esta sección, construimos la interfaz de usuario para el chatbot agregador de noticias. Utilizamos Flask para crear una interfaz web, permitiendo a los usuarios solicitar actualizaciones de noticias, ver resúmenes y categorizar artículos de noticias.
Creamos plantillas HTML con Bootstrap para un diseño receptivo y visualmente atractivo. El frontend interactúa con el backend para obtener artículos de noticias, resumirlos y categorizarlos en diferentes temas.
12.4 Construcción de la Interfaz de Usuario
En esta sección, nos centraremos en la construcción de la interfaz de usuario (UI) para el chatbot agregador de noticias. La UI es crucial ya que permite a los usuarios interactuar con el chatbot y acceder a los artículos de noticias. Crearemos una interfaz web utilizando Flask, un marco web ligero para Python. Esta interfaz permitirá a los usuarios solicitar actualizaciones de noticias, ver resúmenes y explorar artículos de noticias categorizados.
12.4.1 Configuración de Flask
Primero, necesitamos instalar Flask si aún no lo hemos hecho:
pip install Flask
A continuación, configuremos la estructura básica de nuestra aplicación Flask.
from flask import Flask, request, jsonify, render_template
from nlp_engine import preprocess_text, categorize_article
from summarizer import summarize_text, abstractive_summarize_text
from news_fetcher import fetch_news
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/get_news', methods=['POST'])
def get_news():
category = request.form.get('category')
articles = fetch_news(category)
return jsonify(articles)
@app.route('/summarize', methods=['POST'])
def summarize():
article = request.form.get('article')
summary_type = request.form.get('summary_type')
if summary_type == 'extractive':
summary = summarize_text(article)
else:
summary = abstractive_summarize_text(article)
return jsonify({'summary': summary})
if __name__ == '__main__':
app.run(debug=True)
En este script, definimos las rutas básicas para nuestra aplicación Flask:
- La ruta
home
renderiza la página de inicio. - La ruta
get_news
obtiene artículos de noticias basados en la categoría seleccionada. - La ruta
summarize
resume un artículo dado utilizando ya sea el resumen extractivo o el abstractivo.
12.4.2 Creación de Plantillas HTML
A continuación, crearemos plantillas HTML para renderizar las páginas web. Usaremos Bootstrap para el diseño y así crear una interfaz visualmente atractiva y receptiva.
templates/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<a href="${article.url}" target="_blank" class="list-group-item list-group-item-action">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
</a>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
</script>
</body>
</html>
En esta plantilla HTML, creamos un formulario simple para seleccionar la categoría de noticias y un div para mostrar los artículos de noticias obtenidos. Usamos jQuery para manejar el envío del formulario y actualizar dinámicamente la página con los artículos de noticias obtenidos.
12.4.3 Integración de Resumen y Categorización
Para permitir a los usuarios ver resúmenes y categorizar artículos, necesitamos agregar funcionalidad adicional tanto en el frontend como en el backend.
app.py (continuación):
@app.route('/categorize', methods=['POST'])
def categorize():
article = request.form.get('article')
category = categorize_article(article)
return jsonify({'category': category})
@app.route('/summarize_article', methods=['POST'])
def summarize_article():
article = request.form.get('article')
summary_type = request.form.get('summary_type')
if summary_type == 'extractive':
summary = summarize_text(article)
else:
summary = abstractive_summarize_text(article)
return jsonify({'summary': summary})
# Updated HTML template to include summarization and categorization
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<div class="list-group-item">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
<button class="btn btn-secondary btn-sm mt-2" onclick="summarizeArticle('${article.content}')">Summarize</button>
<div class="summary mt-2" id="summary-${article.title}"></div>
</div>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
function summarizeArticle(article) {
const summaryType = 'extractive'; // or 'abstractive'
$.post('/summarize_article', { article: article, summary_type: summaryType }, function(data) {
$('#summary-' + article.title).html('<p>' + data.summary + '</p>');
});
}
</script>
</body>
</html>
En esta plantilla actualizada, añadimos botones para resumir cada artículo. La función summarizeArticle
envía una solicitud al endpoint /summarize_article
y muestra el resumen dentro de la página.
12.4.4 Categorización de Artículos
Integraremos la funcionalidad de categorización para categorizar automáticamente los artículos de noticias en diferentes temas.
nlp_engine.py (continuación):
# Define function to categorize article
def categorize_article(article):
bow = dictionary.doc2bow(nltk.word_tokenize(article.lower()))
topics = lda_model.get_document_topics(bow)
sorted_topics = sorted(topics, key=lambda x: x[1], reverse=True)
topic_index = sorted_topics[0][0]
topic_terms = lda_model.show_topic(topic_index, topn=4)
topic_keywords = [term[0] for term in topic_terms]
return topic_keywords
Esta función utiliza el modelo LDA entrenado para categorizar el artículo en temas basados en las palabras clave más relevantes.
Aplicación Flask Actualizada:
@app.route('/categorize_article', methods=['POST'])
def categorize_article_route():
article = request.form.get('article')
category = categorize_article(article)
return jsonify({'category': category})
# HTML template for categorizing articles
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<div class="list-group-item">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
<button class="btn btn-secondary btn-sm mt-2" onclick="categorizeArticle('${article.content}')">Categorize</button>
<div class="category mt-2" id="category-${article.title}"></div>
<button class="btn btn-secondary btn-sm mt-2" onclick="summarizeArticle('${article.content}')">Summarize</button>
<div class="summary mt-2" id="summary-${article.title}"></div>
</div>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
function summarizeArticle(article) {
const summaryType = 'extractive'; // or 'abstractive'
$.post('/summarize_article', { article: article, summary_type: summaryType }, function(data) {
$('#summary-' + article.title).html('<p>' + data.summary + '</p>');
});
}
function categorizeArticle(article) {
$.post('/categorize_article', { article: article }, function(data) {
$('#category-' + article.title).html('<p>' + data.category.join(', ') + '</p>');
});
}
</script>
</body>
</html>
En esta plantilla actualizada, añadimos botones para categorizar cada artículo. La función categorizeArticle
envía una solicitud al endpoint /categorize_article
y muestra la categoría dentro de la página.
En esta sección, construimos la interfaz de usuario para el chatbot agregador de noticias. Utilizamos Flask para crear una interfaz web, permitiendo a los usuarios solicitar actualizaciones de noticias, ver resúmenes y categorizar artículos de noticias.
Creamos plantillas HTML con Bootstrap para un diseño receptivo y visualmente atractivo. El frontend interactúa con el backend para obtener artículos de noticias, resumirlos y categorizarlos en diferentes temas.
12.4 Construcción de la Interfaz de Usuario
En esta sección, nos centraremos en la construcción de la interfaz de usuario (UI) para el chatbot agregador de noticias. La UI es crucial ya que permite a los usuarios interactuar con el chatbot y acceder a los artículos de noticias. Crearemos una interfaz web utilizando Flask, un marco web ligero para Python. Esta interfaz permitirá a los usuarios solicitar actualizaciones de noticias, ver resúmenes y explorar artículos de noticias categorizados.
12.4.1 Configuración de Flask
Primero, necesitamos instalar Flask si aún no lo hemos hecho:
pip install Flask
A continuación, configuremos la estructura básica de nuestra aplicación Flask.
from flask import Flask, request, jsonify, render_template
from nlp_engine import preprocess_text, categorize_article
from summarizer import summarize_text, abstractive_summarize_text
from news_fetcher import fetch_news
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/get_news', methods=['POST'])
def get_news():
category = request.form.get('category')
articles = fetch_news(category)
return jsonify(articles)
@app.route('/summarize', methods=['POST'])
def summarize():
article = request.form.get('article')
summary_type = request.form.get('summary_type')
if summary_type == 'extractive':
summary = summarize_text(article)
else:
summary = abstractive_summarize_text(article)
return jsonify({'summary': summary})
if __name__ == '__main__':
app.run(debug=True)
En este script, definimos las rutas básicas para nuestra aplicación Flask:
- La ruta
home
renderiza la página de inicio. - La ruta
get_news
obtiene artículos de noticias basados en la categoría seleccionada. - La ruta
summarize
resume un artículo dado utilizando ya sea el resumen extractivo o el abstractivo.
12.4.2 Creación de Plantillas HTML
A continuación, crearemos plantillas HTML para renderizar las páginas web. Usaremos Bootstrap para el diseño y así crear una interfaz visualmente atractiva y receptiva.
templates/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<a href="${article.url}" target="_blank" class="list-group-item list-group-item-action">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
</a>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
</script>
</body>
</html>
En esta plantilla HTML, creamos un formulario simple para seleccionar la categoría de noticias y un div para mostrar los artículos de noticias obtenidos. Usamos jQuery para manejar el envío del formulario y actualizar dinámicamente la página con los artículos de noticias obtenidos.
12.4.3 Integración de Resumen y Categorización
Para permitir a los usuarios ver resúmenes y categorizar artículos, necesitamos agregar funcionalidad adicional tanto en el frontend como en el backend.
app.py (continuación):
@app.route('/categorize', methods=['POST'])
def categorize():
article = request.form.get('article')
category = categorize_article(article)
return jsonify({'category': category})
@app.route('/summarize_article', methods=['POST'])
def summarize_article():
article = request.form.get('article')
summary_type = request.form.get('summary_type')
if summary_type == 'extractive':
summary = summarize_text(article)
else:
summary = abstractive_summarize_text(article)
return jsonify({'summary': summary})
# Updated HTML template to include summarization and categorization
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<div class="list-group-item">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
<button class="btn btn-secondary btn-sm mt-2" onclick="summarizeArticle('${article.content}')">Summarize</button>
<div class="summary mt-2" id="summary-${article.title}"></div>
</div>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
function summarizeArticle(article) {
const summaryType = 'extractive'; // or 'abstractive'
$.post('/summarize_article', { article: article, summary_type: summaryType }, function(data) {
$('#summary-' + article.title).html('<p>' + data.summary + '</p>');
});
}
</script>
</body>
</html>
En esta plantilla actualizada, añadimos botones para resumir cada artículo. La función summarizeArticle
envía una solicitud al endpoint /summarize_article
y muestra el resumen dentro de la página.
12.4.4 Categorización de Artículos
Integraremos la funcionalidad de categorización para categorizar automáticamente los artículos de noticias en diferentes temas.
nlp_engine.py (continuación):
# Define function to categorize article
def categorize_article(article):
bow = dictionary.doc2bow(nltk.word_tokenize(article.lower()))
topics = lda_model.get_document_topics(bow)
sorted_topics = sorted(topics, key=lambda x: x[1], reverse=True)
topic_index = sorted_topics[0][0]
topic_terms = lda_model.show_topic(topic_index, topn=4)
topic_keywords = [term[0] for term in topic_terms]
return topic_keywords
Esta función utiliza el modelo LDA entrenado para categorizar el artículo en temas basados en las palabras clave más relevantes.
Aplicación Flask Actualizada:
@app.route('/categorize_article', methods=['POST'])
def categorize_article_route():
article = request.form.get('article')
category = categorize_article(article)
return jsonify({'category': category})
# HTML template for categorizing articles
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>News Aggregator Chatbot</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
<div class="container">
<h1 class="mt-5">News Aggregator Chatbot</h1>
<form id="news-form" class="mt-4">
<div class="form-group">
<label for="category">Select News Category</label>
<select class="form-control" id="category" name="category">
<option value="general">General</option>
<option value="business">Business</option>
<option value="technology">Technology</option>
<option value="sports">Sports</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Get News</button>
</form>
<div id="news-articles" class="mt-4"></div>
</div>
<script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
<script>
$(document).ready(function() {
$('#news-form').on('submit', function(event) {
event.preventDefault();
const category = $('#category').val();
$.post('/get_news', { category: category }, function(data) {
let articlesHtml = '<div class="list-group">';
data.forEach(article => {
articlesHtml += `
<div class="list-group-item">
<h5 class="mb-1">${article.title}</h5>
<p class="mb-1">${article.description}</p>
<small>${article.source} - ${article.publishedAt}</small>
<button class="btn btn-secondary btn-sm mt-2" onclick="categorizeArticle('${article.content}')">Categorize</button>
<div class="category mt-2" id="category-${article.title}"></div>
<button class="btn btn-secondary btn-sm mt-2" onclick="summarizeArticle('${article.content}')">Summarize</button>
<div class="summary mt-2" id="summary-${article.title}"></div>
</div>
`;
});
articlesHtml += '</div>';
$('#news-articles').html(articlesHtml);
});
});
});
function summarizeArticle(article) {
const summaryType = 'extractive'; // or 'abstractive'
$.post('/summarize_article', { article: article, summary_type: summaryType }, function(data) {
$('#summary-' + article.title).html('<p>' + data.summary + '</p>');
});
}
function categorizeArticle(article) {
$.post('/categorize_article', { article: article }, function(data) {
$('#category-' + article.title).html('<p>' + data.category.join(', ') + '</p>');
});
}
</script>
</body>
</html>
En esta plantilla actualizada, añadimos botones para categorizar cada artículo. La función categorizeArticle
envía una solicitud al endpoint /categorize_article
y muestra la categoría dentro de la página.
En esta sección, construimos la interfaz de usuario para el chatbot agregador de noticias. Utilizamos Flask para crear una interfaz web, permitiendo a los usuarios solicitar actualizaciones de noticias, ver resúmenes y categorizar artículos de noticias.
Creamos plantillas HTML con Bootstrap para un diseño receptivo y visualmente atractivo. El frontend interactúa con el backend para obtener artículos de noticias, resumirlos y categorizarlos en diferentes temas.