---
title: "Cómo acelerar el Scraping web: guía completa"
slug: speed-up-web-scraping
date: 2026-02-17T09:07:39+00:00
modified: 2026-02-17T09:07:41+00:00
permalink: https://brightdata.es/blog/datos-web/speed-up-web-scraping
type: blog
---

[ Blog ](https://brightdata.es/blog "Blog") / [Datos web](https://brightdata.es/blog/datos-web)







 [Datos web](https://brightdata.es/blog/datos-web)

# Cómo acelerar el Scraping web: guía completa

Aprenda a optimizar su proceso de Scraping web con técnicas avanzadas para una recuperación de datos más rápida.

 27 min de lectura





 [ ![Antonello Zanini](https://media.brightdata.es/2022/12/Antonello-Zanini-2-50x50.jpg) ](https://brightdata.com/blog/authors/antonello-zanini)

 [Antonello Zanini

Technical Writer

 ](https://brightdata.com/blog/authors/antonello-zanini)





 ![How to Make Web Scraping Faster](https://media.brightdata.es/2024/11/How-to-Make-Web-Scraping-Faster-2.svg)





En este artículo, verás:

- Las principales causas de la lentitud del proceso de Scraping web
- Varias técnicas para acelerar el Scraping web
- Cómo optimizar un script de scraping de Python de muestra para una recuperación de datos más rápida

¡Empecemos!

## <a></a>Razones por las que tu proceso de scraping es lento

Explora las razones clave por las que tu proceso de Scraping web puede ser lento.

### <a></a>Razón n.º 1: respuestas lentas del servidor

Uno de los factores más notables que afectan a la velocidad del Scraping web es el tiempo de respuesta del servidor. Cuando envías una solicitud a un sitio web, el servidor la procesa y responde a tu solicitud. Si el servidor es lento, tus solicitudes tardarán más en completarse. Las razones por las que un servidor puede ser lento son el tráfico intenso, los recursos limitados o las ralentizaciones de la red.

Desafortunadamente, hay poco que pueda hacer para acelerar un servidor de destino. Eso está fuera de su control, a menos que la ralentización se deba a un número abrumador de solicitudes por su parte. Si este es el caso, distribuya sus solicitudes a lo largo de un periodo de tiempo más largo añadiendo retrasos aleatorios entre ellas.

### <a></a>Razón n.º 2: procesamiento lento de la CPU

La velocidad de procesamiento de la CPU desempeña un papel crucial en la rapidez con la que pueden funcionar sus scripts de scraping. Cuando ejecuta sus scripts de forma secuencial, su CPU se encarga de procesar cada operación de una en una, lo que puede llevar mucho tiempo. Esto se nota especialmente cuando sus scripts implican cálculos complejos o transformaciones de datos.

Además, el parseo de HTML lleva cierto tiempo y puede ralentizar significativamente el proceso de scraping. Obtenga más información en nuestro artículo sobre [Scraping web HTML](/blog/how-tos/html-web-scraping).

### <a></a>Razón n.º 3: Operaciones de E/S limitadas

Las operaciones de entrada/salida (E/S) pueden convertirse fácilmente en el cuello de botella de su operación de scraping. Esto es especialmente cierto cuando el sitio de destino consta de varias páginas. Si su script está diseñado para esperar las respuestas de recursos externos antes de continuar, esto puede provocar retrasos considerables.

Enviar una solicitud, esperar a que el servidor responda, procesarla y luego pasar a la siguiente solicitud no es una forma eficiente de realizar el Scraping web.

### <a></a>Otras razones

Otras razones que ralentizan su script de Scraping web son:

- **Código ineficiente**: una lógica de scraping mal optimizada puede ralentizar todo el proceso de scraping. Evite estructuras de datos ineficientes, bucles innecesarios o registros excesivos.
- **Limitación de velocidad**: si el sitio de destino restringe el número de solicitudes que un usuario puede realizar en un periodo de tiempo determinado, tu Scraper automatizado será lento como resultado. ¿La solución? [¡Servicios de Proxy!](/proxy-types)
- **CAPTCHAs y otras soluciones antirraspado**: Los CAPTCHAs y las medidas antibots pueden interrumpir su proceso de rastreo al requerir la interacción del usuario. Descubra otras [técnicas antirraspado](/blog/web-data/anti-scraping-techniques).

## <a></a>Técnicas para acelerar el Scraping web

En esta sección, descubrirá los métodos más populares para acelerar el Scraping web. Comenzaremos con un script básico de scraping en Python y demostraremos el impacto de varias optimizaciones en él.

**Nota**: Las técnicas que se exploran aquí funcionan con cualquier lenguaje de programación o tecnología. Se utiliza Python solo por simplicidad y porque es uno de los [mejores lenguajes de programación para el Scraping web](/blog/web-data/best-languages-web-scraping).

Este es el script inicial de scraping en Python:

```none
import requests
from bs4 import BeautifulSoup
import csv
import time

def scrape_quotes_to_scrape():
    # matriz con las URL de la página que se va a rastrear
    urls = [
        "http://quotes.toscrape.com/",
        "https://quotes.toscrape.com/page/2/",
        "https://quotes.toscrape.com/page/3/",
        "https://quotes.toscrape.com/page/4/",
        "https://quotes.toscrape.com/page/5/",
        "https://quotes.toscrape.com/page/6/",
        "https://quotes.toscrape.com/page/7/",
        "https://quotes.toscrape.com/page/8/",
        "https://quotes.toscrape.com/page/9/",
        "https://quotes.toscrape.com/page/10/"
    ]

    # dónde almacenar los datos recopilados
    quotes = []

    # extraer las páginas secuencialmente
    for url in urls:
        print(f"Extraer página: '{url}'")

        # enviar una solicitud GET para obtener el HTML de la página
        response = requests.get(url)
        # analizar el HTML de la página utilizando BeautifulSoup
        soup = BeautifulSoup(response.content, "html.parser")

        # seleccionar todos los elementos de cita de la página
        quote_html_elements = soup.select(".quote")

        # iterar sobre los elementos de cita y extraer su contenido
        for quote_html_element in quote_html_elements:
            # extraer el texto de la cita
            text = quote_html_element.select_one(".text").get_text()
            # extraer el autor de la cita
            author = quote_html_element.select_one(".author").get_text()
            # extraer las etiquetas asociadas a la cita
            tags = [tag.get_text() for tag in quote_html_element.select(".tag")]

            # rellenar un nuevo objeto de cita y añadirlo a la lista
            quote = {
                "text": text,
                "author": author,
                "tags": ", ".join(tags)
            }
            quotes.append(quote)

        print(f"Página '{url}' rastreada con éxiton")

    print("Exportando datos rastreados a CSV")

    # exportar las citas extraídas a un archivo CSV
    with open("quotes.csv", "w", newline="", encoding="utf-8") as csvfile:
        fieldnames = ["text", "author", "tags"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

        writer.writeheader()
        writer.writerows(quotes)

    print("Citas exportadas a CSVn")

# medir el tiempo de ejecución
start_time = time.time()
scrape_quotes_to_scrape()
end_time = time.time()

execution_time = end_time - start_time
print(f"Tiempo de ejecución: {execution_time:.2f} segundos")

```

El Scraper anterior tiene como objetivo 10 URL paginadas del sitio web [Quotes to Scrape](https://quotes.toscrape.com/). Para cada URL, el script realiza las siguientes operaciones:

1. Envía una solicitud GET utilizando [`requests`](https://requests.readthedocs.io/en/latest/) para obtener el HTML de la página.
2. Parsea el contenido HTML con [`BeautifulSoup`](https://www.crummy.com/software/BeautifulSoup/bs4/doc/).
3. Extrae el texto de la cita, el autor y las etiquetas de cada elemento de cita de la página.
4. Almacena los datos extraídos en una lista de diccionarios.

Por último, exporta los datos extraídos a un archivo CSV llamado `quotes.csv`.

Para ejecutar el script, instala las bibliotecas necesarias con:

```none
pip install requests beautifulsoup4

```

La llamada a la función `scrape_quotes_to_scrape()` se envuelve con llamadas a [`time.time()`](https://docs.python.org/3/library/time.html#time.time) para medir cuánto tiempo tarda el proceso de recopilación. En nuestra máquina, el script inicial tarda aproximadamente **4,51 segundos en completarse**.

Al ejecutar el script, se genera un archivo `quotes.csv` en la carpeta del proyecto. Además, verá registros similares a los siguientes:

```none
Rastreando la página: 'http://quotes.toscrape.com/'
Página 'http://quotes.toscrape.com/' rastreada con éxito

Rastreando la página: 'https://quotes.toscrape.com/page/2/'
Página 'https://quotes.toscrape.com/page/2/' rastreada con éxito

Raspando la página: 'https://quotes.toscrape.com/page/3/'
Página 'https://quotes.toscrape.com/page/3/' raspada con éxito

Raspando la página: 'https://quotes.toscrape.com/page/4/'
Página «https://quotes.toscrape.com/page/4/» extraída correctamente

Extraer página: «https://quotes.toscrape.com/page/5/»
Página «https://quotes.toscrape.com/page/5/» extraída correctamente

Raspando página: 'https://quotes.toscrape.com/page/6/'
Página 'https://quotes.toscrape.com/page/6/' raspada con éxito

Raspando página: 'https://quotes.toscrape.com/page/7/'
Página «https://quotes.toscrape.com/page/7/» extraída correctamente

Extraer página: «https://quotes.toscrape.com/page/8/»
Página «https://quotes.toscrape.com/page/8/» extraída correctamente

Raspando página: 'https://quotes.toscrape.com/page/9/'
Página 'https://quotes.toscrape.com/page/9/' raspada con éxito

Raspando página: 'https://quotes.toscrape.com/page/10/'
Página «https://quotes.toscrape.com/page/10/» extraída correctamente

Exportando datos extraídos a CSV
Cotizaciones exportadas a CSV

Tiempo de ejecución: 4,63 segundos

```

Este resultado muestra claramente que el script extrae secuencialmente cada página web paginada de *Quotes to Scrape*. Como verás a continuación, algunas optimizaciones cambiarán significativamente el flujo y la velocidad de este proceso.

Ahora, ¡veamos cómo acelerar el Scraping web!

### <a></a>1. Utilice una biblioteca de parseo HTML más rápida

[El parseo de datos](/blog/web-data/what-is-data-parsing) consume tiempo y recursos, y los diferentes analizadores HTML utilizan diversos enfoques para realizar esta tarea. Algunos se centran en proporcionar un amplio conjunto de funciones con una API autodescriptiva, mientras que otros dan prioridad al rendimiento. Para obtener más detalles, consulte nuestra guía sobre los [mejores analizadores HTML](/blog/web-data/best-html-parsers).

En Python, Beautiful Soup es el analizador HTML más popular, pero no necesariamente el más rápido. [Consulte algunas pruebas de rendimiento para obtener más contexto](https://thehftguy.com/2020/07/28/making-beautifulsoup-parsing-10-times-faster/).

En realidad, Beautiful Soup actúa como un envoltorio alrededor de diferentes analizadores subyacentes. Puede especificar el analizador que desea utilizar al inicializarlo, a través del segundo argumento:

```none
soup = BeautifulSoup(response.content, "html.parser")

```

Por lo general, Beautiful Soup se utiliza en combinación con [`html.parser`](https://docs.python.org/3/library/html.parser.html), el analizador integrado de la biblioteca estándar de Python. Sin embargo, si lo que busca es velocidad, debería considerar [`lxml`](https://lxml.de/). Se trata de uno de los analizadores HTML más rápidos disponibles en Python, ya que se basa en una implementación en C.

Para instalar `lxml`, ejecuta el siguiente comando:

```none
pip install lxml

```

Una vez instalado, puedes utilizarlo con Beautiful Soup de la siguiente manera:

```none
soup = BeautifulSoup(response.content, "lxml")

```

Ahora, vuelve a ejecutar tu script de scraping en Python. Esta vez, deberías ver el siguiente resultado:

```none
# omitido por brevedad...

Tiempo de ejecución: 4,35 segundos

```

El tiempo de ejecución se redujo **de 4,61 segundos a 4,35 segundos**. Aunque este cambio pueda parecer pequeño, el impacto de esta optimización depende en gran medida del tamaño y la complejidad de las páginas HTML que se realizan y del número de elementos que se seleccionan.

En este ejemplo, el sitio de destino tiene páginas con una estructura DOM simple, corta y poco profunda. Aun así, lograr una mejora de velocidad de alrededor del 6 % con solo un pequeño cambio en el código es una ganancia que vale la pena.

**👍 Ventajas**:

- Fácil de implementar en Beautiful Soup

**👎 Desventajas**:

- Ventaja pequeña
- Solo funciona en páginas con estructuras DOM complejas
- Los analizadores HTML más rápidos pueden tener una API más compleja

### <a></a>2. Implementar el scraping multiprocesamiento

[El multiprocesamiento](https://www.techtarget.com/searchdatacenter/definition/multiprocessing) es un enfoque de ejecución paralela en el que un programa genera múltiples procesos. Cada uno de estos procesos opera en paralelo y de forma independiente en un núcleo de CPU para realizar tareas simultáneamente en lugar de secuencialmente.

Este método es especialmente beneficioso para operaciones vinculadas a E/S, como el Scraping web. El motivo es que el principal cuello de botella suele ser el tiempo que se pasa esperando las respuestas de los servidores web. Al utilizar múltiples procesos, se pueden enviar solicitudes a varias páginas al mismo tiempo, lo que reduce el tiempo total de scraping.

Para adaptar su script de scraping al multiprocesamiento, es necesario realizar algunas modificaciones importantes en la lógica de ejecución. Siga los pasos que se indican a continuación para transformar su Scraper de Python de un enfoque secuencial a uno de multiprocesamiento.

Para empezar con el multiprocesamiento en Python, el primer paso es importar `Pool` y `cpu_count` desde el módulo [`multiprocessing`](https://docs.python.org/3/library/multiprocessing.html):

```none
from multiprocessing import Pool, cpu_count

```

`Pool` proporciona lo que necesitas para gestionar un conjunto de procesos de trabajo. Por su parte, `cpu_count` te ayuda a determinar el número de núcleos de CPU disponibles para el procesamiento paralelo.

A continuación, aísle la lógica para extraer una sola URL dentro de una función:

```none
def scrape_page(url):
    print(f"Scraping page: '{url}'")

    response = requests.get(url)
    soup = BeautifulSoup(response.content, "html.parser")
    quote_html_elements = soup.select(".quote")

    quotes = []
    for quote_html_element in quote_html_elements:
        text = quote_html_element.select_one(".text").get_text()
        author = quote_html_element.select_one(".author").get_text()
        tags = [tag.get_text() for tag in quote_html_element.select(".tag")]
        quotes.append({
            "text": text,
            "author": author,
            "tags": ", ".join(tags)
        })

    print(f"Página '{url}' extraída correctamenten")

    return quotes

```

La función anterior será llamada por cada proceso de trabajo y ejecutada en un núcleo de CPU a la vez.

A continuación, sustituya el flujo de rastreo secuencial por una lógica de multiprocesamiento:

```none
def scrape_quotes():
    urls = [
        "http://quotes.toscrape.com/",
        "https://quotes.toscrape.com/page/2/",
        "https://quotes.toscrape.com/page/3/",
        "https://quotes.toscrape.com/page/4/",
        "https://quotes.toscrape.com/page/5/",
        "https://quotes.toscrape.com/page/6/",
        "https://quotes.toscrape.com/page/7/",
        «https://quotes.toscrape.com/page/8/»,
        «https://quotes.toscrape.com/page/9/»,
        «https://quotes.toscrape.com/page/10/»
    ]

    # crear un grupo de procesos
    with Pool(processes=cpu_count()) as pool:
        results = pool.map(scrape_page, urls)

    # aplanar la lista de resultados
    quotes = [quote for sublist in results for quote in sublist]

    print("Exporting scraped data to CSV")

    with open("quotes_multiprocessing.csv", "w", newline="", encoding="utf-8") as csvfile:
        fieldnames = ["text", "author", "tags"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(quotes)

    print("Citas exportadas a CSVn")

```

Por último, ejecuta la función `scrape_quotes()` mientras mides el tiempo de ejecución:

```none
if __name__ == "__main__":
    start_time = time.time()
    scrape_quotes()
    end_time = time.time()

    execution_time = end_time - start_time
    print(f"Tiempo de ejecución: {execution_time:.2f} segundos")

```

Ten en cuenta que la construcción `if __name__ == "__main__":` es necesaria para evitar que ciertas partes de tu código se ejecuten cuando se importa el módulo. Sin esta comprobación, el módulo multiprocessing puede intentar generar nuevos procesos que pueden provocar un comportamiento inesperado, especialmente en Windows.

Si lo juntamos todo, obtendremos:

```none
from multiprocessing import Pool, cpu_count
import requests
from bs4 import BeautifulSoup
import csv
import time

def scrape_page(url):
    print(f"Scraping page: '{url}'")

    response = requests.get(url)
    soup = BeautifulSoup(response.content, "html.parser")
    quote_html_elements = soup.select(".quote")

    quotes = []
    for quote_html_element in quote_html_elements:
        text = quote_html_element.select_one(".text").get_text()
        author = quote_html_element.select_one(".author").get_text()
        tags = [tag.get_text() for tag in quote_html_element.select(".tag")]
        quotes.append({
            "text": text,
            "author": author,
            "tags": ", ".join(tags)
        })

    print(f"Página '{url}' extraída correctamenten")

    return quotes

def scrape_quotes():
    urls = [
        "http://quotes.toscrape.com/",
        "https://quotes.toscrape.com/page/2/",
        "https://quotes.toscrape.com/page/3/",
        "https://quotes.toscrape.com/page/4/",
        "https://quotes.toscrape.com/page/5/",
        "https://quotes.toscrape.com/page/6/",
        "https://quotes.toscrape.com/page/7/",
        «https://quotes.toscrape.com/page/8/»,
        «https://quotes.toscrape.com/page/9/»,
        «https://quotes.toscrape.com/page/10/»
    ]

    # crear un grupo de procesos
    with Pool(processes=cpu_count()) as pool:
        results = pool.map(scrape_page, urls)

    # aplanar la lista de resultados
    quotes = [quote for sublist in results for quote in sublist]

    print("Exporting scraped data to CSV")

    with open("quotes_multiprocessing.csv", "w", newline="", encoding="utf-8") as csvfile:
        fieldnames = ["text", "author", "tags"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(quotes)

    print("Citas exportadas a CSVn")

if __name__ == "__main__":
    start_time = time.time()
    scrape_quotes()
    end_time = time.time()

    execution_time = end_time - start_time
    print(f"Tiempo de ejecución: {execution_time:.2f} segundos")

```

Vuelve a ejecutar el script. Esta vez, generará algunos registros como los siguientes:

```none
Raspando página: 'http://quotes.toscrape.com/'
Raspando página: 'https://quotes.toscrape.com/page/2/'
Raspando página: 'https://quotes.toscrape.com/page/3/'
Raspando página: 'https://quotes.toscrape.com/page/4/'
Página rastreada: «https://quotes.toscrape.com/page/5/»
Página rastreada: «https://quotes.toscrape.com/page/6/»
Página de rastreo: «https://quotes.toscrape.com/page/7/»
Página de rastreo: «https://quotes.toscrape.com/page/8/»
Página «http://quotes.toscrape.com/» rastreada correctamente

Página de rastreo: «https://quotes.toscrape.com/page/9/»
Página «https://quotes.toscrape.com/page/3/» extraída correctamente

Extraer página: «https://quotes.toscrape.com/page/10/»
Página «https://quotes.toscrape.com/page/4/» extraída correctamente.

Página «https://quotes.toscrape.com/page/5/» extraída correctamente.

Página «https://quotes.toscrape.com/page/6/» extraída correctamente.

Página «https://quotes.toscrape.com/page/7/» extraída correctamente.

Página «https://quotes.toscrape.com/page/2/» extraída correctamente.

Página «https://quotes.toscrape.com/page/8/» extraída correctamente.

Página «https://quotes.toscrape.com/page/9/» extraída correctamente

Página «https://quotes.toscrape.com/page/10/» extraída correctamente

Exportación de datos extraídos a CSV
Cotizaciones exportadas a CSV

Tiempo de ejecución: 1,87 segundos

```

Como puede ver, el orden de ejecución ya no es secuencial. Ahora su script puede extraer varias páginas simultáneamente. Concretamente, puede extraer hasta el número de núcleos disponibles en su CPU (8, en nuestro caso).

El procesamiento paralelo da como resultado una mejora del tiempo de alrededor del 145 %, **lo que reduce el tiempo de ejecución de 4,61 segundos a 1,87 segundos**. ¡Es impresionante!

**👍 Ventajas**:

- Gran mejora en el tiempo de ejecución
- Compatible de forma nativa con la mayoría de los lenguajes de programación

**👎 Desventajas**:

- Limitado por el número de núcleos disponibles en su máquina
- No respeta el orden de las URL en la lista
- Requiere muchos cambios en el código

### <a></a>3. Implementar el scraping multihilo

[El multithreading](https://www.techtarget.com/whatis/definition/multithreading) es una técnica de programación que permite ejecutar varios subprocesos simultáneamente dentro de un mismo proceso. Esto permite que tu script realice varias tareas a la vez, cada una de ellas gestionada por un subproceso específico.

Aunque es similar al multiprocesamiento, el multithreading no requiere necesariamente múltiples núcleos de CPU. Esto se debe a que un solo núcleo de CPU puede ejecutar numerosos subprocesos simultáneamente, compartiendo el mismo espacio de memoria. Profundiza en este concepto en nuestra guía sobre [concurrencia frente a paralelismo](/blog/web-data/concurrency-vs-parallelism).

Ten en cuenta que transformar un script de scraping de un enfoque secuencial a uno multihilo requiere cambios similares a los descritos en el capítulo anterior.

En esta implementación, utilizaremos `ThreadPoolExecutor` del módulo [`concurrent.futures`](https://docs.python.org/3/library/concurrent.futures.html) de Python. Puede importarlo como se indica a continuación:

```none
from concurrent.futures import ThreadPoolExecutor

```

`ThreadPoolExecutor` proporciona una interfaz de alto nivel para gestionar un grupo de subprocesos, ejecutándolos simultáneamente por usted.

Como antes, comience aislando la lógica para extraer una sola URL en una función, tal como lo hicimos en el capítulo anterior. La diferencia clave es que ahora necesita utilizar [`ThreadPoolExecutor`](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) para ejecutar la función en múltiples subprocesos:

```none
quotes = []

# crear un grupo de subprocesos con hasta 10 trabajadores
with ThreadPoolExecutor(max_workers=10) as executor:
    # utilizar map para aplicar la función scrape_page a cada URL
    results = executor.map(scrape_page, urls)

# combinar los resultados de todos los subprocesos
for result in results:
    quotes.extend(result)

```

De forma predeterminada, si `max_workers` es `None` o no se especifica, el valor predeterminado será el número de procesadores de tu máquina, multiplicado por 5. En este caso, solo tenemos 10 páginas, por lo que establecerlo en 10 estará bien. No olvides que abrir demasiados subprocesos puede ralentizar tu sistema y provocar problemas de rendimiento en lugar de mejoras.

El script completo de scraping contendrá el siguiente código:

```none
from concurrent.futures import ThreadPoolExecutor
import requests
from bs4 import BeautifulSoup
import csv
import time

def scrape_page(url):
    print(f"Scraping page: '{url}'")

    response = requests.get(url)
    soup = BeautifulSoup(response.content, "html.parser")
    quote_html_elements = soup.select(".quote")

    quotes = []
    for quote_html_element in quote_html_elements:
        text = quote_html_element.select_one(".text").get_text()
        author = quote_html_element.select_one(".author").get_text()
        tags = [tag.get_text() for tag in quote_html_element.select(".tag")]
        quotes.append({
            "text": text,
            "author": author,
            "tags": ", ".join(tags)
        })

    print(f"Página '{url}' extraída correctamenten")

    return quotes

def scrape_quotes():
    urls = [
        "http://quotes.toscrape.com/",
        "https://quotes.toscrape.com/page/2/",
        "https://quotes.toscrape.com/page/3/",
        "https://quotes.toscrape.com/page/4/",
        "https://quotes.toscrape.com/page/5/",
        "https://quotes.toscrape.com/page/6/",
        "https://quotes.toscrape.com/page/7/",
        «https://quotes.toscrape.com/page/8/»,
        «https://quotes.toscrape.com/page/9/»,
        «https://quotes.toscrape.com/page/10/»
    ]

    # dónde almacenar los datos extraídos
    quotes = []

    # crear un grupo de subprocesos con hasta 10 trabajadores
    with ThreadPoolExecutor(max_workers=10) as executor:
        # usar map para aplicar la función scrape_page a cada URL
        results = executor.map(scrape_page, urls)

    # combinar los resultados de todos los subprocesos
    for result in results:
        quotes.extend(result)

    print("Exportando datos extraídos a CSV")

    with open("quotes_multiprocessing.csv", "w", newline="", encoding="utf-8") as csvfile:
        fieldnames = ["text", "author", "tags"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(quotes)

    print("Citas exportadas a CSVn")

if __name__ == "__main__":
    start_time = time.time()
    scrape_quotes()
    end_time = time.time()

    execution_time = end_time - start_time
    print(f"Tiempo de ejecución: {execution_time:.2f} segundos")

```

Al ejecutarlo, se registrarán los siguientes mensajes:

```none
Raspando la página: 'http://quotes.toscrape.com/'
Raspando la página: 'https://quotes.toscrape.com/page/2/'
Raspando la página: 'https://quotes.toscrape.com/page/3/'
Raspando la página: 'https://quotes.toscrape.com/page/4/'
Raspando la página: 'https://quotes.toscrape.com/page/5/'
Raspando la página: 'https://quotes.toscrape.com/page/6/'
Raspando la página: 'https://quotes.toscrape.com/page/7/'
Página de rastreo: 'https://quotes.toscrape.com/page/8/'
Página de rastreo: 'https://quotes.toscrape.com/page/9/'
Página de rastreo: 'https://quotes.toscrape.com/page/10/'
Página «http://quotes.toscrape.com/» extraída correctamente

Página «https://quotes.toscrape.com/page/6/» extraída correctamente

Página «https://quotes.toscrape.com/page/7/» extraída correctamente

Página «https://quotes.toscrape.com/page/10/» extraída correctamente

Página «https://quotes.toscrape.com/page/8/» extraída correctamente

Página «https://quotes.toscrape.com/page/5/» extraída correctamente

Página «https://quotes.toscrape.com/page/9/» extraída correctamente

Página «https://quotes.toscrape.com/page/4/» extraída correctamente

Página «https://quotes.toscrape.com/page/3/» extraída correctamente

Página «https://quotes.toscrape.com/page/2/» extraída correctamente

Exportación de datos extraídos a CSV
Cotizaciones exportadas a CSV

Tiempo de ejecución: 0,52 segundos

```

Al igual que en el rastreo multiprocesamiento, el orden de ejecución de las páginas ya no es secuencial. En esta ocasión, la mejora en el rendimiento es aún mayor que con el multiprocesamiento. Esto se debe a que el script ahora puede ejecutar 10 solicitudes simultáneamente, superando el límite anterior de 8 solicitudes (el número de núcleos de la CPU).

La mejora en el tiempo es enorme, **de 4,61 segundos a 0,52 segundos**, lo que supone una reducción porcentual de alrededor del 885 %.

**👍 Ventajas**:

- Enorme mejora en el tiempo de ejecución
- Compatible de forma nativa con la mayoría de las tecnologías

**👎 Desventajas**:

- No es fácil encontrar el número adecuado de subprocesos
- No respeta el orden de las URL en la lista
- Requiere muchos cambios en el código

### <a></a>4. Uso de Async/Await Scraping

[La programación asíncrona](https://realpython.com/async-io-python/) es un paradigma de programación moderno que permite escribir código sin bloqueos. La idea es dar a los desarrolladores la capacidad de gestionar operaciones concurrentes sin tener que gestionar explícitamente el multithreading o el multiprocesamiento.

En un enfoque síncrono tradicional, cada operación debe terminar antes de que comience la siguiente. Esto puede dar lugar a ineficiencias, especialmente en tareas vinculadas a la E/S, como el Scraping web. Con la programación asíncrona, se pueden iniciar varias operaciones de E/S simultáneamente y luego esperar a que se completen. Esto mantiene el script receptivo y eficiente.

En Python, el scraping asíncrono se implementa generalmente utilizando el módulo [`asyncio`](https://docs.python.org/3/library/asyncio.html) de la biblioteca estándar. Este paquete proporciona la infraestructura para escribir código concurrente de un solo subproceso utilizando [corrutinas](https://docs.python.org/3/library/asyncio-task.html), a través de las palabras clave `async` y `await`.

Sin embargo, las bibliotecas HTTP estándar, como `requests`, no admiten operaciones asíncronas. Por lo tanto, es necesario utilizar un cliente HTTP asíncrono como [AIOHTTP](https://docs.aiohttp.org/en/stable/), que está diseñado específicamente para funcionar a la perfección con `asyncio`. Esta combinación le ayuda a enviar múltiples solicitudes HTTP simultáneamente sin bloquear la ejecución de su script.

Instale AIOHTTP utilizando el siguiente comando:

```none
pip install aiohttp

```

A continuación, importe `asyncio` y `aiohttp`:

```none
import asyncio
import aiohttp

```

Al igual que en los capítulos anteriores, encapsule la lógica para extraer una sola URL en una función. Sin embargo, esta vez, la función será asíncrona:

```none
async def scrape_url(session, url):
    async with session.get(url) as response:
        print(f"Scraping page: '{url}'")

        html_content = await response.text()
        soup = BeautifulSoup(html_content, "html.parser")
        # scraping logic...

```

Observe el uso de la función `await` para recuperar el HTML de la página web.

Para ejecutar la función en paralelo, cree una sesión AIOHTTP y recopile varias tareas de rastreo:

```none
# ejecutando las tareas de scraping de forma concurrente
async with aiohttp.ClientSession() as session:
    tasks = [scrape_url(session, url) for url in urls]
    results = await asyncio.gather(*tasks)

# aplanar la lista de resultados
quotes = [quote for sublist in results for quote in sublist]

```

Por último, utiliza `asyncio.run()` para ejecutar tu función principal de scraping asíncrono:

```none
if __name__ == "__main__":
    start_time = time.time()
    asyncio.run(scrape_quotes())
    end_time = time.time()

    execution_time = end_time - start_time
    print(f"Tiempo de ejecución: {execution_time:.2f} segundos")

```

Tu script de scraping asíncrono en Python contendrá estas líneas de código:

```none
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import csv
import time

async def scrape_url(session, url):
    async with session.get(url) as response:
        print(f"Rastreando página: '{url}'")

        html_content = await response.text()
        soup = BeautifulSoup(html_content, "html.parser")
        quote_html_elements = soup.select(".quote")

        quotes = []
        for quote_html_element in quote_html_elements:
            text = quote_html_element.select_one(".text").get_text()
            author = quote_html_element.select_one(".author").get_text()
            tags = [tag.get_text() for tag in quote_html_element.select(".tag")]
            quotes.append({
                "text": text,
                "author": author,
                "tags": ", ".join(tags)
            })

        print(f"Página '{url}' rastreada con éxiton")

        return quotes

async def scrape_quotes():
    urls = [
        "http://quotes.toscrape.com/",
        "https://quotes.toscrape.com/page/2/",
        "https://quotes.toscrape.com/page/3/",
        "https://quotes.toscrape.com/page/4/",
        "https://quotes.toscrape.com/page/5/",
        "https://quotes.toscrape.com/page/6/",
        "https://quotes.toscrape.com/page/7/",
        «https://quotes.toscrape.com/page/8/»,
        «https://quotes.toscrape.com/page/9/»,
        «https://quotes.toscrape.com/page/10/»
    ]

    # ejecutando las tareas de scraping simultáneamente
    async with aiohttp.ClientSession() as session:
        tasks = [scrape_url(session, url) for url in urls]
        results = await asyncio.gather(*tasks)

    # aplanar la lista de resultados
    quotes = [quote for sublist in results for quote in sublist]

    print("Exportando datos extraídos a CSV")

    with open("quotes_multiprocessing.csv", "w", newline="", encoding="utf-8") as csvfile:
        fieldnames = ["text", "author", "tags"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(quotes)

    print("Citas exportadas a CSVn")

if __name__ == "__main__":
    start_time = time.time()
    asyncio.run(scrape_quotes())
    end_time = time.time()

    execution_time = end_time - start_time
    print(f"Tiempo de ejecución: {execution_time:.2f} segundos")

```

Ejecútalo y obtendrás un resultado como este:

```none
Raspando la página: 'http://quotes.toscrape.com/'
Página 'http://quotes.toscrape.com/' raspada con éxito

Raspando la página: 'https://quotes.toscrape.com/page/3/'
Raspando la página: 'https://quotes.toscrape.com/page/7/'
Raspando la página: 'https://quotes.toscrape.com/page/9/'
Raspando la página: 'https://quotes.toscrape.com/page/6/'
Página rastreada: «https://quotes.toscrape.com/page/8/»
Página rastreada: «https://quotes.toscrape.com/page/10/»
Página «https://quotes.toscrape.com/page/3/» rastreada correctamente

Página de rastreo: 'https://quotes.toscrape.com/page/5/'
Página de rastreo: 'https://quotes.toscrape.com/page/4/'
Página 'https://quotes.toscrape.com/page/7/' rastreada correctamente

Página «https://quotes.toscrape.com/page/9/» extraída correctamente

Página «https://quotes.toscrape.com/page/6/» extraída correctamente

Extrayendo página: «https://quotes.toscrape.com/page/2/»
Página «https://quotes.toscrape.com/page/10/» extraída correctamente

Página «https://quotes.toscrape.com/page/5/» extraída correctamente

Página «https://quotes.toscrape.com/page/4/» extraída correctamente

Página «https://quotes.toscrape.com/page/8/» extraída correctamente.

Página «https://quotes.toscrape.com/page/2/» extraída correctamente.

Exportación de datos extraídos a CSV.
Cotizaciones exportadas a CSV.

Tiempo de ejecución: 0,51 segundos.

```

Tenga en cuenta que el tiempo de ejecución es similar al del enfoque multihilo, pero con la ventaja añadida de no tener que gestionar manualmente los hilos.

**👍 Ventajas**:

- Gran ahorro en el tiempo de ejecución
- La programación moderna se basa en la lógica asíncrona.
- No requiere la gestión manual de subprocesos o procesos

**👎 Desventajas**:

- No es tan fácil de dominar
- No respeta el orden de las URL en la lista
- Requiere bibliotecas asíncronas dedicadas

### <a></a>5. Otros consejos y enfoques para acelerar el scraping

Otras formas de acelerar el Scraping web son:

- **Optimización de la tasa de solicitudes**: ajusta los intervalos de solicitud para encontrar el equilibrio óptimo entre la velocidad y evitar la limitación de la tasa o el bloqueo.
- **Proxies rotativos**: utilice proxies rotativos para distribuir las solicitudes entre varias direcciones IP, lo que reduce las posibilidades de ser bloqueado y permite un rastreo más rápido. Vea los [mejores proxies rotativos](/blog/proxy-101/best-rotating-proxies).
- **Rastreo paralelo con sistemas distribuidos**: distribuya las tareas de rastreo entre varias máquinas en línea.
- **Reducir la representación de JavaScript**: Intente evitar las herramientas de automatización del navegador y dé preferencia a herramientas como los clientes HTTP como analizadores HTML. Recuerde que los navegadores consumen muchos recursos y son mucho más lentos que la mayoría de los analizadores HTML tradicionales.

## <a></a>Conclusión

En esta guía, hemos visto cómo acelerar el Scraping web. Hemos descubierto las principales razones por las que un script de Scraping web puede ser lento y hemos examinado varias técnicas para abordar estos problemas utilizando un script de Python de ejemplo. Con solo unos pocos ajustes en la lógica de Scraping web, hemos logrado una mejora de 8 veces en el tiempo de ejecución.

Si bien la optimización manual de la lógica de Scraping web es fundamental para acelerar el proceso de recuperación de datos, el uso de las herramientas adecuadas es igualmente importante. Cuando se trata de sitios dinámicos que requieren soluciones de automatización de navegadores, las cosas pueden complicarse, ya que los navegadores tienden a ser lentos y a consumir muchos recursos.

Para superar estos retos, prueba[el Navegador de scraping](/products/scraping-browser), una solución totalmente alojada en la nube y diseñada para el scraping. Se integra a la perfección con Puppeteer, Selenium, Playwright y otras herramientas populares de automatización de navegadores. Equipado con un [solucionador automático de CAPTCHA](/products/web-unlocker/captcha-solver) y respaldado por una [red de proxies residenciales de más de 150 millones de IPs](/proxy-types/residential-proxies), ofrece una escalabilidad ilimitada para cubrir cualquier necesidad de scraping.

Regístrese ahora y comience su prueba gratuita.



Contactar ventasPrueba gratuita![google social icon](/wp-content/themes/brightdata/assets/images/ic_google.svg)









 Tabla de Contenidos













 [ ](https://news.ycombinator.com/submitlink?t=C%C3%B3mo+acelerar+el+Scraping+web%3A+gu%C3%ADa+completa&u=https://brightdata.es/blog/datos-web/speed-up-web-scraping) [ ](https://www.linkedin.com/shareArticle?mini=true&title=C%C3%B3mo+acelerar+el+Scraping+web%3A+gu%C3%ADa+completa&url=https://brightdata.es/blog/datos-web/speed-up-web-scraping) [ ](http://www.reddit.com/submit?title=C%C3%B3mo+acelerar+el+Scraping+web%3A+gu%C3%ADa+completa&url=https://brightdata.es/blog/datos-web/speed-up-web-scraping)







##  Usted también puede estar interesado en

 [ ![OpenHuman with Bright Data](https://media.brightdata.es/2026/09/OpenHuman-with-Bright-Data.png) ](https://brightdata.es/blog/ai/openhuman-with-bright-data "Acceso Web Listo para Producción en OpenHuman a Través de la CLI de Bright Data")

 [AI



 ![Antonello Zanini](https://media.brightdata.es/2022/12/Antonello-Zanini-2-50x50.jpg)

Antonello Zanini

Technical Writer





### Acceso Web Listo para Producción en OpenHuman a Través de la CLI de Bright Data

Integra la CLI de Bright Data con OpenHuman para habilitar acceso web listo para producción y recopilación de datos para agentes de IA.



 09-Sep-2026

 14 min de lectura

 ](https://brightdata.es/blog/ai/openhuman-with-bright-data)

 [ ![Multimodal Web Scraping with MiniMax](https://media.brightdata.es/2026/09/Multimodal-Web-Scraping-with-MiniMax.png) ](https://brightdata.es/blog/datos-web/multimodal-web-scraping-with-minimax "Scraping Web Multimodal con MiniMax")

 [Datos web



 ![Antonello Zanini](https://media.brightdata.es/2022/12/Antonello-Zanini-2-50x50.jpg)

Antonello Zanini

Technical Writer





### Scraping Web Multimodal con MiniMax

Combina Bright Data Web Unlocker con la visión de MiniMax M3 para extraer datos estructurados de imágenes y capturas de pantalla de páginas web.



 09-Sep-2026

 5 min de lectura

 ](https://brightdata.es/blog/datos-web/multimodal-web-scraping-with-minimax)

 [ ![The 10 Best CLI Tools for Codex in 2026](https://media.brightdata.es/2026/08/The-10-Best-CLI-Tools-for-Codex-in-2026.png) ](https://brightdata.es/blog/ai/best-cli-tools-for-codex "Las 10 mejores herramientas CLI para Codex en 2026 – Probadas y clasificadas")

 [AI



 ![Daniel Shashko](https://media.brightdata.es/2022/04/Daniel-Shashko-2-50x50.png)

Daniel Shashko

Web Data &amp; AI Expert





### Las 10 mejores herramientas CLI para Codex en 2026 – Probadas y clasificadas

Las 10 herramientas CLI que hacen a Codex más rápido y capaz, comenzando con la Bright Data CLI para acceso web real desde dentro del sandbox.



 06-Sep-2026

 24 min de lectura

 ](https://brightdata.es/blog/ai/best-cli-tools-for-codex)
