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ícateCreació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.
Navegación del árbol DOM: padres, hijos y hermanos
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, requierelxml
)'html5lib'
(muy tolerante, requierehtml5lib
)
- Ejemplo básico:
- 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
otag.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
- Hijos:
- Acceso directo por etiqueta
- 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 conid="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)
(envuelvetag
dentro dewrapper_tag
)tag.unwrap()
(elimina la etiqueta, conservando el contenido)
- Limpiar contenido interno
tag.clear()
(vacía el contenido de la etiqueta)
- Modificar texto o nodos
- 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
- Ej:
**Comment**
(nodo de comentario<!-- ... -->
)- Se maneja similar a un texto, pero es un tipo distinto (
Comment
).
- Se maneja similar a un texto, pero es un tipo distinto (
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
Introducción
Instalación Y Creación De Proyecto
Introducción
Tema 2: Tipos De Datos, Variables Y Operadores
Introducción
Instalación De Python
Introducción
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Estructuras Control Iterativo
Sintaxis
Estructuras Control Condicional
Sintaxis
Testing Con Pytest
Sintaxis
Listas
Estructuras De Datos
Tuplas
Estructuras De Datos
Diccionarios
Estructuras De Datos
Conjuntos
Estructuras De Datos
Comprehensions
Estructuras De Datos
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Mixins Y Herencia Múltiple
Programación Orientada A Objetos
Métodos Especiales (Dunder Methods)
Programación Orientada A Objetos
Composición De Clases
Programación Orientada A Objetos
Funciones Lambda
Programación Funcional
Aplicación Parcial
Programación Funcional
Entrada Y Salida, Manejo De Archivos
Programación Funcional
Decoradores
Programación Funcional
Generadores
Programación Funcional
Paradigma Funcional
Programación Funcional
Composición De Funciones
Programación Funcional
Funciones Orden Superior Map Y Filter
Programación Funcional
Funciones Auxiliares
Programación Funcional
Reducción Y Acumulación
Programación Funcional
Archivos Comprimidos
Entrada Y Salida Io
Entrada Y Salida Avanzada
Entrada Y Salida Io
Archivos Temporales
Entrada Y Salida Io
Contexto With
Entrada Y Salida Io
Módulo Csv
Biblioteca Estándar
Módulo Json
Biblioteca Estándar
Módulo Datetime
Biblioteca Estándar
Módulo Math
Biblioteca Estándar
Módulo Os
Biblioteca Estándar
Módulo Re
Biblioteca Estándar
Módulo Random
Biblioteca Estándar
Módulo Time
Biblioteca Estándar
Módulo Collections
Biblioteca Estándar
Módulo Sys
Biblioteca Estándar
Módulo Statistics
Biblioteca Estándar
Módulo Pickle
Biblioteca Estándar
Módulo Pathlib
Biblioteca Estándar
Importar Módulos Y Paquetes
Paquetes Y Módulos
Crear Módulos Y Paquetes
Paquetes Y Módulos
Entornos Virtuales (Virtualenv, Venv)
Entorno Y Dependencias
Gestión De Dependencias (Pip, Requirements.txt)
Entorno Y Dependencias
Python-dotenv Y Variables De Entorno
Entorno Y Dependencias
Acceso A Datos Con Mysql, Pymongo Y Pandas
Acceso A Bases De Datos
Acceso A Mongodb Con Pymongo
Acceso A Bases De Datos
Acceso A Mysql Con Mysql Connector
Acceso A Bases De Datos
Novedades Python 3.13
Características Modernas
Operador Walrus
Características Modernas
Pattern Matching
Características Modernas
Instalación Beautiful Soup
Web Scraping
Sintaxis General De Beautiful Soup
Web Scraping
Tipos De Selectores
Web Scraping
Web Scraping De Html
Web Scraping
Web Scraping Para Ciencia De Datos
Web Scraping
Autenticación Y Acceso A Recursos Protegidos
Web Scraping
Combinación De Selenium Con Beautiful Soup
Web Scraping
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
Reto herencia
Excepciones
Introducción a Python
Reto variables
Funciones Python
Reto funciones
Módulo datetime
Reto acumulación
Reto estructuras condicionales
Polimorfismo
Módulo os
Reto métodos dunder
Diccionarios
Reto clases y objetos
Reto operadores
Operadores
Estructuras de control
Funciones lambda
Reto diccionarios
Reto función lambda
Encapsulación
Reto coleciones
Reto funciones auxiliares
Crear módulos y paquetes
Módulo datetime
Excepciones
Operadores
Diccionarios
Reto map, filter
Reto tuplas
Proyecto gestor de tareas CRUD
Tuplas
Variables
Tipos de datos
Conjuntos
Reto mixins
Módulo csv
Módulo json
Herencia
Análisis de datos de ventas con Pandas
Reto fechas y tiempo
Reto estructuras de iteración
Funciones
Reto comprehensions
Variables
Reto serialización
Módulo csv
Reto polimorfismo
Polimorfismo
Clases y objetos
Reto encapsulación
Estructuras de control
Importar módulos y paquetes
Módulo math
Funciones lambda
Reto excepciones
Listas
Reto archivos
Encapsulación
Reto conjuntos
Clases y objetos
Instalación de Python y creación de proyecto
Reto listas
Tipos de datos
Crear módulos y paquetes
Tuplas
Herencia
Reto acceso a sistema
Proyecto sintaxis calculadora
Importar módulos y paquetes
Clases y objetos
Módulo os
Listas
Conjuntos
Reto tipos de datos
Reto matemáticas
Módulo json
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()
yfind_all()
para buscar elementos. - Manejar y extraer texto y comentarios en HTML.