Python

Python

Tutorial Python: Sintaxis general de Beautiful Soup

Beautiful Soup sintaxis general: aprende a extraer datos de HTML con Python. Crea objetos BeautifulSoup, navega el DOM y manipula elementos usando métodos y selectores CSS.

Aprende Python y certifícate

Creación y estructura básica de un objeto BeautifulSoup

Para comenzar a trabajar con BeautifulSoup, es necesario crear un objeto que represente el documento HTML o XML que deseamos analizar. Este objeto nos permite navegar y manipular el contenido del documento. Primero, debemos importar la librería y luego crear el objeto BeautifulSoup utilizando el contenido HTML.

Por ejemplo:

from bs4 import BeautifulSoup

html_doc = '''
<html>
    <head>
        <title>Ejemplo de página</title>
    </head>
    <body>
        <p class="titulo">Título del párrafo</p>
        <p id="parrafo1">Este es el primer párrafo.</p>
        <p id="parrafo2">Este es el segundo párrafo.</p>
    </body>
</html>
'''

soup = BeautifulSoup(html_doc, 'html.parser')

En este ejemplo, hemos creado una cadena de texto llamada **html_doc** que contiene el código HTML. Luego, al crear el objeto BeautifulSoup llamado soup, utilizamos el analizador 'html.parser'. Este analizador es adecuado para la mayoría de los casos y está integrado en Python.

Una vez que hemos creado un objeto BeautifulSoup, podemos navegar por el árbol DOM del documento para acceder a elementos específicos. El árbol DOM representa la estructura jerárquica del documento HTML, donde las etiquetas se relacionan como padres, hijos y hermanos.

Para acceder al padre de un elemento, podemos utilizar el atributo .parent. Por ejemplo:

parrafo = soup.find('p', class_='titulo')
padre_parrafo = parrafo.parent
print(padre_parrafo.name)
# Resultado: body

En este caso, estamos obteniendo el elemento <p> con la clase "titulo" y luego accediendo a su padre, que es la etiqueta <body>.

Para iterar sobre los hijos de un elemento, podemos utilizar el atributo .contents, que devuelve una lista de los elementos hijos directos, o .children, que es un iterador de los mismos. Por ejemplo:

cuerpo = soup.body
hijos_cuerpo = cuerpo.contents
for hijo in hijos_cuerpo:
    print(hijo.name)
# Resultado:
# p
# p
# p

Si queremos acceder a los hermanos de un elemento (etiquetas al mismo nivel jerárquico), utilizamos .next_sibling y .previous_sibling. Por ejemplo:

parrafo1 = soup.find('p', id='parrafo1')
siguiente_hermano = parrafo1.next_sibling
print(siguiente_hermano)
# Resultado: '\n'
siguiente_parrafo = siguiente_hermano.next_sibling
print(siguiente_parrafo)
# Resultado: <p id="parrafo2">Este es el segundo párrafo.</p>

Es importante tener en cuenta que los saltos de línea y espacios en blanco en el HTML se consideran nodos, por lo que al navegar por los hermanos, a veces obtenemos caracteres de nueva línea ('\n'). Para evitarlos, podemos utilizar funciones como .next_siblings que permiten iterar sobre todos los hermanos siguientes de manera más limpia:

for hermano in parrafo1.next_siblings:
    if hermano.name:
        print(hermano.name)
# Resultado: p

La navegación del árbol DOM utilizando padres, hijos y hermanos es fundamental para acceder y manipular elementos específicos dentro del documento HTML.

Acceso y modificación de atributos y contenidos de etiquetas

BeautifulSoup nos permite acceder y modificar los atributos y el contenido de las etiquetas en el documento HTML. Esto es útil cuando necesitamos extraer información o actualizar elementos específicos.

Para acceder a los atributos de una etiqueta, tratamos el objeto etiqueta como un diccionario. Por ejemplo, para obtener el valor del atributo class de un párrafo:

parrafo = soup.find('p', class_='titulo')
clase_parrafo = parrafo['class']
print(clase_parrafo)
# Resultado: ['titulo']

Si deseamos obtener todos los atributos de una etiqueta, podemos utilizar el atributo .attrs:

atributos_parrafo = parrafo.attrs
print(atributos_parrafo)
# Resultado: {'class': ['titulo']}

Para modificar un atributo, simplemente asignamos un nuevo valor:

parrafo['class'] = 'nuevo-titulo'
print(parrafo)
# Resultado: <p class="nuevo-titulo">Título del párrafo</p>

