Raspado web con ChatGPT: guía paso a paso

Aprende a usar las funciones de ChatGPT para generar secuencias de comandos para hacer raspados de sitios web estáticos y complejos, lo que simplifica el proceso de recopilación de datos.
17 min read
Web Scraping With ChatGPT blog image

Debido al continuo crecimiento exponencial de la economía digital, recopilar datos de diversas fuentes, como las API, los sitios web y las bases de datos, es más importante que nunca.

Una forma habitual de extraer datos es a través del raspado web. El raspado web implica hacer uso de herramientas automatizadas para buscar páginas web y para analizar su contenido con el objetivo de extraer información específica para su posterior evaluación y uso. Los casos prácticos frecuentes incluyen estudios de mercado, control de precios y agregación de datos.

La implementación del raspado web supone tener que gestionar el contenido dinámico, controlar las sesiones y las cookies, adoptar medidas antirraspado y garantizar el cumplimiento legal. Para este tipo de obstáculos, hace falta tener herramientas y técnicas avanzadas para que la extracción de datos sea eficaz. ChatGPT puede ayudar a superar estos obstáculos porque aprovecha sus funciones de procesamiento del lenguaje natural para generar código y solucionar errores.

En este artículo, vas a aprender a usar ChatGPT para generar códigos de raspado para sitios web que se basan principalmente en contenido HTML estático y para sitios web complejos que emplean técnicas de generación de páginas más complejas.

Requisitos previos

Antes de empezar este tutorial, asegúrate de que cumples los siguientes puntos:

Cuando usas ChatGPT para generar tus secuencias de comandos para el raspado web, hay dos pasos principales que tienes que seguir:

  1. Documenta cada paso que tiene que seguir el código para encontrar la información que quieres extraer, como los elementos HTML a los que se tiene que dirigir, los cuadros de texto que tiene que rellenar y los botones en los que tiene que hacer clic. Muchas veces, tendrás que copiar el selector específico de elementos HTML. Para ello, haz clic con el botón derecho en el elemento concreto de la página que quieres extraer y, después, haz clic en Inspeccionar; Chrome resalta el elemento DOM específico. Haz clic con el botón derecho en este elemento y selecciona Copiar > Copiar selector para que la ruta del selector de HTML se copie en tu portapapeles:
    Copiando un selector
  1. Crea indicaciones de ChatGPT que sean concretas y detalladas para generar el código para el raspado web.
  2. Ejecuta y prueba el código que se ha generado.

Raspado de sitios web con HTML estático usando ChatGPT

Ahora que ya estás familiarizado con el flujo de trabajo general, vamos a utilizar ChatGPT para recopilar datos de algunos sitios web con elementos HTML estáticos.  Para empezar, vas a extraer los títulos y los precios de los libros de https://books.toscrape.com.

Al principio, tienes que identificar los elementos HTML que contienen los datos que necesitas:

  • El selector para los títulos de los libros es #default > div.container-fluid.page > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > h3 > a.
  • El selector para los precios de los libros es *#default > div.container-fluid.page > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.product_price > p.price_color.

Después, tienes que crear indicaciones de ChatGPT que sean concretas y detalladas para generar el código del raspado web. Para hacerlo, tienes que decirle a ChatGPT que instale todos los paquetes de Python necesarios, que lo guíe a través de la extracción de los selectores de HTML (que has identificado con anterioridad) y, a continuación, pedirle que guarde los datos en un archivo de Excel.

No te olvides de configurar la versión de ChatGPT en GPT-4o.

Puedes escribir algo como esto en ChatGPT:

Eres un experto en raspado web y utilizas la biblioteca de Python Beautiful Soup y todas las herramientas de automatización necesarias. Quiero que generes una secuencia de comandos detallada paso a paso para hacer un raspado web de https://books.toscrape.com; haz lo siguiente:

  1. Instala todos los paquetes de Python que sean necesarios.
  2. Extrae los títulos de los libros, que tienen el selector de HTML #default > div.container-fluid.page > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > h3 > a, y los precios de los libros (solo el número, nada más), que tienen el selector #default > div.container-fluer-fluir id.page > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.product_price > p.price _color.
  3. Extrae la lista de todos los títulos y los precios de los libros y guárdala en un archivo de Excel.
  4. Haz el raspado solo de la primera página.

