Guía paso a paso de Python para principiantes en raspado web

Comentarios: 0

Python destaca como la mejor opción para el web scraping debido a sus sólidas bibliotecas y sintaxis sencilla. En este artículo, exploraremos los fundamentos del web scraping y le guiaremos en la configuración de su entorno Python para crear su primer web scraper. Le presentaremos las principales bibliotecas de Python adecuadas para tareas de scraping, como Beautiful Soup, Playwright y lxml.

Bibliotecas Python para web scraping

Python proporciona varias bibliotecas para facilitar el web scraping. Éstas son algunas de las más utilizadas:

  • requests: una librería HTTP simple y elegante para Python, utilizada para enviar peticiones HTTP para obtener páginas web.
  • Beautiful Soup: ideal para analizar documentos HTML y XML. Crea árboles de análisis a partir del código fuente de la página que facilitan la extracción de datos.
  • lxml: conocido por su rapidez y eficacia, lxml es excelente para analizar documentos XML y HTML.
  • Playwright: una herramienta robusta para el scraping de contenidos dinámicos y la interacción con páginas web.

Introducción a las peticiones HTTP

HTTP (HyperText Transfer Protocol) es un protocolo de capa de aplicación para la transferencia de datos a través de la web. Usted escribe una URL en el navegador, y éste genera una petición HTTP y la envía al servidor web. A continuación, el servidor devuelve al navegador la respuesta HTTP, que se muestra en forma de página HTML. Para el web scraping, necesitas imitar este proceso y generar peticiones HTTP desde tu script para obtener el contenido HTTP de las páginas web mediante programación.

Cómo configurar el entorno

En primer lugar, asegúrate de que tienes Python instalado en tu sistema. Puedes descargarlo desde la web oficial de Python.

Un entorno virtual ayuda a gestionar las dependencias. Utiliza estos comandos para crear y activar un entorno virtual:


python -m venv scraping_env
source scraping_env/bin/activate

A continuación, instale los paquetes necesarios utilizando los siguientes comandos:


pip install requests
pip install beautifulsoup4 
pip install lxml

Construyendo web scraper con Beautiful Soup

Empecemos con un simple web scraper usando la petición para scrapear contenido HTML estático.

Haciendo petición HTTP GET

El tipo más común de solicitud HTTP es la solicitud GET, que se utiliza para recuperar datos de una URL especificada. A continuación se muestra un ejemplo básico de cómo realizar una petición GET a http://example.com.


import requests
url = 'http://example.com'
response = requests.get(url)

Manejo de respuestas HTTP

La librería requests proporciona varias formas de manejar y procesar la respuesta:

Comprobar código de estado: asegurar que la petición se ha realizado correctamente.


if response.status_code == 200:
    print('Request was successful!')
else:
    print('Request failed with status code:', response.status_code)

Extraer contenido: extraer el contenido de texto o JSON de la respuesta.


# Obtener el contenido de la respuesta como texto
page_content = response.text
print(page_content)

# Obtener el contenido de la respuesta como JSON (si la respuesta está en formato JSON)
json_content = response.json()
print(json_content)

Manejo de errores HTTP y de red

Los errores HTTP y de red pueden producirse cuando no se puede acceder a un recurso, cuando se agota el tiempo de espera de una petición o cuando el servidor devuelve un estado HTTP de error (por ejemplo, 404 Not Found, 500 Internal Server Error). Podemos utilizar los objetos de excepción lanzados por las peticiones para manejar estas situaciones.


import requests

url = 'http://example.com'

try:
    response = requests.get(url, timeout=10)  # Set a timeout for the request
    response.raise_for_status()  # Raises an HTTPError for bad responses
except requests.exceptions.HTTPError as http_err:
    print(f'HTTP error occurred: {http_err}')
except requests.exceptions.ConnectionError:
    print('Failed to connect to the server.')
except requests.exceptions.Timeout:
    print('The request timed out.')
except requests.exceptions.RequestException as req_err:
    print(f'Request error: {req_err}')
else:
    print('Request was successful!')

Extracción de datos de elementos HTML

Para el web scraping, a menudo necesitamos extraer datos del contenido HTML. En esta parte hablaremos de cómo localizar y extraer datos de elementos HTML con algunas librerías como Beautiful Soup o lxml.