Si queremos agregar un nuevo atributo, podemos hacerlo de la misma manera:

parrafo['data-custom'] = 'valor personalizado'
print(parrafo)
# Resultado: <p class="nuevo-titulo" data-custom="valor personalizado">Título del párrafo</p>

Para eliminar un atributo, utilizamos el operador del:

del parrafo['class']
print(parrafo)
# Resultado: <p data-custom="valor personalizado">Título del párrafo</p>

En cuanto al contenido de las etiquetas, podemos acceder y modificar el texto encerrado entre las etiquetas utilizando el atributo .string o .text. El atributo .string devuelve un objeto NavigableString si la etiqueta solo contiene texto, mientras que .text devuelve una cadena con todo el texto contenido, incluso si hay etiquetas anidadas.

Por ejemplo, para obtener y modificar el contenido de un párrafo:

contenido_parrafo = parrafo.string
print(contenido_parrafo)
# Resultado: Título del párrafo

parrafo.string.replace_with('Nuevo título del párrafo')
print(parrafo)
# Resultado: <p data-custom="valor personalizado">Nuevo título del párrafo</p>

Si el contenido de la etiqueta es más complejo (por ejemplo, contiene etiquetas anidadas), podemos utilizar .get_text() para obtener todo el texto:

html_doc = '''
<p>Este es un <strong>párrafo</strong> con texto en negrita.</p>
'''
soup = BeautifulSoup(html_doc, 'html.parser')
parrafo = soup.p
texto = parrafo.get_text()
print(texto)
# Resultado: Este es un párrafo con texto en negrita.

La capacidad de acceder y modificar atributos y contenidos de etiquetas nos permite manipular el documento HTML según nuestras necesidades, extrayendo información relevante o actualizando elementos específicos.

Uso de métodos find() y find_all() para búsqueda de elementos

Los métodos **find()** y **find_all()** son fundamentales en BeautifulSoup para buscar y extraer elementos del documento HTML. Nos permiten localizar etiquetas específicas basadas en su nombre, atributos, texto y más.

El método find() devuelve el primer elemento que coincide con los criterios de búsqueda, mientras que find_all() devuelve una lista de todos los elementos coincidentes.

Por ejemplo, para encontrar la primera etiqueta <p> en el documento:

primer_parrafo = soup.find('p')
print(primer_parrafo)
# Resultado: <p data-custom="valor personalizado">Nuevo título del párrafo</p>

Para encontrar todos los párrafos:

todos_los_parrafos = soup.find_all('p')
for p in todos_los_parrafos:
    print(p)
# Resultado:
# <p data-custom="valor personalizado">Nuevo título del párrafo</p>
# <p id="parrafo1">Este es el primer párrafo.</p>
# <p id="parrafo2">Este es el segundo párrafo.</p>

Podemos afinar la búsqueda utilizando atributos. Por ejemplo, para encontrar el párrafo con id="parrafo1":

parrafo1 = soup.find('p', id='parrafo1')
print(parrafo1)
# Resultado: <p id="parrafo1">Este es el primer párrafo.</p>

Si queremos encontrar todos los párrafos con una clase o atributo específico:

parrafos_titulo = soup.find_all('p', class_='titulo')
for p in parrafos_titulo:
    print(p)

También podemos utilizar el parámetro attrs para buscar por cualquier atributo:

parrafos_personalizados = soup.find_all('p', attrs={'data-custom': 'valor personalizado'})
for p in parrafos_personalizados:
    print(p)
# Resultado: <p data-custom="valor personalizado">Nuevo título del párrafo</p>

La búsqueda puede ser aún más específica utilizando funciones anónimas (lambdas) o expresiones regulares. Por ejemplo, para encontrar todos los elementos cuya clase comienza con 'titulo':

import re
parrafos_titulo = soup.find_all('p', class_=re.compile('^titulo'))
for p in parrafos_titulo:
    print(p)

Además, podemos buscar elementos basados en su texto utilizando el parámetro string:

parrafo_texto = soup.find('p', string='Este es el primer párrafo.')
print(parrafo_texto)
# Resultado: <p id="parrafo1">Este es el primer párrafo.</p>

Los métodos find() y find_all() son herramientas esenciales para extraer información específica de un documento HTML, permitiéndonos buscar de manera flexible y precisa según nuestras necesidades.

Manejo y extracción de texto y comentarios en HTML

Al realizar scraping de páginas web, es común necesitar extraer el texto contenido en las etiquetas, así como manejar los comentarios presentes en el código HTML. BeautifulSoup proporciona herramientas para acceder y manipular estos elementos.