Aviso: es posible que recibas una respuesta algo diferente.

En la respuesta, ChatGPT te pide que ejecutes el siguiente comando para instalar la biblioteca Beautiful Soup, que es la que se encarga de hacer el raspado web, y la biblioteca pandas, una biblioteca muy completa de análisis de datos que los almacena en formato Excel:

pip3 install requests beautifulsoup4 pandas openpyxl

Verás que ChatGPT también te sugiere instalar openpyxl, pero, en este caso, no hace falta.

ChatGPT también te facilita el siguiente código de raspado web:

import requests
from bs4 import BeautifulSoup
import pandas as pd

# URL of the website
url = 'https://books.toscrape.com'

# Send a GET request to the website
response = requests.get(url)
if response.status_code == 200:
    # Parse the HTML content of the page
    soup = BeautifulSoup(response.content, 'html.parser')
    
    # Initialize lists to store the titles and prices
    book_titles = []
    book_prices = []

    # Extract the first book title and price using the provided selectors
    book_title_selector = "#default > div.container-fluid.page > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > h3 > a"
    book_price_selector = "#default > div.container-fluid.page > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.product_price > p.price_color"

    title_element = soup.select_one(book_title_selector)
    price_element = soup.select_one(book_price_selector)
    
    if title_element and price_element:
        book_titles.append(title_element.get('title'))
        book_prices.append(price_element.text.strip()[1:])

    # Extract all book titles and prices on the first page
    books = soup.select('section > div:nth-child(2) > ol > li')
    for book in books:
        title = book.select_one('h3 > a')
        price = book.select_one('div.product_price > p.price_color')
        if title and price:
            book_titles.append(title.get('title'))
            book_prices.append(price.text.strip()[1:])

    # Create a DataFrame from the lists
    df = pd.DataFrame({
        'Title': book_titles,
        'Price': book_prices
    })

    # Save the DataFrame to an Excel file
    df.to_excel('books_scraped.xlsx', index=False)

    print('Data has been successfully scraped and saved to books_scraped.xlsx')
else:
    print('Failed to retrieve the webpage')

Este código importa el módulo requests, que hace llamadas de HTTP al sitio web que extrae. También importa paquetes de pandas que almacenan datos que se han extraído en archivos de Excel. El código define la URL base del sitio web y los selectores específicos de HTML a los que se dirige para obtener los datos solicitados.

Después, el código llama al sitio web e introduce el contenido del sitio web como un objeto de Beautiful Soup llamado soup. El código selecciona los valores de los títulos y los precios de los libros como listas del objeto soup por medio de los selectores de HTML. Por último, el código crea un «DataFrame» de pandas a partir de la lista de los títulos y los precios de los libros y la guarda como un archivo de Excel.

A continuación, tienes que guardar el código en un archivo llamado books_scraping.py y ejecutar el comando python3 books_scraping.py desde la línea de comandos. Este código genera un archivo de Excel llamado books_scraped.xlsx en el mismo directorio que books_scraping.py:

El archivo de Excel generado con el nombre books_scraped.xlsx

Ahora que has visto un ejemplo, vamos a dar un paso más en este tutorial y vamos a hacer el raspado de otro sitio web sencillo: https://quotes.toscrape.com, que contiene una colección de citas.

Volvemos a empezar por identificar la secuencia de pasos.

Si estás utilizando Chrome, encuentra los siguientes selectores de HTML:

  • body > div.container > div:nth-child(2) > div.col-md-8 > div:nth-child(1) > span.text para extraer las citas.
  • body > div.container > div:nth-child(2) > div.col-md-8 > div:nth-child(1) > span:nth-child(2) > small para identificar a los autores.

Una vez que hayas identificado los selectores de HTML que quieres extraer, puedes crear una indicación detallada para generar el código de raspado como la siguiente:

Eres un experto en raspado web y utilizas la biblioteca de Python Beautiful Soup y todas las herramientas de automatización necesarias. Quiero que generes una secuencia de comandos detallada paso a paso para hacer un raspado web de https://quotes.toscrape.com. Haz lo siguiente:

  1. Instala todos los paquetes de Python que sean necesarios.
  2. Extrae las citas, que tiene el selector de HTML body > div.container > div:nth-child(2) > div.col-md-8 > div:nth-child(1) > span.text, y el nombre de los autores, que tiene el selector body > div.container > div:nth-child(2) > div.col-md-8 > div:nth-child(1) > span:nth-child(2) > small.
  3. Extrae la lista de todas las citas y de todos los autores y guárdala en un archivo de Excel.
  4. Haz el raspado solo de la primera página.