HTML (HyperText Markup Language) es el lenguaje de marcado estándar para crear páginas web. Consiste en elementos anidados representados por etiquetas, como <div>, <p>, <a>, etc. Cada etiqueta puede tener atributos y contener texto, otras etiquetas o ambas cosas.

Los selectores XPath y CSS proporcionan una forma versátil de seleccionar elementos HTML basándose en sus atributos o en su posición en el documento.

Buscar selectores XPath y CSS

Al hacer web scraping, extraer datos específicos de páginas web a menudo requiere identificar los selectores XPath o CSS correctos para apuntar a elementos HTML. He aquí cómo encontrar estos selectores de manera eficiente:

La mayoría de los navegadores web modernos vienen con herramientas integradas para desarrolladores que permiten inspeccionar la estructura HTML de las páginas web. He aquí una guía paso a paso sobre cómo utilizar estas herramientas:

  1. Herramientas abiertas para desarrolladores:
    • En Chrome: Haz clic con el botón derecho en la página y selecciona "Inspeccionar" o pulsa Ctrl+Shift+I (Windows/Linux) o Cmd+Opt+I (Mac).
    • En Firefox: Haz clic con el botón derecho en la página y selecciona "Inspeccionar elemento" o pulsa Ctrl+Shift+I (Windows/Linux) o Cmd+Opt+I (Mac).
  2. Inspeccione el elemento:
    • Utilice la herramienta de inspección (un icono de cursor) para pasar el ratón por encima y hacer clic en el elemento que desea raspar. Esto resaltará el elemento en la vista de estructura HTML.
  3. Copiar XPath o selector CSS:
    • Haga clic con el botón derecho en el elemento HTML resaltado en el panel de herramientas de desarrollo.
    • Seleccione "Copiar" y, a continuación, elija "Copiar XPath" o "Copiar selector" (selector CSS).

1n.png

XPath: /html/body/div/h1

CSS Selector: body > div > h1

Extracción utilizando Beautiful Soup

Beautiful Soup es una librería Python para analizar documentos HTML y XML. Proporciona métodos y atributos simples para navegar y buscar a través de la estructura HTML.


from bs4 import BeautifulSoup
import requests

# URL de la página web que se va a raspar
url = 'https://example.com'

# Enviar una solicitud HTTP GET a la URL
response = requests.get(url)

# Analiza el contenido HTML de la respuesta utilizando Beautiful Soup
soup = BeautifulSoup(response.content, 'html.parser')

# Utiliza el selector CSS para encontrar todas las etiquetas <h1> que estén dentro de etiquetas <div>.
# que sean hijas directas de la etiqueta <body>.
h1_tags = soup.select('body > div > h1')

# Iterar sobre la lista de etiquetas <h1> encontradas e imprimir su contenido textual
for tag in h1_tags:
    print(tag.text)

Tratamiento de errores de análisis

Los errores de análisis se producen cuando la estructura HTML o XML no es la esperada, causando problemas en la extracción de datos. Estos errores pueden gestionarse mediante excepciones como AttributeError.


from bs4 import BeautifulSoup
import requests

# URL de la página web que se va a raspar
url = 'https://example.com'

# Enviar una solicitud HTTP GET a la URL
response = requests.get(url)

try:
    # Analiza el contenido HTML de la respuesta utilizando Beautiful Soup
    soup = BeautifulSoup(response.content, 'html.parser')

    # Utiliza el selector CSS para encontrar todas las etiquetas <h1> que estén dentro de etiquetas <div>.
    # que sean hijas directas de la etiqueta <body>.
    h1_tags = soup.select('body > div > h1')

    # Iterar sobre la lista de etiquetas <h1> encontradas e imprimir su contenido textual
    for tag in h1_tags:
        print(tag.text)
except AttributeError as attr_err:
    # Tratar los casos en los que pueda producirse un AttributeError (por ejemplo, si response.content es None)
    print(f'Attribute error occurred: {attr_err}')
except Exception as parse_err:
    # Manejar cualquier otra excepción que pueda ocurrir durante el análisis sintáctico
    print(f'Error while parsing HTML: {parse_err}')

Extracción mediante lxml

Además de Beautiful Soup, otra biblioteca popular para analizar documentos HTML y XML en Python es lxml. Mientras que BeautifulSoup se centra en proporcionar una interfaz cómoda para navegar y manipular los datos analizados, lxml es conocida por su velocidad y flexibilidad, lo que la convierte en la opción preferida para tareas de rendimiento crítico.


from lxml.html import fromstring
import requests

# URL de la página web que se va a raspar
url = 'https://example.com'

# Enviar una solicitud HTTP GET a la URL
response = requests.get(url)

# Analiza el contenido HTML de la respuesta utilizando el método fromstring de lxml
parser = fromstring(response.text)

# Utilice XPath para encontrar el contenido de texto de la primera etiqueta <h1>
# que está dentro de una etiqueta <div>, que es hija directa de la etiqueta <body>.
title = parser.xpath('/html/body/div/h1/text()')[0]

# Imprimir el título
print(title)

Manejo de errores de análisis

De forma similar a Beautiful Soup, lxml te permite manejar errores de análisis sintáctico de forma elegante mediante la captura de excepciones como lxml.etree.XMLSyntaxError.


from lxml.html import fromstring
from lxml import etree
import requests

# URL de la página web que se va a raspar
url = 'https://example.com'

# Enviar una solicitud HTTP GET a la URL
response = requests.get(url)

try:
    # Analiza el contenido HTML de la respuesta utilizando el método fromstring de lxml
    parser = fromstring(response.text)

    # Utilice XPath para encontrar el contenido de texto de la primera etiqueta <h1>
    # que está dentro de una etiqueta <div>, que es hija directa de la etiqueta <body>.
    title = parser.xpath('/html/body/div/h1/text()')[0]

    # Imprimir el título
    print(title)
except IndexError:
    # Manejar el caso en que la consulta XPath no devuelva ningún resultado
    print('No <h1> tag found in the specified location.')
except etree.XMLSyntaxError as parse_err:
    # Gestión de errores de sintaxis XML durante el análisis sintáctico
    print(f'Error while parsing HTML: {parse_err}')
except Exception as e:
    # Manejar cualquier otra excepción
    print(f'An unexpected error occurred: {e}')

Guardar los datos extraídos

Una vez que haya extraído con éxito los datos de los elementos HTML, el siguiente paso es guardar estos datos. Python proporciona varias opciones para guardar los datos raspados, incluyendo guardar en archivos CSV, archivos JSON y bases de datos. Aquí hay una visión general de cómo guardar los datos extraídos utilizando diferentes formatos:

Guardar datos en un archivo CSV

CSV (Comma-Separated Values) es un formato sencillo y muy utilizado para almacenar datos tabulares. El módulo CSV de Python facilita la escritura de datos en archivos CSV.


import csv

