En este artículo, crearemos una aplicación web de noticias utilizando Flask y NewsAPI. La página web mostrará los principales titulares y una barra de búsqueda donde el usuario puede ingresar una consulta, después de procesar la consulta, la página web mostrará todos los artículos relevantes (hasta un máximo de 100 titulares). Crearemos una interfaz de usuario simple usando HTML y bootstrap. Puede usar cualquier IDE de su elección, por ejemplo. Código VS o texto sublime, etc.
Introducción a Flask y NewsAPI
Flask: Flask es un marco web escrito en python que nos permite crear puntos finales del lado del servidor. Puede obtener más información sobre el matraz en este enlace: https://www.geeksforgeeks.org/python-introduction-to-web-development-using-flask/.
NewsAPI: News API es una API Rest simple para recuperar artículos en vivo de toda la web. Con News API, podemos obtener los principales titulares de un país de una fuente en particular, como Times of India, Hindustan Times, BBC News y muchos más. También podemos buscar artículos relacionados con un tema en particular. visite https://newsapi.org/ para obtener más información.
Generación de claves API
Para utilizar News API en nuestra aplicación, debemos generar una clave de API única desde https://newsapi.org/. Visite este sitio web y cree su cuenta gratuita, en el registro exitoso y la verificación por correo electrónico obtendrá su clave API en la pantalla. Al registrarse, es posible que deba elegir un plan de desarrollador (elija según sus requisitos). Guarde esta clave API en algún lugar para que pueda usarse más.
Instalación de Flask y NewsAPI
Simplemente instalaremos Flask usando el comando pip:
pip install flask
Después de una instalación exitosa, cree una carpeta para el nombre de la aplicación, esta carpeta matraz_noticias o cualquier otra cosa de su elección. Dentro de esta carpeta crea un nuevo archivo llamado app.py. Escribiremos todo nuestro código de back-end en este archivo en los próximos pasos.
Para instalar NewsAPI usaremos un comando pip como este:
pip install newsapi-python
Puede obtener más información sobre la biblioteca newsapi-python aquí: https://newsapi.org/docs/client-libraries/python
Creación de puntos finales de back-end
Hay dos cosas que queremos de nuestra aplicación:
- Muestra los titulares principales cuando se abre la aplicación web.
- Mostrar resultados basados en una consulta de búsqueda.
En primer lugar, importaremos el matraz y newsapi en el archivo app.py.
Python3
# import libraries from flask import Flask, render_template, request from newsapi import NewsApiClient # init flask app app = Flask(__name__) # Init news api newsapi = NewsApiClient(api_key='YOUR_API_KEY')
Para obtener los principales titulares, usaremos la función get_top_headlines de la biblioteca newsapi . Podemos pasar parámetros a esta función como país, idioma, fuentes, etc. En esta aplicación, pasaremos un parámetro adicional llamado page_size para obtener todos los titulares. La función de la biblioteca newsapi solo devuelve los 20 artículos principales, pero también tiene un campo llamado totalResults en el objeto de respuesta JSON. Modificaremos nuestra llamada de función para obtener todos los resultados usando el parámetro page_size . Esta parte del código se ve así:
Python3
# this function returns a JSON object top_headlines = newsapi.get_top_headlines(country="in", language="en") total_results = top_headlines['totalResults'] # the maximum value for page_size parameter is 100 # so we need to keep it at max 100 if total_results > 100: total_results = 100 # fetch articles where no. of articles=total_results # this returns a list of articles all_headlines = newsapi.get_top_headlines(country="in", language="en", page_size=total_results)['articles']
Enviaremos esta lista de artículos al código HTML.
Obtener artículos relacionados con una consulta de búsqueda
Esto estará relacionado con una solicitud de publicación. Vamos a utilizar la función get_everything con parámetros como fuentes de consulta, dominios, idioma, clasificación basada en y tamaño de página. Obtendremos todas las fuentes con la ayuda de la función get_sources de newsapi y para obtener todos los dominios usaremos la propiedad ‘URL’ de cada fuente. Aquí está el código que muestra cómo vamos a manejarlo:
Python3
# this function will return sources and domains in str format # each of them separated by a comma def get_sources_and_domains(): all_sources = newsapi.get_sources()['sources'] sources = [] domains = [] for e in all_sources: id = e['id'] domain = e['url'].replace("http://", "") domain = domain.replace("https://", "") domain = domain.replace("www.", "") slash = domain.find('/') if slash != -1: domain = domain[:slash] sources.append(id) domains.append(domain) sources = ", ".join(sources) domains = ", ".join(domains) return sources, domains # in post request sources, domains = get_sources_and_domains() related_news = newsapi.get_everything(q=keyword, sources=sources, domains=domains, language='en', sort_by='relevancy') no_of_articles = related_news['totalResults'] # the max number of article can be fetched is 100 if no_of_articles > 100: no_of_articles = 100 all_articles = newsapi.get_everything(q=keyword, sources=sources, domains=domains, language='en', sort_by='relevancy', page_size=no_of_articles)['articles'] # we will send this list of articles to the html web page
Ahora podemos modelar todo el programa para obtener los puntos finales requeridos de la API del matraz. Básicamente, necesitamos una forma de manejar las requests GET para obtener todos los titulares y otra para manejar las requests POST para una consulta de búsqueda. Así es como se verá todo el archivo app.py después de agregar la ruta necesaria.
Código completo de app.py:
Python3
# import libraries from flask import Flask, render_template, request from newsapi import NewsApiClient # init flask app app = Flask(__name__) # Init news api newsapi = NewsApiClient(api_key='70fdb9ba81ba40b6bda148e672898bd9') # helper function def get_sources_and_domains(): all_sources = newsapi.get_sources()['sources'] sources = [] domains = [] for e in all_sources: id = e['id'] domain = e['url'].replace("http://", "") domain = domain.replace("https://", "") domain = domain.replace("www.", "") slash = domain.find('/') if slash != -1: domain = domain[:slash] sources.append(id) domains.append(domain) sources = ", ".join(sources) domains = ", ".join(domains) return sources, domains @app.route("/", methods=['GET', 'POST']) def home(): if request.method == "POST": sources, domains = get_sources_and_domains() keyword = request.form["keyword"] related_news = newsapi.get_everything(q=keyword, sources=sources, domains=domains, language='en', sort_by='relevancy') no_of_articles = related_news['totalResults'] if no_of_articles > 100: no_of_articles = 100 all_articles = newsapi.get_everything(q=keyword, sources=sources, domains=domains, language='en', sort_by='relevancy', page_size = no_of_articles)['articles'] return render_template("home.html", all_articles = all_articles, keyword=keyword) else: top_headlines = newsapi.get_top_headlines(country="in", language="en") total_results = top_headlines['totalResults'] if total_results > 100: total_results = 100 all_headlines = newsapi.get_top_headlines(country="in", language="en", page_size=total_results)['articles'] return render_template("home.html", all_headlines = all_headlines) return render_template("home.html") if __name__ == "__main__": app.run(debug = True)
Creación de interfaz de usuario
Crearemos una página HTML que atenderá todas las requests de los usuarios. Cree una carpeta llamada templates en su directorio raíz ( carpeta flass_news ). Cree un archivo llamado «home.html» dentro de la carpeta de plantillas . La estructura de carpetas debería verse así:
Ahora agregue el código final en home.html :
HTML
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>News application</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> </head> <body> <div class="container"> <form action="/" method="post"> <div class="input-group mb-3"> <input type="text" class="form-control" name="keyword" placeholder="Enter keyword ...." aria-label="Recipient's username" aria-describedby="button-addon2"> <button class="btn btn-outline-secondary" type="button" id="button-addon2">Search</button> </div> </form> </div> {% if all_headlines %} <center><h1>Headlines</h1></center> <div class="row row-cols-1 row-cols-md-2 g-4 mx-3 my-3"> {% for headline in all_headlines %} <div class="col"> <div class="card h-100"> <img src="{{headline['urlToImage']}}" class="card-img-top" alt="..."> <div class="card-body"> <h3 class="card-title">{{headline['title']}}</h3> <p class="card-text">{{headline['description']}} <a href="{{headline['url']}}" target="blank">Read More...</a></p> </div> <div class="card-footer"> <small class="text-muted">{{headline['source']['name']}}</small> </div> </div> </div> {% endfor %} </div> {% endif %} {% if all_articles %} <center><h1>Results for '{{keyword}}'</h1></center> <div class="row row-cols-1 row-cols-md-2 g-4 mx-3 my-3"> {% for article in all_articles %} <div class="col"> <div class="card h-100"> <img src="{{article['urlToImage']}}" class="card-img-top" alt="..."> <div class="card-body"> <h3 class="card-title">{{article['title']}}</h3> <p class="card-text">{{article['description']}} <a href="{{article['url']}}" target="blank">Read More...</a></p> </div> <div class="card-footer"> <small class="text-muted">{{article['source']['name']}}</small> </div> </div> </div> {% endfor %} </div> {% endif %} <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script> </body> </html>
Probando la aplicación
Ejecutemos el servidor y verifiquemos si nuestra aplicación funciona o no. Vaya a la terminal y ejecute el archivo app.py usando este comando:
python .\app.py
La salida en la consola debería verse así:
Ahora vaya a http://127.0.0.1:5000 o localhost:5000 y la salida debería ser así: