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
classHomepage: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
classHomepage:# ... __init__ como arriba ...defvisit(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:
classHomepage:# ... __init__ y visit ...defselect(self, query_string):return self._html.select(query_string)@propertydefarticle_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)returnlist({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.
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.