# Datos de la muestra
data = {
    'title': 'Example Title',
    'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}

# Guardar datos en un archivo CSV
with open('scraped_data.csv', mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(['Title', 'Paragraph'])
    for paragraph in data['paragraphs']:
        writer.writerow([data['title'], paragraph])

print('Data saved to scraped_data.csv')

Guardar datos en un archivo JSON

JSON (JavaScript Object Notation) es un formato ligero de intercambio de datos que es fácil de leer y escribir. El módulo JSON de Python proporciona métodos para guardar datos en formato JSON.


import json

# Datos de la muestra
data = {
    'title': 'Example Title',
    'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}

# Guardar datos en un archivo JSON
with open('scraped_data.json', mode='w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False, indent=4)

print('Data saved to scraped_data.json')

Técnicas avanzadas de web scraping con Playwright

Playwright es una potente herramienta para scrapear contenido dinámico e interactuar con elementos web. Puede manejar sitios web con mucho JavaScript que los analizadores HTML estáticos no pueden.

Instale Playwright y configúrelo:


pip install playwright
playwright install

Raspado de contenidos dinámicos

Playwright permite interactuar con elementos web como rellenar formularios y pulsar botones. Puede esperar a que se completen las peticiones AJAX antes de continuar, lo que lo hace ideal para el scraping de contenido dinámico.

2n.png

El código proporcionado realiza web scraping en una página de producto de Amazon usando Playwright y lxml. Inicialmente, se importan los módulos necesarios. Se define una función de ejecución para encapsular la lógica de raspado. La función comienza configurando un servidor proxy y lanzando una nueva instancia del navegador con el proxy y en modo no headless, lo que nos permite observar las acciones del navegador. Dentro del contexto del navegador, se abre una nueva página y se navega a la URL del producto de Amazon especificado, con un tiempo de espera de 60 segundos para asegurar que la página se carga completamente.

A continuación, el script interactúa con la página para seleccionar un estilo de producto específico de un menú desplegable y una opción de producto mediante el uso de localizadores y coincidencia de texto. Después de asegurarse de que estas interacciones se han completado y la página se ha cargado completamente de nuevo, se captura el contenido HTML de la página.

A continuación, el contenido HTML se analiza utilizando el método fromstring de lxml para crear un árbol de elementos. Se utiliza una consulta XPath para extraer el contenido de texto del título del producto de un elemento específico con el ID productTitle. El script incluye un tratamiento de errores para gestionar los casos en los que la consulta XPath no devuelva resultados, cuando se produzcan errores de sintaxis XML durante el análisis sintáctico o cualquier otra excepción inesperada. Por último, se imprime el título del producto extraído de tlxml y se cierran el contexto del navegador y el navegador para finalizar la sesión.

La función de ejecución se ejecuta dentro de una sesión de Playwright iniciada por sync_playwright, lo que garantiza que todo el proceso se gestione y ejecute dentro de un entorno controlado. Esta estructura garantiza la solidez y la resistencia a errores mientras se realiza la tarea de raspado web.


from playwright.sync_api import Playwright, sync_playwright
from lxml.html import fromstring, etree


def run(playwright: Playwright) -> None:
   # Definir el servidor proxy
   proxy = {"server": "https://IP:PORT", "username": "LOGIN", "password": "PASSWORD"}

   # Lanzar una nueva instancia del navegador con el proxy especificado y en modo no headless.
   browser = playwright.chromium.launch(
       headless=False,
       proxy=proxy,
       slow_mo=50,
       args=['--ignore-certificate-errors'],
   )

   # Crear un nuevo contexto de navegación
   context = browser.new_context(ignore_https_errors=True)

   # Abrir una nueva página en el contexto del navegador
   page = context.new_page()

   # Navegar a la página de producto de Amazon especificada
   page.goto(
       "https://www.amazon.com/A315-24P-R7VH-Display-Quad-Core-Processor-Graphics/dp/B0BS4BP8FB/",
       timeout=10000,
   )

   # Espere a que la página se cargue completamente
   page.wait_for_load_state("load")

   # Seleccione un estilo de producto específico en el menú desplegable
   page.locator("#dropdown_selected_style_name").click()

   # Seleccione una opción de producto específica
   page.click('//*[@id="native_dropdown_selected_style_name_1"]')
   page.wait_for_load_state("load")

   # Obtener el contenido HTML de la página cargada
   html_content = page.content()

   try:
       # Analiza el contenido HTML utilizando el método fromstring de lxml
       parser = fromstring(html_content)

       # Utilice XPath para extraer el contenido de texto del título del producto
       product_title = parser.xpath('//span[@id="productTitle"]/text()')[0].strip()

       # Imprimir el título del producto extraído
       print({"Product Title": product_title})
   except IndexError:
       # Manejar el caso en que la consulta XPath no devuelva ningún resultado
       print('Product title not found in the specified location.')
   except etree.XMLSyntaxError as parse_err:
       # Gestión de errores de sintaxis XML durante el análisis sintáctico
       print(f'Error while parsing HTML: {parse_err}')
   except Exception as e:
       # Manejar cualquier otra excepción
       print(f'An unexpected error occurred: {e}')

   # Cerrar el contexto del navegador y el navegador
   context.close()
   browser.close()


# Utilice sync_playwright para iniciar la sesión de Playwright y ejecutar el script
with sync_playwright() as playwright:
   run(playwright)

El web scraping con Python es un potente método para obtener datos de sitios web. Las herramientas analizadas facilitan la extracción, el procesamiento y el almacenamiento de datos web para diversos fines. En este proceso, el uso de servidores proxy para alternar direcciones IP y la implementación de retardos entre peticiones son cruciales para sortear los bloqueos. Beautiful Soup es fácil de usar para los principiantes, mientras que lxml es adecuado para manejar grandes conjuntos de datos gracias a su eficiencia. Para necesidades de scraping más avanzadas, especialmente con sitios web cargados dinámicamente con JavaScript, Playwright resulta muy eficaz.

Comentarios:

0 Comentarios