Para extraer el texto de todo el documento o de una etiqueta específica, utilizamos el método .get_text():

texto_completo = soup.get_text()
print(texto_completo)

Este método devuelve una cadena con todo el texto, eliminando las etiquetas HTML. Si queremos extraer el texto de una sección específica, podemos seleccionar la etiqueta correspondiente:

cuerpo = soup.body
texto_cuerpo = cuerpo.get_text()
print(texto_cuerpo)
# Resultado:
# Nuevo título del párrafo
# Este es el primer párrafo.
# Este es el segundo párrafo.

Para manejar los comentarios en el HTML, BeautifulSoup los trata como objetos Comment. Podemos buscar comentarios y acceder a su contenido.

Por ejemplo, si el HTML contiene un comentario:

html_doc = '''
<html>
    <body>
        <!-- Este es un comentario -->
        <p>Texto dentro del párrafo.</p>
    </body>
</html>
'''
soup = BeautifulSoup(html_doc, 'html.parser')

Para encontrar los comentarios, podemos buscar todos los elementos de tipo Comment:

from bs4 import Comment

comentarios = soup.find_all(string=lambda text: isinstance(text, Comment))
for comentario in comentarios:
    print(comentario)
# Resultado:  Este es un comentario 

Si necesitamos eliminar comentarios del documento, podemos recorrerlos y utilizar el método .extract():

for comentario in comentarios:
    comentario.extract()

Ahora, si volvemos a obtener el texto del documento:

texto_sin_comentarios = soup.get_text()
print(texto_sin_comentarios)
# Resultado:
# 
# 
# Texto dentro del párrafo.

La capacidad de extraer y manipular texto y comentarios es importante para limpiar el contenido y obtener únicamente la información relevante de una página web.

Esquema resumen de la API de Beautiful Soup

A continuación, veremos un esquema que resume los principales métodos y atributos de Beautiful Soup que podemos utilizar:

  • 1. Creación de la instancia (**BeautifulSoup**)
    • Ejemplo básico:
      • soup = BeautifulSoup(html_doc, 'html.parser')
    • Parsers más usados:
      • 'html.parser' (por defecto, sin dependencias)
      • 'lxml' (más rápido, tolera HTML malformado, requiere lxml)
      • 'html5lib' (muy tolerante, requiere html5lib)
  • 2. Navegación y acceso a elementos
    • Acceso directo por etiqueta
      • soup.title (devuelve el primer <title>)
      • soup.title.string (texto dentro de <title>)
    • Atributos de un Tag
      • tag.name (nombre de la etiqueta, ej. "div")
      • tag.attrs (diccionario de todos los atributos)
      • tag['id'], tag.get('class') (acceso a atributos concretos)
      • tag.string o tag.text (texto contenido, si es simple)
      • tag.parent (etiqueta padre)
    • Navegación en el árbol
      • Hijos: tag.contents, tag.children
      • Todos los descendientes: tag.descendants
      • Padres: tag.parent, tag.parents
      • Hermanos: tag.next_sibling, tag.previous_sibling (ojo con saltos de línea)
      • Secuencia: tag.next_element, tag.previous_element
  • 3. Métodos de búsqueda
    • **find()**
      • Retorna el primer elemento que coincida.
      • Ejemplos:
        • soup.find('div')
        • soup.find(id='main')
        • soup.find(class_='active')
        • soup.find('div', {'data-type': 'x'})
    • **find_all()**
      • Retorna todos los elementos que coincidan.
      • Ejemplos:
        • soup.find_all('div')
        • soup.find_all(['div', 'p'])
        • soup.find_all(class_='product')
        • soup.find_all('span', limit=3)
    • **select()** y **select_one()** (selectores CSS)
      • soup.select('div#main') (div con id="main")
      • soup.select('.content li a') (dentro de clase .content, buscar <li><a>)
      • soup.select_one('div#container') (solo el primer match)
  • 4. Extracción y manipulación de texto
    • tag.get_text() (retorna todo el texto interno, sin HTML)
    • tag.string (si la etiqueta tiene un único nodo de texto)
    • tag.stripped_strings (iterador de nodos de texto, sin espacios vacíos extra)
  • 5. Modificación del árbol HTML
    • Modificar texto o nodos
      • tag.string = "Nuevo texto" (sobrescribe texto)
      • tag.replace_with(nuevo_tag_o_texto) (sustituye la etiqueta/nodo)
    • Añadir elementos
      • tag.append(nuevo_tag) (al final de su contenido)
      • tag.insert(0, nuevo_tag) (en posición concreta)
      • tag.insert_before(nuevo_tag), tag.insert_after(nuevo_tag)
    • Eliminar elementos
      • tag.extract() (lo quita del árbol y lo devuelve)
      • tag.decompose() (lo destruye sin devolver nada)
    • Envolver y desenvolver
      • tag.wrap(wrapper_tag) (envuelve tag dentro de wrapper_tag)
      • tag.unwrap() (elimina la etiqueta, conservando el contenido)
    • Limpiar contenido interno
      • tag.clear() (vacía el contenido de la etiqueta)
  • 6. Conversiones y formateo
    • str(tag) (HTML del Tag como cadena)
    • tag.prettify() (HTML con indentación y formato bonito)
    • tag.encode('utf-8') (resultado en bytes, codificado en UTF-8)
  • 7. Objetos especiales
    • **NavigableString** (nodo de texto dentro del árbol)
      • Ej: type(tag.string) == NavigableString
    • **Comment** (nodo de comentario <!-- ... -->)
      • Se maneja similar a un texto, pero es un tipo distinto (Comment).