Después de que introduzcas esta información, ChatGPT debería facilitarte el siguiente comando, que instala las bibliotecas de Beautiful Soup, pandas y openpyxl:

pip3 install requests beautifulsoup4 pandas openpyxl

ChatGPT también debería facilitarte el siguiente código de raspado web:

import requests
from bs4 import BeautifulSoup
import pandas as pd

# Step 1: Fetch the web page content
url = "https://quotes.toscrape.com"
response = requests.get(url)
html_content = response.text

# Step 2: Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(html_content, 'html.parser')

# Step 3: Extract the specific quote and author
quote_selector = "body > div.container > div:nth-child(2) > div.col-md-8 > div:nth-child(1) > span.text"
author_selector = "body > div.container > div:nth-child(2) > div.col-md-8 > div:nth-child(1) > span:nth-child(2) > small"

specific_quote = soup.select_one(quote_selector).get_text()
specific_author = soup.select_one(author_selector).get_text()

print(f"Specific Quote: {specific_quote}")
print(f"Specific Author: {specific_author}")

# Step 4: Extract all quotes and authors
quotes = soup.find_all('div', class_='quote')

all_quotes = []
for quote in quotes:
  text = quote.find('span', class_='text').get_text()
  author = quote.find('small', class_='author').get_text()
  all_quotes.append({"quote": text, "author": author})

# Step 5: Save the quotes to an Excel file
df = pd.DataFrame(all_quotes)
df.to_excel('quotes.xlsx', index=False)

print("Quotes have been saved to quotes.xlsx")
soup = BeautifulSoup(html_content, 'html.parser')

# Step 3: Extract the specific quote and author
quote_selector = "body > div.container > div:nth-child(2) > div.col-md-8 > div:nth-child(1) > span.text"
author_selector = "body > div.container > div:nth-child(2) > div.col-md-8 > div:nth-child(1) > span:nth-child(2) > small"

specific_quote = soup.select_one(quote_selector).get_text()
specific_author = soup.select_one(author_selector).get_text()

print(f"Specific Quote: {specific_quote}")
print(f"Specific Author: {specific_author}")

# Step 4: Extract all quotes and authors
quotes = soup.find_all('div', class_='quote')

all_quotes = []
for quote in quotes:
    text = quote.find('span', class_='text').get_text()
    author = quote.find('small', class_='author').get_text()
    all_quotes.append({"quote": text, "author": author})

# Step 5: Save the quotes to an Excel file
df = pd.DataFrame(all_quotes)
df.to_excel('quotes.xlsx', index=False)

print("Quotes have been saved to quotes.xlsx")

Guarda este código en un archivo llamado quotes_scraping.py y ejecuta el comando python3 books_scraping.py desde la línea de comandos. Este código genera un archivo de Excel llamado quotes_scraped.xlsx en el mismo directorio que quotes_scraping.py. Abre el archivo de Excel que se ha generado, que debe tener este aspecto:

Archivo Excel generado con citas y autores

Raspado de sitios web complejos

Hacer el raspado de sitios web complejos puede ser todo un reto porque el contenido dinámico se suele cargar por JavaScript, algo que las herramientas como requests y Beautiful Soup no pueden gestionar. Estos sitios pueden que requieran interacciones como hacer clic en los botones o desplazarse para acceder a todos los datos. Para poder superar estos obstáculos, puedes usar WebDriver, que reproduce las páginas como si fuera un navegador y simula las interacciones de los usuarios, de manera que te permite asegurarte de que todo el contenido es accesible tal y como lo sería para un usuario normal.

Por ejemplo, Yelp es un sitio web colaborativo de valoraciones para empresas. Yelp se basa en la generación dinámica de páginas y tiene que simular varias interacciones de los usuarios. Ahora vas a utilizar ChatGPT para generar un código de extracción que recupere una lista de empresas de Estocolmo y sus valoraciones.

Para hacer un raspado web de Yelp, vamos a empezar por documentar los pasos que tendrás que seguir:

  1. Encuentra el selector del cuadro de texto de ubicación que utilizará la secuencia de comandos; en este caso, es #search_location. Escribe «Estocolmo» en el cuadro de búsqueda de ubicaciones y, a continuación, encuentra el selector del botón de búsqueda; en este caso, es #header_find_form > div.y-css-1iy1dwt > button. Haz clic en el botón de búsqueda para ver los resultados de la misma. Esto puede tardar unos segundos. Encuentra un selector que contenga los nombres de las empresas (por ejemplo, #main-content > ul > li:nth-child(3) > div.container_\ _09f24_\ _FeTO6.hoverable_\ _09f24_\ __UXLO.y-css-way87j > div > div.y-css-cxcdjj > div:nth-child(1) > div.y-css-1iy1dwt > div:nth-child(1) > div > div > h3 > a):
     Obteniendo el selector para los nombres de las empresas
  1. Busca el selector que contiene las valoraciones de las empresas (por ejemplo, #main-content > ul > li:nth-child(3) > div.container_\ _09f24_\ _FeTO6.hoverable_\ _09f24_\ __UXLO.y-css-way87j > div > div.y-css-cxcdjj > div:nth-child(1) > div.y-css-1iy1dwt > div:nth-child(2) > div > div > div.y-css-ohs7lg > span.y-css-jf9frv):
     Obteniendo el selector para las valoraciones medias de las empresas
  1. Encuentra el selector del botón Abierto ahora; es #main-content > div.stickyFilterOnSmallScreen_\ _09f24_\ _UWWJ3.hideFilterOnLargeScreen_\ _09f24_\ _ilqIP.y-css-9ze9ku > div > div > div > div > div > span > button:nth-child(3) > span:
    Selector del botón «Abierto ahora»
  1. Guarda una copia de la página web para poder subirla más tarde junto con las indicaciones que le has dado a ChatGPT para ayudar a que ChatGPT entienda el contexto de las indicaciones. En Chrome, puedes hacer clic en los tres puntos de la parte superior derecha y, después, hacer clic en Guardar y compartir > Guardar página como:
    Guardar una página web en Chrome

A continuación, con los valores del selector que has extraído antes, tienes que redactar una indicación detallada para guiar a ChatGPT a la hora de generar la secuencia de comandos del raspado:

Eres un experto en raspado web. Quiero que hagas un raspado de https://www.yelp.com/ para extraer datos concretos. Sigue estos pasos antes de hacer el raspado:

  1. Borra la casilla con el selector #search_location.
  2. Escribe «Estocolmo» en el cuadro de búsqueda con el selector #search_location.
  3. Haz clic en el botón con el selector #header_find_form > div.y-css-1iy1dwt > button.
  4. Espera unos segundos a que la página cargue los resultados de la búsqueda.
  5. Haz clic en el botón Abierto ahora, que tiene el selector #main-content > div.stickyFilterOnSmallScreen_\ _09f24_\ _UWWJ3.hideFilterOnLargeScreen_\ _09f24_\ _ilqip.y-CSS-9ze9ku > div > div > div > div > div > span > button:nth-child(3) > span, para filtrar las empresas que están abiertas ahora.
  6. Crea una lista con los nombres de las empresas, que tiene el selector #main-content > ul > li:nth-child(3) > div.container_\ _09f24_\ _FeTO6.hoverable_\ _09f24_\ __UXLO.y-css-way87j > div > div.y-css-cxcdjj > div:nth-child(1) > div.y-css-1iy1dwt > div:n-child(1) > div > div > h3 > a.
  7. Crea una lista con las valoraciones de las empresas, que tiene el selector #main-content > ul > li:nth-child(3) > div.container_\ _09f24_\ _FeTO6.hoverable_\ _09f24_\ __UXLO.y-css-way87j > div > div.y-css-cxcdjj > div:nth-child(1) > div.y-css-1iy1dwt > div:n-child(2) > div > div > div > div.y-css-ohs7lg > span.y-css-jf9frv.
  8. Crea un archivo de Excel con los nombres de las empresas y sus valoraciones.
  9. Comprueba que has instalado todos los paquetes de Python necesarios.
  10. Usa WebDriver de Selenium para automatizar el proceso.
  11. Consulta la copia adjunta de la página HTML de resultados para obtener información sobre el formato HTML.

Después de introducir esta información, ChatGPT te pide que instales Selenium, la herramienta de automatización web que admite WebDriver, y pandas:

pip3 install selenium pandas

ChatGPT también te facilita un código de extracción junto con una explicación:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd
import time

# Initialize the WebDriver
driver = webdriver.Chrome()

try:
    # Open Yelp
    driver.get('https://www.yelp.com/')

    # Clear the location search box
    location_box = driver.find_element(By.CSS_SELECTOR, '#search_location')
    location_box.clear()

    # Enter "Stockholm" in the location search box
    location_box.send_keys('Stockholm')

    # Click the search button
    search_button = driver.find_element(By.CSS_SELECTOR, '#header_find_form > div.y-css-1iy1dwt > button')
    search_button.click()

    # Wait for search results to load
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, '#main-content'))
    )

    # Click on "Open Now" filter
    open_now_button = driver.find_element(By.CSS_SELECTOR, '#main-content > div.stickyFilterOnSmallScreen__09f24__UWWJ3.hideFilterOnLargeScreen__09f24__ilqIP.y-css-9ze9ku > div > div > div > div > div > span > button:nth-child(3) > span')
    open_now_button.click()

    # Wait for the filter results to load
    time.sleep(5)

    # Extract business names and reviews
    business_names = []
    business_reviews = []

    businesses = driver.find_elements(By.CSS_SELECTOR, '#main-content > ul > li')

    for business in businesses:
        try:
            name = business.find_element(By.CSS_SELECTOR, 'div.container__09f24__FeTO6.hoverable__09f24___UXLO.y-css-way87j > div > div.y-css-cxcdjj > div:nth-child(1) > div.y-css-1iy1dwt > div:nth-child(1) > div > div > h3 > a').text
            review = business.find_element(By.CSS_SELECTOR, 'div.container__09f24__FeTO6.hoverable__09f24___UXLO.y-css-way87j > div > div.y-css-cxcdjj > div:nth-child(1) > div.y-css-1iy1dwt > div:nth-child(2) > div > div > div > div.y-css-ohs7lg > span.y-css-jf9frv').text
            business_names.append(name)
            business_reviews.append(review)
        except Exception as e:
            print(f"Error extracting data for a business: {e}")

    # Create a DataFrame and save to Excel
    df = pd.DataFrame({'Business Name': business_names, 'Reviews': business_reviews})
    df.to_excel('stockholm_businesses.xlsx', index=False)
    print("Data saved to stockholm_businesses.xlsx")

