Python
Tutorial Python: Web Scraping de HTML
Beautiful Soup y web scraping de HTML. Aprende a extraer enlaces, tablas e imágenes de manera eficiente mejorando tus proyectos de scraping.
Aprende Python y certifícateExtracción de enlaces y URLs
Una de las tareas más comunes en el web scraping es la extracción de enlaces y sus URLs de un documento HTML. Con Beautiful Soup, este proceso se simplifica gracias a sus métodos de navegación y búsqueda en el árbol DOM.
Para obtener todos los enlaces de una página, se utiliza el método find_all()
buscando las etiquetas <a>
, que representan los enlaces en HTML:
from bs4 import BeautifulSoup
html_doc = """
<html>
<head><title>Página de ejemplo</title></head>
<body>
<p>Enlaces útiles:</p>
<a href="https://www.ejemplo.com">Ejemplo</a>
<a href="https://www.prueba.com">Prueba</a>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
enlaces = soup.find_all('a')
En este código, hemos creado un objeto BeautifulSoup
y recopilado todos los enlaces en la variable enlaces
. Cada elemento en enlaces
es un objeto Tag
que representa una etiqueta <a>
del documento.
Para extraer las URLs de estos enlaces, accedemos al atributo href
de cada elemento:
for enlace in enlaces:
url = enlace.get('href')
texto = enlace.text
print(f"Texto: {texto}, URL: {url}")
Este bucle recorrerá cada enlace, obteniendo tanto el texto visible como la URL asociada. El método get()
es seguro, ya que si el atributo no existe, devolverá None
en lugar de causar un error.
Es posible filtrar enlaces que cumplan ciertas condiciones. Por ejemplo, si deseamos obtener solo los enlaces que apuntan a dominios específicos:
import re
enlaces_ejemplo = soup.find_all('a', href=re.compile(r'ejemplo\.com'))
for enlace in enlaces_ejemplo:
print(enlace.get('href'))
Aquí utilizamos el módulo re
para emplear expresiones regulares en la búsqueda, permitiendo localizar enlaces cuyo atributo href
contenga "ejemplo.com".
Además, podemos buscar enlaces con una clase o identificador específico:
html_doc = """
<html>
<body>
<a href="https://www.ejemplo.com" class="importante">Enlace Importante</a>
<a href="https://www.otro.com">Otro Enlace</a>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
enlace_importante = soup.find('a', class_='importante')
print(enlace_importante.get('href'))
Nótese que utilizamos class_
en lugar de class
debido a que class
es una palabra reservada en Python. De esta manera, podemos acceder a enlaces con una clase específica.
También es posible utilizar selectores CSS para una búsqueda más avanzada:
enlaces = soup.select('a.importante')
for enlace in enlaces:
print(enlace['href'])
El método select()
permite utilizar selectores CSS, como en este caso que seleccionamos todas las etiquetas <a>
con la clase "importante".
Si necesitamos extraer todos los enlaces absolutos de una página, es importante tener en cuenta si las URLs son relativas. Para convertirlas en absolutas, podemos utilizar la librería urllib.parse
:
from urllib.parse import urljoin
base_url = 'https://www.ejemplo.com'
for enlace in enlaces:
url = urljoin(base_url, enlace.get('href'))
print(url)
Con urljoin()
, combinamos la URL base con el valor del atributo href
, obteniendo así la URL completa.
La extracción de enlaces y URLs con Beautiful Soup es un proceso sencillo y eficiente. Gracias a sus métodos de búsqueda y navegación, podemos personalizar nuestras búsquedas y extraer la información necesaria de manera precisa.
Manejo de tablas y listas en HTML
El web scraping a menudo implica la extracción de información de tablas y listas presentes en páginas web. Beautiful Soup ofrece herramientas eficientes para navegar y extraer datos estructurados de estas etiquetas HTML.
Las tablas en HTML se definen con la etiqueta <table>
y se componen de filas (<tr>
) y celdas (<td>
para datos y <th>
para encabezados). Para extraer información de una tabla, primero localizamos la tabla de interés y luego iteramos sobre sus filas y celdas.
Por ejemplo, dado el siguiente fragmento de HTML:
<table id="tabla_datos">
<tr>
<th>Nombre</th>
<th>Edad</th>
</tr>
<tr>
<td>Ana</td>
<td>28</td>
</tr>
<tr>
<td>Luis</td>
<td>34</td>
</tr>
</table>
Podemos extraer los datos de la tabla utilizando el siguiente código:
from bs4 import BeautifulSoup
html_doc = '''
<table id="tabla_datos">
<tr>
<th>Nombre</th>
<th>Edad</th>
</tr>
<tr>
<td>Ana</td>
<td>28</td>
</tr>
<tr>
<td>Luis</td>
<td>34</td>
</tr>
</table>
'''
soup = BeautifulSoup(html_doc, 'html.parser')
tabla = soup.find('table', id='tabla_datos')
filas = tabla.find_all('tr')
for fila in filas:
celdas = fila.find_all(['th', 'td'])
datos = [celda.get_text(strip=True) for celda in celdas]
print(datos)
En este ejemplo, localizamos la tabla con id='tabla_datos'
y luego extraemos todas las filas. Para cada fila, obtenemos las celdas y extraemos el texto de cada una, obteniendo una lista de datos por fila.
Para manejar listas en HTML, que se definen con <ul>
(lista no ordenada) y <ol>
(lista ordenada), el proceso es similar. Consideremos el siguiente ejemplo:
<ul class="lista-elementos">
<li>Elemento 1</li>
<li>Elemento 2</li>
<li>Elemento 3</li>
</ul>
El código para extraer los elementos de la lista sería:
lista = soup.find('ul', class_='lista-elementos')
items = lista.find_all('li')
for item in items:
texto = item.get_text(strip=True)
print(texto)
Aquí, buscamos la lista con la clase 'lista-elementos' y luego iteramos sobre cada elemento <li>
, extrayendo su texto.
Cuando trabajamos con tablas más complejas, es posible que necesitemos manejar celdas combinadas (rowspan
y colspan
). Aunque Beautiful Soup no procesa automáticamente estas propiedades, podemos escribir lógica adicional para interpretarlas correctamente.
Para extraer datos específicos de una tabla, podemos utilizar selectores CSS:
celdas_edad = tabla.select('tr td:nth-of-type(2)')
for celda in celdas_edad:
edad = celda.get_text(strip=True)
print(edad)
Este código selecciona todas las celdas que contienen la edad, utilizando el selector nth-of-type(2)
para obtener el segundo <td>
de cada fila.
Al manejar listas anidadas, es importante considerar la estructura jerárquica. Por ejemplo:
<ul class="menu">
<li>
Opción 1
<ul>
<li>Subopción 1.1</li>
<li>Subopción 1.2</li>
</ul>
</li>
<li>Opción 2</li>
</ul>
Para extraer todos los elementos, incluyendo los anidados, podemos utilizar una función recursiva:
def extraer_items(lista):
items = lista.find_all('li', recursive=False)
for item in items:
texto = item.contents[0].strip()
print(texto)
sublista = item.find('ul')
if sublista:
extraer_items(sublista)
menu = soup.find('ul', class_='menu')
extraer_items(menu)
Este código primero imprime el texto de cada elemento <li>
y luego verifica si contiene una sublista <ul>
, llamando a la función de nuevo si es así.
Si deseamos convertir los datos de una tabla en un diccionario o lista de registros, podemos hacerlo de la siguiente manera:
cabeceras = [th.get_text(strip=True) for th in tabla.find_all('th')]
registros = []
for fila in tabla.find_all('tr')[1:]:
celdas = fila.find_all('td')
valores = [celda.get_text(strip=True) for celda in celdas]
registro = dict(zip(cabeceras, valores))
registros.append(registro)
print(registros)
Este enfoque es útil para estructurar los datos y facilitar su posterior manipulación o almacenamiento.
Es fundamental prestar atención a los detalles, como los espacios en blanco y los caracteres especiales, utilizando métodos como get_text(strip=True)
para obtener el texto limpio de las etiquetas.
Al extraer datos de listas y tablas, podemos combinar Beautiful Soup con otras librerías, como pandas, para procesar y analizar la información:
import pandas as pd
df = pd.DataFrame(registros)
print(df)
Esto nos permite convertir nuestros datos en un DataFrame, facilitando operaciones de análisis y visualización.
Descarga y procesamiento de imágenes y multimedia
En el proceso de web scraping, es común encontrar la necesidad de extraer y descargar imágenes u otros contenidos multimedia de páginas web. Beautiful Soup facilita la localización y extracción de estas etiquetas en el código HTML, permitiéndonos obtener las URLs para su posterior descarga y procesamiento.
Para extraer todas las imágenes de una página web, buscamos las etiquetas <img>
, que representan las imágenes en HTML:
from bs4 import BeautifulSoup
html_doc = '''
<html>
<body>
<h1>Galería de Imágenes</h1>
<img src="imagen1.jpg" alt="Imagen 1">
<img src="/media/imagen2.png" alt="Imagen 2">
<img src="https://www.ejemplo.com/imagenes/imagen3.gif" alt="Imagen 3">
</body>
</html>
'''
soup = BeautifulSoup(html_doc, 'html.parser')
imagenes = soup.find_all('img')
En este código, utilizamos find_all('img')
para obtener una lista de todas las etiquetas <img>
presentes en el documento. Cada elemento en imagenes
es un objeto Tag
que representa una imagen específica.
Para extraer las URLs de las imágenes, accedemos al atributo src
de cada etiqueta:
for img in imagenes:
url_imagen = img.get('src')
texto_alt = img.get('alt')
print(f"Texto alternativo: {texto_alt}, URL de la imagen: {url_imagen}")
Este bucle nos permite obtener tanto la URL de la imagen como su texto alternativo. Es recomendable utilizar get()
en lugar de acceder directamente al atributo, ya que así evitamos errores si el atributo no existe.
Es habitual que las URLs de las imágenes sean relativas, por lo que necesitamos convertirlas en URLs absolutas para poder descargarlas correctamente. Para ello, empleamos la función urljoin
del módulo urllib.parse
:
from urllib.parse import urljoin
base_url = 'https://www.ejemplo.com/'
for img in imagenes:
url_relativa = img.get('src')
url_absoluta = urljoin(base_url, url_relativa)
print(f"URL absoluta de la imagen: {url_absoluta}")
Con urljoin
, combinamos la URL base con la ruta relativa de la imagen, obteniendo la URL completa necesaria para su descarga.
Para descargar las imágenes, utilizamos la biblioteca requests:
import requests
for img in imagenes:
url_relativa = img.get('src')
url_absoluta = urljoin(base_url, url_relativa)
nombre_imagen = url_absoluta.split('/')[-1]
respuesta = requests.get(url_absoluta)
if respuesta.status_code == 200:
with open(nombre_imagen, 'wb') as archivo:
archivo.write(respuesta.content)
print(f"Imagen {nombre_imagen} descargada correctamente.")
else:
print(f"Error al descargar {nombre_imagen}")
En este ejemplo, por cada imagen:
- Construimos la URL absoluta de la imagen.
- Extraemos el nombre del archivo a partir de la URL.
- Realizamos una petición
GET
para descargar la imagen. - Si la respuesta es exitosa (
status_code
200), guardamos el contenido en un archivo binario. - Informamos si hubo algún error durante la descarga.
Para manejar otros tipos de contenido multimedia, como videos o audios, el proceso es similar. Las etiquetas <video>
y <audio>
también contienen un atributo src
o tienen etiquetas <source>
anidadas:
# Extraer y descargar videos
videos = soup.find_all('video')
for video in videos:
fuente = video.find('source')
if fuente:
url_relativa = fuente.get('src')
else:
url_relativa = video.get('src')
if url_relativa:
url_absoluta = urljoin(base_url, url_relativa)
nombre_video = url_absoluta.split('/')[-1]
respuesta = requests.get(url_absoluta)
if respuesta.status_code == 200:
with open(nombre_video, 'wb') as archivo:
archivo.write(respuesta.content)
print(f"Video {nombre_video} descargado correctamente.")
else:
print(f"Error al descargar {nombre_video}")
Aquí, buscamos primero si existe una etiqueta <source>
dentro del <video>
. Si no, utilizamos el atributo src
directamente del <video>
. Luego, procedemos de la misma manera que con las imágenes.
Para archivos multimedia de gran tamaño, es recomendable descargar el contenido en streaming para no saturar la memoria del sistema:
for img in imagenes:
url_relativa = img.get('src')
url_absoluta = urljoin(base_url, url_relativa)
nombre_imagen = url_absoluta.split('/')[-1]
with requests.get(url_absoluta, stream=True) as respuesta:
if respuesta.status_code == 200:
with open(nombre_imagen, 'wb') as archivo:
for trozo in respuesta.iter_content(chunk_size=8192):
archivo.write(trozo)
print(f"Imagen {nombre_imagen} descargada en streaming correctamente.")
else:
print(f"Error al descargar {nombre_imagen}")
Este método descarga el archivo en fragmentos pequeños, escribiendo cada trozo directamente en el archivo y evitando cargar todo el contenido en memoria.
Es esencial implementar un correcto adecuado de excepciones para gestionar posibles errores durante la descarga:
for img in imagenes:
try:
url_relativa = img.get('src')
url_absoluta = urljoin(base_url, url_relativa)
nombre_imagen = url_absoluta.split('/')[-1]
respuesta = requests.get(url_absoluta)
respuesta.raise_for_status()
with open(nombre_imagen, 'wb') as archivo:
archivo.write(respuesta.content)
print(f"Imagen {nombre_imagen} descargada exitosamente.")
except requests.exceptions.RequestException as e:
print(f"Error al descargar {nombre_imagen}: {e}")
Al utilizar respuesta.raise_for_status()
, provocamos una excepción si la petición HTTP no fue exitosa, lo que nos permite capturar y manejar el error correctamente.
Además de descargar, podemos procesar las imágenes utilizando librerías como Pillow:
from PIL import Image
from io import BytesIO
for img in imagenes:
try:
url_relativa = img.get('src')
url_absoluta = urljoin(base_url, url_relativa)
respuesta = requests.get(url_absoluta)
respuesta.raise_for_status()
imagen = Image.open(BytesIO(respuesta.content))
imagen = imagen.convert('L') # Convertir a escala de grises
nombre_imagen = url_absoluta.split('/')[-1]
imagen.save(f"gris_{nombre_imagen}")
print(f"Imagen {nombre_imagen} procesada y guardada como gris_{nombre_imagen}.")
except Exception as e:
print(f"Error al procesar {nombre_imagen}: {e}")
En este caso, después de descargar la imagen, la convertimos a escala de grises y la guardamos con un nombre distinto, demostrando cómo podemos manipular imágenes tras su descarga.
Para asegurarnos de que todas las descargas y procesos se realizan de manera responsable, es importante:
- Respetar los términos y condiciones del sitio web.
- Validar que tenemos permiso para descargar y utilizar el contenido multimedia.
- Implementar pausas entre las descargas para no sobrecargar el servidor:
import time
for img in imagenes:
# Código de descarga...
time.sleep(1) # Esperar 1 segundo entre descargas
Finalmente, al trabajar con contenido multimedia, debemos estar atentos a los metadatos y otros atributos que pueden ser de interés:
for img in imagenes:
titulo = img.get('title')
clase = img.get('class')
print(f"Imagen con título: {titulo}, clase: {clase}")
La extracción de estos atributos nos permite obtener información adicional sobre las imágenes, lo cual puede ser útil en diferentes contextos.
Gestión de contenido dinámico y JavaScript básico
Al realizar web scraping, es común enfrentarse a páginas web cuyo contenido es generado dinámicamente mediante JavaScript. Beautiful Soup, al procesar el HTML estático obtenido de la respuesta HTTP inicial, no ejecuta JavaScript. Por ello, es necesario emplear estrategias para extraer la información deseada de este tipo de páginas.
Una técnica eficaz es analizar las peticiones de red que realiza la página al cargar el contenido dinámico. Muchas veces, los datos se obtienen a través de solicitudes XHR o fetch a APIs que devuelven información en formato JSON. Utilizando herramientas de desarrollo del navegador, como la pestaña "Red" (o Network), podemos identificar estas peticiones y obtener sus URL.
Por ejemplo, si una página carga una lista de productos mediante una petición a una API, podemos replicar esta solicitud:
import requests
url_api = 'https://www.ejemplo.com/api/productos'
respuesta = requests.get(url_api)
datos = respuesta.json()
for producto in datos['items']:
nombre = producto['nombre']
precio = producto['precio']
print(f"Producto: {nombre}, Precio: {precio}")
Aquí, realizamos una petición directa a la API y procesamos la respuesta JSON, facilitando la extracción de datos sin necesidad de ejecutar JavaScript.
Otra estrategia es extraer los datos embebidos dentro de etiquetas <script>
en el HTML. Algunas páginas incluyen variables JavaScript que contienen información útil. Podemos localizar estas etiquetas y extraer el contenido relevante:
from bs4 import BeautifulSoup
import json
import re
html_doc = '''
<html>
<head></head>
<body>
<script type="text/javascript">
window.datosProductos = {
"items": [
{"nombre": "Producto A", "precio": 25},
{"nombre": "Producto B", "precio": 30}
]
};
</script>
</body>
</html>
'''
soup = BeautifulSoup(html_doc, 'html.parser')
script = soup.find('script', text=re.compile('window\.datosProductos'))
contenido = script.string
json_texto = re.search(r'window\.datosProductos\s*=\s*(\{.*\});', contenido, re.DOTALL).group(1)
datos = json.loads(json_texto)
for producto in datos['items']:
nombre = producto['nombre']
precio = producto['precio']
print(f"Producto: {nombre}, Precio: {precio}")
En este caso, utilizamos expresiones regulares para extraer el objeto JSON de la variable JavaScript y luego lo procesamos con el módulo json.
Cuando los datos se cargan mediante solicitudes POST o GET con parámetros específicos, podemos simular estas peticiones para acceder al contenido:
import requests
url_busqueda = 'https://www.ejemplo.com/buscar'
parametros = {'q': 'ordenadores', 'categoria': 'tecnologia'}
respuesta = requests.get(url_busqueda, params=parametros)
soup = BeautifulSoup(respuesta.text, 'html.parser')
productos = soup.find_all('div', class_='producto-item')
for producto in productos:
titulo = producto.find('h3').get_text(strip=True)
precio = producto.find('span', class_='precio').get_text(strip=True)
print(f"Título: {titulo}, Precio: {precio}")
Al incluir los parámetros de búsqueda adecuados, obtenemos el HTML con los resultados que nos interesan y podemos extraer la información utilizando Beautiful Soup.
Es esencial considerar las cabeceras HTTP al realizar peticiones. Algunas páginas responden de manera diferente según el User-Agent o requieren ciertas cabeceras para devolver el contenido correcto:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Accept-Language': 'es-ES,es;q=0.9'
}
respuesta = requests.get(url_busqueda, params=parametros, headers=headers)
Estableciendo las cabeceras apropiadas, podemos emular el comportamiento de un navegador real y mejorar el éxito de nuestras peticiones.
En situaciones donde el contenido dinámico es complejo, puede ser útil revisar si la página utiliza frameworks como React o Vue.js. A veces, estos frameworks incluyen los datos en forma de render props o atributos de datos en las etiquetas, que podemos aprovechar:
<div id="root" data-inicial='{"usuario":"Juan","edad":30}'></div>
Podemos extraer este atributo y cargarlo como JSON:
div = soup.find('div', id='root')
data_inicial = div.get('data-inicial')
datos = json.loads(data_inicial)
print(f"Usuario: {datos['usuario']}, Edad: {datos['edad']}")
Al acceder a los atributos de datos, obtenemos información directamente sin necesidad de procesar el contenido generado por JavaScript.
Otra opción es aprovechar los sitemaps o archivos robots.txt de los sitios web, que a veces contienen enlaces directos a recursos o APIs útiles para la extracción de datos.
Es importante mantener una actitud ética y responsable al realizar web scraping. Debemos respetar los términos de servicio y las normativas legales aplicables, evitando acceder a información no autorizada o sensible.
Para mejorar la eficiencia de nuestro código, es recomendable implementar cacheo de solicitudes y manejar adecuadamente las excepciones:
try:
respuesta = requests.get(url_api, timeout=5)
respuesta.raise_for_status()
except requests.exceptions.Timeout:
print("La solicitud ha excedido el tiempo de espera.")
except requests.exceptions.HTTPError as err:
print(f"Error HTTP: {err}")
Manejando las posibles excepciones, nuestro programa será más robusto y podrá gestionar errores sin detener su ejecución.
Finalmente, aunque Beautiful Soup no ejecuta JavaScript, combinándolo con estas técnicas podemos extraer gran parte del contenido dinámico de las páginas web. La clave es entender cómo se carga la información y encontrar formas de acceder a ella mediante peticiones directas o analizando el HTML estático disponible.
Resolución de codificaciones y caracteres especiales
Al realizar web scraping, es frecuente encontrarse con problemas relacionados con las codificaciones de caracteres y la gestión de caracteres especiales. Las páginas web pueden utilizar diferentes codificaciones, como UTF-8, ISO-8859-1 o Windows-1252, lo que puede causar que el texto extraído contenga caracteres ilegibles o símbolos extraños si no se maneja adecuadamente.
Para asegurar que Beautiful Soup interprete correctamente el contenido de la página, es fundamental gestionar la codificación de manera correcta. Cuando se utiliza la biblioteca requests
para obtener el contenido HTML, esta intenta detectar la codificación automáticamente, pero no siempre es precisa.
Por ejemplo:
import requests
from bs4 import BeautifulSoup
url = 'https://www.ejemplo.com'
respuesta = requests.get(url)
contenido = respuesta.content
soup = BeautifulSoup(contenido, 'html.parser')
texto = soup.get_text()
En este caso, el objeto respuesta
contiene los datos de la página web. Sin embargo, si la codificación no se detecta correctamente, el texto extraído puede contener errores. Para evitar esto, podemos establecer explícitamente la codificación antes de procesar el contenido:
respuesta.encoding = 'utf-8'
soup = BeautifulSoup(respuesta.text, 'html.parser')
Al asignar 'utf-8'
a respuesta.encoding
, indicamos a requests que interprete el contenido utilizando dicha codificación, facilitando que Beautiful Soup procese correctamente los caracteres especiales.
En algunas ocasiones, es útil verificar cuál es la codificación detectada por requests
:
print(respuesta.apparent_encoding)
Este atributo muestra la codificación que requests ha inferido. Podemos utilizar esta información para ajustar la codificación si es necesario.
Además, al crear el objeto BeautifulSoup
, podemos especificar la codificación mediante el parámetro from_encoding
:
soup = BeautifulSoup(contenido, 'html.parser', from_encoding='utf-8')
Es importante notar que Beautiful Soup suele manejar automáticamente la detección de codificaciones, y en versiones recientes este parámetro puede ser menos necesario.
Si trabajamos con páginas que declaran una codificación incorrecta en sus metadatos, podemos utilizar la biblioteca chardet
para detectar la codificación real:
import chardet
detector = chardet.detect(contenido)
codificacion = detector['encoding']
print(f'Codificación detectada: {codificacion}')
Con la codificación detectada, podemos decodificar el contenido y procesarlo:
contenido_decodificado = contenido.decode(codificacion, errors='replace')
soup = BeautifulSoup(contenido_decodificado, 'html.parser')
El parámetro errors='replace'
sustituye los caracteres que no pueden ser decodificados, evitando que el proceso falle.
Al extraer texto que contiene caracteres especiales como acentos, eñes o símbolos, es crucial asegurar que estos se manejen correctamente. Por ejemplo, al escribir el contenido en un archivo:
with open('contenido.txt', 'w', encoding='utf-8') as archivo:
archivo.write(soup.get_text())
Al especificar encoding='utf-8'
en la función open
, nos aseguramos de que el texto se guarde con la codificación adecuada, preservando los caracteres especiales.
Cuando nos encontramos con entidades HTML, como á
para á
, Beautiful Soup las maneja automáticamente y las decodifica al carácter correspondiente. Sin embargo, si necesitamos acceder a las entidades, podemos utilizar el módulo html
:
import html
texto_bruto = soup.prettify()
texto_con_entidades = html.escape(texto_bruto)
Con html.escape()
, convertimos los caracteres especiales a sus entidades HTML correspondientes.
En caso de que el contenido incluya secuencias de escape o caracteres Unicode, podemos normalizarlos utilizando el módulo unicodedata
:
import unicodedata
texto = soup.get_text()
texto_normalizado = unicodedata.normalize('NFKD', texto)
La función normalize()
nos permite convertir caracteres compuestos en sus equivalentes descompuestos, facilitando el procesamiento y comparación de textos.
Es posible que algunos textos contengan caracteres no imprimibles o espacios en blanco especiales que pueden afectar al análisis de datos. Para limpiar estos caracteres, podemos aplicar expresiones regulares:
import re
texto_limpio = re.sub(r'\s+', ' ', texto).strip()
Este código reemplaza múltiples espacios en blanco por un solo espacio, y elimina espacios al inicio y al final con strip()
.
Al trabajar con diferentes codificaciones, es fundamental estar atentos a las excepciones que puedan surgir. Por ejemplo, si intentamos decodificar con una codificación incorrecta, obtendremos un UnicodeDecodeError
. Para manejar estas situaciones, podemos utilizar bloques try-except
:
try:
contenido_decodificado = contenido.decode('utf-8')
except UnicodeDecodeError:
contenido_decodificado = contenido.decode('latin-1', errors='replace')
De esta forma, si la decodificación con 'utf-8'
falla, intentamos con 'latin-1'
, reemplazando los caracteres problemáticos.
Ejercicios de esta lección Web Scraping de HTML
Evalúa tus conocimientos de esta lección Web Scraping de HTML con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Diccionarios en Python
Módulo math
Excepciones
Gestor de tareas CRUD
Funciones Python
Módulo datetime
Polimorfismo
Módulo os
Diccionarios
Operadores
Estructuras de control
Instalación de Python y creación de proyecto
Estructuras de control
Encapsulación
Herencia de clases
Crear módulos y paquetes
Módulo datetime
Excepciones
Operadores
Funciones lambda
Diccionarios
Funciones lambda
Tuplas
Operadores
Variables
Tipos de datos
Conjuntos
Módulo csv
Módulo json
Tipos de datos
Herencia
Análisis de datos de ventas con Pandas
Funciones
Funciones Python
Variables
Módulo csv
Introducción a Python
Polimorfismo
Clases y objetos
Listas
Estructuras de control
Importar módulos y paquetes
Módulo math
OOP en python
Listas
Encapsulación
Clases y objetos
Tipos de datos
Crear módulos y paquetes
Tuplas
Herencia
Importar módulos y paquetes
Clases y objetos
Módulo os
Listas
Conjuntos
Módulo json
Todas las 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 Y Entorno
Instalación Y Creación De Proyecto
Introducción Y Entorno
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Funciones Lambda
Programación Funcional
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
Listas
Estructuras De Datos
Tuplas
Estructuras De Datos
Diccionarios
Estructuras De Datos
Conjuntos
Estructuras De Datos
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
Importar Módulos Y Paquetes
Paquetes Y Módulos
Crear Módulos Y Paquetes
Paquetes Y Módulos
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
Acceso A Datos Con Mysql, Pymongo Y Pandas
Acceso A Bases De Datos
Certificados de superación de Python
Supera todos los ejercicios de programación del curso de Python y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender cómo obtener enlaces y URLs de páginas HTML.
- Aprender a extraer datos de tablas y listas.
- Manejo de imágenes y contenido multimedia.
- Técnicas para gestionar contenido dinámico y JavaScript básico.
- Resolver problemas de codificación y caracteres especiales.