Contenido del curso

Web scraping

Pandas

Page Objects para extraer vínculos de noticias

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.