Aprende Python online

Otras lecciones de Python

Accede a todas las lecciones de Python y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Python

Python

Introducción

Instalación Y Creación De Proyecto

Python

Introducción

Tema 2: Tipos De Datos, Variables Y Operadores

Python

Introducción

Instalación De Python

Python

Introducción

Tipos De Datos

Python

Sintaxis

Variables

Python

Sintaxis

Operadores

Python

Sintaxis

Estructuras De Control

Python

Sintaxis

Funciones

Python

Sintaxis

Estructuras Control Iterativo

Python

Sintaxis

Estructuras Control Condicional

Python

Sintaxis

Testing Con Pytest

Python

Sintaxis

Listas

Python

Estructuras De Datos

Tuplas

Python

Estructuras De Datos

Diccionarios

Python

Estructuras De Datos

Conjuntos

Python

Estructuras De Datos

Comprehensions

Python

Estructuras De Datos

Clases Y Objetos

Python

Programación Orientada A Objetos

Excepciones

Python

Programación Orientada A Objetos

Encapsulación

Python

Programación Orientada A Objetos

Herencia

Python

Programación Orientada A Objetos

Polimorfismo

Python

Programación Orientada A Objetos

Mixins Y Herencia Múltiple

Python

Programación Orientada A Objetos

Métodos Especiales (Dunder Methods)

Python

Programación Orientada A Objetos

Composición De Clases

Python

Programación Orientada A Objetos

Funciones Lambda

Python

Programación Funcional

Aplicación Parcial

Python

Programación Funcional

Entrada Y Salida, Manejo De Archivos

Python

Programación Funcional

Decoradores

Python

Programación Funcional

Generadores

Python

Programación Funcional

Paradigma Funcional

Python

Programación Funcional

Composición De Funciones

Python

Programación Funcional

Funciones Orden Superior Map Y Filter

Python

Programación Funcional

Funciones Auxiliares

Python

Programación Funcional

Reducción Y Acumulación

Python

Programación Funcional

Archivos Comprimidos

Python

Entrada Y Salida Io

Entrada Y Salida Avanzada

Python

Entrada Y Salida Io

Archivos Temporales

Python

Entrada Y Salida Io

Contexto With

Python

Entrada Y Salida Io

Módulo Csv

Python

Biblioteca Estándar

Módulo Json

Python

Biblioteca Estándar

Módulo Datetime

Python

Biblioteca Estándar

Módulo Math

Python

Biblioteca Estándar

Módulo Os

Python

Biblioteca Estándar

Módulo Re

Python

Biblioteca Estándar

Módulo Random

Python

Biblioteca Estándar

Módulo Time

Python

Biblioteca Estándar

Módulo Collections

Python

Biblioteca Estándar

Módulo Sys

Python

Biblioteca Estándar

Módulo Statistics

Python

Biblioteca Estándar

Módulo Pickle

Python

Biblioteca Estándar

Módulo Pathlib

Python

Biblioteca Estándar

Importar Módulos Y Paquetes

Python

Paquetes Y Módulos

Crear Módulos Y Paquetes

Python

Paquetes Y Módulos

Entornos Virtuales (Virtualenv, Venv)

Python

Entorno Y Dependencias

Gestión De Dependencias (Pip, Requirements.txt)

Python

Entorno Y Dependencias

Python-dotenv Y Variables De Entorno

