Obtención de datos del Artículo

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

Contenido del curso

Web scraping

Pandas

Resumen

Construye un scraper fiable en Python que valida vínculos, maneja errores HTTP y solo guarda artículos válidos. Aquí aprenderás a combinar expresiones regulares, programación defensiva y page objects como ArticlePage para recorrer vínculos del homepage, formar URLs correctas y filtrar contenido sin body.

¿Cómo construir y validar links con expresiones regulares en Python?

Para armar una URL correcta desde los vínculos del homepage, primero se distingue entre un vínculo bien formado (con esquema http/https), un vínculo relativo a la raíz (inicia con /) y un vínculo relativo (no inicia con / ni con http). Con expresiones regulares y el módulo re, se implementa pattern matching para decidir cómo construir el enlace final.

  • Usa import re para trabajar con regex en Python.
  • Define un patrón para vínculo bien formado: https?:// seguido de texto y una / más texto.
  • Define un patrón para path basado en la raíz: empieza con / y tiene contenido después.
  • Emplea raw strings con prefijo r y el símbolo caret ^ para indicar inicio de cadena.
import re IS_WELL_FORMED_LINK = re.compile(r'^https?://.+/.+') IS_ROOT_PATH = re.compile(r'^/.+') def build_link(host, link): if IS_WELL_FORMED_LINK.match(link): return link if IS_ROOT_PATH.match(link): return '{}{}'.format(host, link) # relativo: no inicia con '/' ni con 'http' return '{host}/{uri}'.format(host=host, uri=link)

¿Qué es un vínculo bien formado y uno relativo?

  • Bien formado: incluye esquema y dominio, por ejemplo, https://example.com/hello.
  • Relativo a la raíz: comienza con /, se antepone el host.
  • Relativo: no tiene / inicial ni esquema, se concatena *host/*vínculo.

¿Cómo se usa raw string y caret en regex?

  • Raw string r'': evita que secuencias como \n sean interpretadas.
  • ^ indica el inicio del patrón y $ el final, asegurando coincidencias exactas.

¿Cómo formatear URLs con format de Python?

  • Con posiciones: '{}{}'.format(host, link).
  • Con nombres: '{host}/{uri}'.format(host=host, uri=link).

¿Cómo obtener artículos con fetch_article y programación defensiva?

La función fetch_article crea el page object ArticlePage con una URL válida mediante build_link. Para que el scraper no muera ante fallos de red o páginas inexistentes, se aplica programación defensiva con try y except, capturando solo errores previstos.

  • Se registra el inicio con logger info y avisos con warning.
  • Se captura HTTPError cuando la página no existe.
  • Se captura MaxRetryError para evitar reintentos infinitos.
  • Se valida que el artículo tenga body; si no, se descarta.
from requests.exceptions import HTTPError from urllib3.exceptions import MaxRetryError def fetch_article(news_site_uid, host, link, logger): logger.info('start fetching article at {}'.format(link)) article = None try: article = ArticlePage(news_site_uid, build_link(host, link)) except (HTTPError, MaxRetryError): logger.warning('error while fetching the article') return None if not article or not getattr(article, 'body', None): logger.warning('invalid article, there is no body') return None return article

¿Qué errores capturar con Requests y urllib3?

  • HTTPError: surge cuando un vínculo del homepage apunta a una página inexistente.
  • MaxRetryError: evita bucles de reintentos contra una URL inalcanzable.

¿Cómo validar article.body antes de continuar?

  • Si article.body está vacío, el contenido no sirve para análisis.
  • Se devuelve None para mantener limpia la lista final de artículos.

¿Por qué el logger es clave en scraping?

  • Registro de eventos: inicio de fetch, avisos y conteos.
  • Diagnóstico rápido sin saturar la consola con trazas innecesarias.

¿Qué integra el flujo del news scraper desde homepage hasta la lista?

El flujo recorre cada vínculo del homepage, intenta formar una URL válida, construye ArticlePage y agrega el resultado a articles solo si es válido. Al final, se imprime el título de cada artículo y el total obtenido. Se mencionó ejecutar el main con el parámetro del sitio (por ejemplo, universal) y que el siguiente paso será guardar en disco para no perder datos al terminar el proceso.

articles = [] for link in homepage_links: article = fetch_article(news_site_uid, host, link, logger) if article: logger.info('article fetched') articles.append(article) print(article.title) print(len(articles))
  • Itera sobre vínculos del homepage y normaliza URLs.
  • Construye ArticlePage con news_site_uid, host y link.
  • Aplica try/except selectivo: HTTPError, MaxRetryError.
  • Filtra por article.body para asegurar contenido útil.
  • Reporta progreso con logger y muestra article.title.
  • Prepara el terreno para persistencia en disco.

¿Tienes dudas con regex o con la jerarquía de objetos del news page? Deja tu comentario y con gusto te ayudamos a resolverlo.