Page Objects para extraer vínculos de noticias

Clase 17 de 38Curso de Ingeniería de Datos con Python

Contenido del curso

Web scraping

Pandas

Resumen

La construcción de un scraper profesional comienza separando la configuración del código y modelando la interfaz con Page Objects. Aquí verás cómo crear un Homepage que visita una URL, parsea el HTML con requests y Beautiful Soup, y extrae article links definidos desde un archivo YAML para sitios como El Universal.

Page Objects en Python: extracción de vínculos de noticias

¿Cómo se define el Page Object de la homepage?

Un Page Object abstrae la lógica de cada página para mantener el código claro y escalable. La clase Homepage recibe una URL y el ID del sitio de noticias, consulta la configuración y prepara el HTML para seleccionar elementos.

  • Se crea el archivo: News Page Objects.
  • Se define la clase: Homepage.
  • El método init recibe: url y news site id.
  • Se obtiene la configuración con config y la clave de News Sites.
  • Se guardan las queries de la configuración para seleccionar elementos.

¿Qué parámetros y dependencias necesita init?

  • Parámetros: url del sitio y news_site_uid.
  • Dependencias: función config importada con: from common import config.
  • Estructura deseada: guardar self._queries y self._html inicial en None.

Ejemplo de estructura en Python:

from common import config class Homepage: def __init__(self, url, news_site_uid): self._url = url site_cfg = config()['news_sites'][news_site_uid] self._queries = site_cfg['queries'] self._html = None

¿Cómo se visita la URL y se parsea HTML con requests y Beautiful Soup?

Tras inicializar, el objeto visita la URL, valida el estado y parsea el contenido con Beautiful Soup usando el html parser. Se almacena el árbol en self._html.

  • Librerías: requests y Beautiful Soup.
  • Validación: response.raise_for_status() para cortar en caso de error.
  • Parser: 'html.parser' para construir el árbol navegable.

¿Qué hace el método visit y por qué raise_for_status?

  • visit: descarga la página y convierte el texto en un árbol HTML.
  • raise_for_status: lanza error si la solicitud falló.

Implementación sugerida:

import requests from bs4 import BeautifulSoup class Homepage: # ... __init__ como arriba ... def visit(self): response = requests.get(self._url) response.raise_for_status() self._html = BeautifulSoup(response.text, 'html.parser')

¿Cómo se seleccionan y depuran los article links desde YAML?

La selección se configura en YAML y el objeto la ejecuta con un select auxiliar que aplica el query string al árbol HTML. Luego se filtran elementos válidos con href y se deduplican con un set.

  • Función auxiliar: select(query_string) que usa self._html.select(query_string).
  • Propiedad article_links: recorre los nodos, toma link['href'] y deduplica.
  • Uso de set y comprensión para eliminar repetidos.

¿Cómo se conecta select con article_links?

  • select devuelve una lista de nodos.
  • article_links filtra por href y devuelve una lista única.

Código ilustrativo:

class Homepage: # ... __init__ y visit ... def select(self, query_string): return self._html.select(query_string) @property def article_links(self): link_list = [] for link in self.select(self._queries['homepage_article_links']): if link and link.has_attr('href'): link_list.append(link) return list({link['href'] for link in link_list})

¿Cómo debe verse la configuración en config.yaml?

Se agrega la llave queries por sitio y dentro la clave homepage article links. Para El Universal, se añade también field content según lo preparado.

Ejemplo YAML:

news_sites: eluniversal: url: https://www.eluniversal.com.mx queries: homepage article links: "" field content: "" elpais: url: https://elpais.com queries: homepage article links: ""

Importante: en YAML se usan dos puntos y no el signo =. Un uso incorrecto genera errores de lectura del archivo.

¿Cómo se integra en el archivo principal para imprimir vínculos?

  • Importación con alias: import News Page Objects as News.
  • Instanciación: HomePage = News.HomePage(news_site_uid, host).
  • Iteración: for link in HomePage.article_links: print(link).

Ejemplo:

import News_Page_Objects as News home = News.Homepage(url=host, news_site_uid='eluniversal') home.visit() for link in home.article_links: print(link)

Habilidades y conceptos reforzados:

  • Diseño con Page Objects para desacoplar lógica y configuración.
  • Parsing HTML con Beautiful Soup y selectores CSS.
  • Manejo de errores HTTP con raise_for_status.
  • Lectura de YAML y estructura de queries por sitio.
  • Filtrado y deduplicación con comprensiones y set.

¿Te gustaría compartir tu propia versión del selector para El País o una variante con set comprehension? Deja tu comentario y cuéntanos cómo lo resolviste.