Python

Entorno Y Dependencias

Acceso A Datos Con Mysql, Pymongo Y Pandas

Python

Acceso A Bases De Datos

Acceso A Mongodb Con Pymongo

Python

Acceso A Bases De Datos

Acceso A Mysql Con Mysql Connector

Python

Acceso A Bases De Datos

Novedades Python 3.13

Python

Características Modernas

Operador Walrus

Python

Características Modernas

Pattern Matching

Python

Características Modernas

Instalación Beautiful Soup

Python

Web Scraping

Sintaxis General De Beautiful Soup

Python

Web Scraping

Tipos De Selectores

Python

Web Scraping

Web Scraping De Html

Python

Web Scraping

Web Scraping Para Ciencia De Datos

Python

Web Scraping

Autenticación Y Acceso A Recursos Protegidos

Python

Web Scraping

Combinación De Selenium Con Beautiful Soup

Python

Web Scraping

Accede GRATIS a Python y certifícate

Ejercicios de programación de Python

Evalúa tus conocimientos de esta lección Sintaxis general de Beautiful Soup con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Módulo math

Python
Puzzle

Reto herencia

Python
Código

Excepciones

Python
Test

Introducción a Python

Python
Test

Reto variables

Python
Código

Funciones Python

Python
Puzzle

Reto funciones

Python
Código

Módulo datetime

Python
Test

Reto acumulación

Python
Código

Reto estructuras condicionales

Python
Código

Polimorfismo

Python
Test

Módulo os

Python
Test

Reto métodos dunder

Python
Código

Diccionarios

Python
Puzzle

Reto clases y objetos

Python
Código

Reto operadores

Python
Código

Operadores

Python
Test

Estructuras de control

Python
Puzzle

Funciones lambda

Python
Test

Reto diccionarios

Python
Código

Reto función lambda

Python
Código

Encapsulación

Python
Puzzle

Reto coleciones

Python
Proyecto

Reto funciones auxiliares

Python
Código

Crear módulos y paquetes

Python
Puzzle

Módulo datetime

Python
Puzzle

Excepciones

Python
Puzzle

Operadores

Python
Puzzle

Diccionarios

Python
Test

Reto map, filter

Python
Código

Reto tuplas

Python
Código

Proyecto gestor de tareas CRUD

Python
Proyecto

Tuplas

Python
Puzzle

Variables

Python
Puzzle

Tipos de datos

Python
Puzzle

Conjuntos

Python
Test

Reto mixins

Python
Código

Módulo csv

Python
Test

Módulo json

Python
Test

Herencia

Python
Test

Análisis de datos de ventas con Pandas

Python
Proyecto

Reto fechas y tiempo

Python
Proyecto

Reto estructuras de iteración

Python
Código

Funciones

Python
Test

Reto comprehensions

Python
Código

Variables

Python
Test

Reto serialización

Python
Proyecto

Módulo csv

Python
Puzzle

Reto polimorfismo

Python
Código

Polimorfismo

Python
Puzzle

Clases y objetos

Python
Código

Reto encapsulación

Python
Código

Estructuras de control

Python
Test

Importar módulos y paquetes

Python
Test

Módulo math

Python
Test

Funciones lambda

Python
Puzzle

Reto excepciones

Python
Código

Listas

Python
Puzzle

Reto archivos

Python
Proyecto

Encapsulación

Python
Test

Reto conjuntos

Python
Código

Clases y objetos

Python
Test

Instalación de Python y creación de proyecto

Python
Test

Reto listas

Python
Código

Tipos de datos

Python
Test

Crear módulos y paquetes

Python
Test

Tuplas

Python
Test

Herencia

Python
Puzzle

Reto acceso a sistema

Python
Proyecto

Proyecto sintaxis calculadora

Python
Proyecto

Importar módulos y paquetes

Python
Puzzle

Clases y objetos

Python
Puzzle

Módulo os

Python
Puzzle

Listas

Python
Test

Conjuntos

Python
Puzzle

Reto tipos de datos

Python
Código

Reto matemáticas

Python
Proyecto

Módulo json

Python
Puzzle

En esta lección

Objetivos de aprendizaje de esta lección

  • Crear objetos BeautifulSoup a partir de documentos HTML.
  • Navegar por el árbol DOM: padres, hijos y hermanos.
  • Acceder y modificar atributos y contenidos de etiquetas HTML.
  • Utilizar los métodos find() y find_all() para buscar elementos.
  • Manejar y extraer texto y comentarios en HTML.