finally:
    # Close the WebDriver
    driver.quit()

Guarda esta secuencia de comandos y ejecútala con Python en Visual Studio Code. Verás que el código abre Chrome, se dirige a Yelp, borra el cuadro de texto de la ubicación, escribe «Estocolmo», hace clic en el botón de búsqueda, filtra las empresas que están abiertas ahora y, por último, cierra la página. Después de eso, el resultado del raspado se guarda en el archivo de Excel stockholm_bussinsess.xlsx:

Valoraciones de empresas de Yelp en Excel

Todo el código fuente de este tutorial está disponible en GitHub.

Conclusión

En este tutorial, has aprendido a usar ChatGPT para extraer datos específicos de sitios web con representación estática en HTML y sitios web más complejos con una generación dinámica de páginas, con enlaces externos de JavaScript y con interacciones de usuario.

Aunque raspar un sitio web como Yelp era sencillo, lo cierto es que hacer el raspado de estructuras HTML complejas puede ser todo un reto y es probable que te encuentres con restricciones de direcciones IP y con algunos CAPTCHA.

Para ponértelo más fácil, Bright Data ofrece una amplia variedad de servicios de recopilación de datos, incluidos servicios de proxy avanzados para ayudar a evitar las prohibiciones de las direcciones IP, la herramienta Web Unlocker para eludir y resolver los CAPTCHA, la API de Web Scraping para la extracción automática de datos y el navegador Scraping Browser para una extracción de datos eficiente.

Regístrate ya y descubre todos los productos que ofrece Bright Data. ¡Empieza ya con una prueba gratuita!

No se requiere tarjeta de crédito