Contenido del curso
Web Estático Avanzado
Scraping Dinámico con Selenium
Scraping Dinámico con Playwright
Extrae nombre, precio e imagen con BeautifulSoup
Resumen
Hacer web scraping de un catálogo de libros con Python y BeautifulSoup te permite obtener nombre, precio e imagen de cada producto en pocos minutos. Si estás aprendiendo a automatizar la extracción de datos de páginas web, este recorrido te muestra cómo identificar contenedores HTML, recorrerlos con un loop y guardar los resultados en un archivo CSV listo para analizar.
¿Cómo identifico el contenedor de cada producto en el HTML?
Antes de escribir código, abre las herramientas de desarrollo del navegador con clic derecho y "Inspeccionar". En el sitio de práctica vas a notar que cada libro vive dentro de una etiqueta article con la clase product-pod. Ese contenedor agrupa la imagen, el título en h3, las estrellas y el precio.
Identificar bien ese nodo padre es clave, porque sobre él vas a iterar para extraer las propiedades de cada libro sin mezclar información entre productos.
¿Qué es un selector CSS en BeautifulSoup? Es una cadena que describe qué etiqueta y clase buscar en el HTML. Por ejemplo,
article.product-podselecciona todos losarticlecon la claseproduct-pod.
¿Cómo obtengo el listado de productos con select?
Después de hacer la petición GET y parsear el HTML con soup, defines la variable que contendrá todos los artículos:
python products = soup.select("article.product-pod")
El método select te devuelve una lista de elementos. Si imprimes products, verás cada bloque HTML completo, pero en este punto solo te interesan tres campos por libro: nombre, precio e imagen.
¿Cómo extraigo nombre, precio e imagen de cada producto?
La lógica es recorrer el listado con un for y, dentro del loop, usar find sobre cada product (no sobre soup) para acotar la búsqueda al contenedor del libro actual.
- Nombre: el título vive dentro de un
h3y, más específicamente, en el atributotitlede la etiqueta<a>interna. Por eso accedes conproduct.find("h3").find("a")["title"]. - Precio: está en una etiqueta
<p>con la claseprice color. Aplicas.get_text()al final para limpiar la etiqueta y quedarte con el valor. - Imagen: se encuentra dentro de un
divcon clase contenedora. Como el atributo correcto está en la etiquetaimg, usasproduct.find("div", class_="container").find("img")["src"].
Un detalle importante: la URL de la imagen es relativa. No incluye www.books.toscrape.com, así que debes concatenar la raíz del sitio con la ruta extraída para obtener la URL completa que sí abre la imagen en el navegador.
¿Por qué uso guion bajo en class_ dentro de find? Porque
classes una palabra reservada en Python. BeautifulSoup adoptaclass_para que puedas filtrar por clase CSS sin romper la sintaxis del lenguaje.
¿Por qué fallaba el atributo href en la imagen?
Un error común es intentar leer href desde una etiqueta <a> cuando lo que necesitas es el src de una etiqueta <img>. Si te aparece un error de atributo inexistente, revisa qué etiqueta estás consultando. En este caso, cambiar a por img y href por src resuelve el problema y te entrega la URL del recurso.
Esta diferencia entre etiquetas y atributos es lo que distingue el scraping funcional del que rompe en producción.
¿Cómo guardo los datos extraídos en un CSV?
Una vez que tienes la lista de diccionarios con los 20 productos, los exportas a un archivo dentro de una carpeta resultados llamado productos.csv. Los parámetros que importan al abrir el archivo son:
- Modo
"w"para escritura (write). newline=""para que no se inserten saltos de línea adicionales entre filas.encodingconfigurado para soportar caracteres especiales sin romper el archivo.
Las columnas que defines son nombre, precio e imagen_url, y le pasas el listado de productos generado en el loop. Al ejecutar, la consola confirma "extracción completa, 20 productos guardados" y puedes abrir el CSV directamente desde Visual Studio Code para validar el resultado.
El flujo final combina tres habilidades centrales: inspección del DOM, navegación con find y select y persistencia en CSV. Con esa base puedes adaptar el script a cualquier catálogo con estructura similar.
¿Qué reto puedes resolver para practicar?
El ejercicio propuesto es ampliar la extracción para incluir dos campos adicionales por libro:
- El número de estrellas que aparece junto al título.
- El estado de stock, es decir, si el libro está disponible o agotado.
Déjame tu solución en los comentarios y comparte qué selector usaste para capturar las estrellas, que suelen estar codificadas como clases CSS en lugar de texto plano.