Volver al blog
Guías
Ștefan RăcilăLast updated on Mar 31, 20268 min read

Cómo crear un rastreador web con Python: guía para principiantes

Cómo crear un rastreador web con Python: guía para principiantes

El rastreo web es el proceso de visitar automáticamente páginas web y extraer información útil de ellas. Un rastreador web, también conocido como araña o bot, es un programa que realiza esta tarea. En este artículo, veremos cómo crear un rastreador web utilizando el lenguaje de programación Python. En concreto, crearemos dos rastreadores web.

Crearemos un rastreador web sencillo desde cero en Python utilizando las bibliotecas Requests y BeautifulSoup. A continuación, hablaremos de las ventajas de utilizar un marco de rastreo web como Scrapy. Y, por último, crearemos un rastreador de ejemplo con Scrapy para recopilar datos de todos los productos para bebés de Amazon. También veremos cómo Scrapy se adapta a sitios web con varios millones de páginas.

Requisitos previos

Antes de seguir este artículo, necesitarás tener conocimientos básicos de Python y tenerlo instalado en tu ordenador. Además, tendrás que instalar los módulos Requests y BeautifulSoup. Esto se puede hacer ejecutando el siguiente comando en el símbolo del sistema o en la terminal:

$ pip install requests bs4

Para la segunda parte de este artículo, en la que crearemos un rastreador web de ejemplo utilizando Scrapy, necesitarás instalar el marco de trabajo Scrapy. Los creadores de este marco recomiendan encarecidamente instalar Scrapy en un entorno virtual dedicado, para evitar conflictos con los paquetes de tu sistema.

Te sugiero que instales virtualenv y virtualenvwrapper para crear un entorno Python aislado. Ten en cuenta que existe una versión de virtualenvwrapper para Windows llamada virtualenvwrapper-win.

También tendrás que instalar pipx a través de pip para instalar virtualenv.

$ python -m pip install --user pipx

$ python -m pipx ensurepath

Una vez creado un entorno Python aislado, puedes instalar Scrapy con el siguiente comando.

$ pip install Scrapy

Puedes encontrar la guía de instalación de Scrapy aquí.

¿Qué es un rastreador web?

El rastreo web y el scraping web son conceptos relacionados pero distintos. El scraping web es el proceso general de extraer datos de un sitio web. El rastreo web es la tarea específica de navegar automáticamente por las páginas web para encontrar las URL que deben ser objeto de scraping.

Un rastreador web comienza con una lista de URL a las que navegar, conocida como «semilla». A medida que navega por cada URL, busca enlaces en el HTML y los filtra según criterios específicos. Cualquier enlace nuevo que se encuentre se añade a una cola para su procesamiento posterior. El HTML extraído o la información especificada se pasa entonces a otro canal para su posterior procesamiento.

Al crear un rastreador web, es importante tener en cuenta que no se visitarán todas las páginas de un sitio web. El número de páginas visitadas depende del presupuesto del rastreador, la profundidad del rastreo o el tiempo asignado para la ejecución.

Muchos sitios web tienen un archivo robots.txt que indica qué partes del sitio web se pueden rastrear y cuáles deben evitarse. Además, algunos sitios web tienen un sitemap.xml que es más explícito que el robots.txt e indica específicamente a los bots qué páginas deben rastrearse, además de proporcionar metadatos adicionales para cada URL.

Los rastreadores web se utilizan habitualmente para diversos fines:

  • Las herramientas de análisis SEO recopilan metadatos como el tiempo de respuesta y el estado de la respuesta, además del código HTML, para detectar páginas rotas y enlaces entre diferentes dominios con el fin de recopilar backlinks.
  • Las herramientas de monitorización de precios rastrean sitios web de comercio electrónico para encontrar páginas de productos y extraer metadatos, concretamente precios. A continuación, se vuelven a visitar periódicamente las páginas de productos.
  • Los motores de búsqueda, como Googlebot, Bingbot y Yandex Bot, recopilan todo el HTML de una parte significativa de la web y utilizan los datos para que sea consultable.

Más adelante en este artículo, compararemos dos enfoques diferentes para crear un rastreador web en Python. El primer enfoque consiste en utilizar la biblioteca Requests para realizar solicitudes HTTP y BeautifulSoup para analizar el contenido HTML. El segundo enfoque consiste en utilizar un marco de rastreo web. Utilizaremos Scrapy.

Uso de las bibliotecas Requests y BeautifulSoup

El módulo requests de Python es una potente herramienta para realizar solicitudes HTTP. Para utilizarlo en el rastreo web, puedes empezar importando el módulo y realizando una solicitud a una URL específica. Por ejemplo:

url = 'https://amazon.com/s?k=baby+products'

response = requests.get(url)

Una vez obtenida la respuesta, puedes extraer todos los enlaces del contenido HTML utilizando BeautifulSoup. Por ejemplo:

import json

from urllib.parse import urljoin

from bs4 import BeautifulSoup

html = response.text

links = []

soup = BeautifulSoup(html, 'html.parser')

for link in soup.find_all('a'):

    path = link.get('href')

    if path and path.startswith('/'):

        path = urljoin(url, path)

   

    links.append(path)

print(json.dumps(links, sort_keys = True, indent = 2))

A continuación, puedes recorrer los enlaces y realizar solicitudes a ellos, repitiendo el proceso hasta que hayas visitado todas las páginas que deseas rastrear. Esta es una función recursiva que actúa precisamente así:

import requests

from urllib.parse import urljoin

from bs4 import BeautifulSoup

import logging

logging.basicConfig(

    format='%(asctime)s %(levelname)s:%(message)s',

    level=logging.INFO)

url = 'https://amazon.com/s?k=baby+products'

visited = []

def crawl(url):

    logging.info(f'Crawling: {url}')

    visited.append(url)

    html = ''

    try:

        html = requests.get(url).text

    except Exception:

        logging.exception(f'Failed to crawl: {url}')

        return

        

    soup = BeautifulSoup(html, 'html.parser')

    # here you can extract and store useful data from the page

    for link in soup.find_all('a'):

        path = link.get('href')

        if path and path.startswith('/'):

            path = urljoin(url, path)

        

        if path not in visited:

            crawl(path)

crawl(url)

La función registra una línea por cada URL visitada.

2023-01-16 09:20:51,681 INFO:Crawling: https://amazon.com/s?k=baby+products

2023-01-16 09:20:53,053 INFO:Crawling: https://amazon.com/ref=cs_503_logo

2023-01-16 09:20:54,195 INFO:Crawling: https://amazon.com/ref=cs_503_link

2023-01-16 09:20:55,131 INFO:Crawling: https://amazon.com/dogsofamazon/ref=cs_503_d

2023-01-16 09:20:56,549 INFO:Crawling: https://www.amazon.com/ref=nodl_?nodl_android

2023-01-16 09:20:57,071 INFO:Crawling: https://www.amazon.com/ref=cs_503_logo

2023-01-16 09:20:57,690 INFO:Crawling: https://www.amazon.com/ref=cs_503_link

2023-01-16 09:20:57,943 INFO:Crawling: https://www.amazon.com/dogsofamazon/ref=cs_503_d

2023-01-16 09:20:58,413 INFO:Crawling: https://www.amazon.com.au/ref=nodl_&nodl_android

2023-01-16 09:20:59,555 INFO:Crawling: None

2023-01-16 09:20:59,557 ERROR:Failed to crawl: None

Aunque el código de un rastreador web básico pueda parecer sencillo, hay muchos retos que deben superarse para rastrear con éxito un sitio web completo. Entre ellos se incluyen cuestiones como:

  • La lógica de las URL de descarga carece de un mecanismo de reintento y la cola de URL no es muy eficiente con un gran número de URL.
  • El rastreador no se identifica e ignora el archivo robots.txt.
  • El rastreador es lento y no admite el paralelismo. Cada URL tarda aproximadamente un segundo en rastrearse, y el rastreador espera una respuesta antes de pasar a la siguiente URL.
  • La lógica de extracción de enlaces no admite la estandarización de URL mediante la eliminación de parámetros de cadena de consulta, no gestiona URL de anclaje/fragmento relativas (como href="#anchor") y no admite el filtrado de URL por dominio ni el filtrado de solicitudes a archivos estáticos.

En la siguiente sección, veremos cómo Scrapy aborda estos problemas y facilita la ampliación de la funcionalidad del rastreador web para casos de uso personalizados.

Cómo crear un rastreador web en Python utilizando el marco Scrapy

Scrapy es un potente marco de trabajo para crear rastreadores web en Python. Proporciona una forma integrada de seguir enlaces y extraer información de páginas web. Tendrás que crear un nuevo proyecto de Scrapy y una araña para definir el comportamiento de tu rastreador.

Antes de empezar a rastrear un sitio web como Amazon, es importante consultar el archivo robots.txt del sitio web para ver qué rutas URL están permitidas. Scrapy lee automáticamente este archivo y lo sigue cuando la configuración ROBOTSTXT_OBEY está establecida en true, que es el valor predeterminado para los proyectos creados con el comando de Scrapy `startproject`.

Para crear un nuevo proyecto de Scrapy, debes ejecutar el siguiente comando:

$ scrapy startproject amazon_crawler

Este comando generará un proyecto con la siguiente estructura:

amazon_crawler/

├── scrapy.cfg

└── amazon_crawler

    ├── __init__.py

    ├── items.py

    ├── middlewares.py

    ├── pipelines.py

    ├── settings.py

    └── spiders

        ├── __init__.py

Para crear una araña, utiliza el comando `genspider` de la CLI de Scrapy. El comando tiene la siguiente definición:

$ scrapy genspider [options] <name> <domain>

Para generar una araña para este rastreador, podemos ejecutar:

$ cd amazon_crawler

$ scrapy genspider baby_products amazon.com

Debería crear un archivo llamado `baby_products.py` dentro de la carpeta llamada `spiders` y generar este código:

import scrapy

class BabyProductsSpider(scrapy.Spider):

    name = 'wikipedia'

    allowed_domains = ['en.wikipedia.com']

    start_urls = ['http://en.wikipedia.com/']

    def parse(self, response):

        pass

Scrapy también ofrece una variedad de clases de arañas predefinidas, como CrawlSpider, XMLFeedSpider, CSVFeedSpider y SitemapSpider. La clase CrawlSpider, que se basa en la clase Spider base, incluye un atributo adicional «rules» para definir cómo navegar por un sitio web. Cada regla utiliza un LinkExtractor para determinar qué enlaces deben extraerse de cada página.

Para nuestro caso de uso, debemos heredar nuestra clase Spider de CrawlSpider. También tendremos que crear una regla LinkExtractor que indique al rastreador que extraiga enlaces únicamente de la paginación de Amazon. Recuerda que nuestro objetivo era recopilar datos de todos los productos para bebés de Amazon, por lo que en realidad no queremos seguir todos los enlaces que encontremos en la página.

A continuación, debemos crear otros dos métodos en nuestra clase: `parse_item` y `parse_product`. `parse_item` se pasará como función de callback a nuestra regla LinkExtractor y se invocará con cada enlace extraído. `parse_product` analizará cada producto… ¯\_(ツ)_/¯

from scrapy.spiders import CrawlSpider, Rule

from scrapy.linkextractors import LinkExtractor

from bs4 import BeautifulSoup

class BabyProductsSpider(CrawlSpider):

    name = 'baby_products'

    allowed_domains = ['amazon.com']

    start_urls = ['https://amazon.com/s?k=baby+products']

    rules = (

        Rule(

            LinkExtractor(

                restrict_css='.s-pagination-strip'

            ),

            callback='parse_item',

            follow=True),

        )

    def parse_item(self, response):

        soup = BeautifulSoup(response.text, 'html.parser')

        products = soup.select('div[data-component-type="s-search-result"]')

        data = []

        for product in products:

            parsed_product = self.parse_product(product)

            if (parsed_product != 'error'):

                data.append(parsed_product)

        return {

            'url': response.url,

            'data': data

        }

    def parse_product(self, product):

        try:

            link = product.select_one('a.a-text-normal')

            price = product.select_one('span.a-price > span.a-offscreen').text

            return {

                'product_url': link['href'],

                'name': link.text,

                'price': price

            }

        except:

            return 'error'

Para iniciar el rastreador, puedes ejecutar:

$ scrapy crawl baby_products

Verás muchos registros en la consola (puedes especificar un archivo de registro con `--logfile [nombre_del_archivo_de_registro]`).

He utilizado Amazon Search como ejemplo para mostrar los conceptos básicos de la creación de un rastreador web en Python. Sin embargo, el rastreador no encuentra muchos enlaces que seguir y no está diseñado para un caso de uso específico de los datos. Si deseas extraer datos específicos de Amazon Search, puedes considerar el uso de nuestra API de datos de productos de Amazon. Hemos creado analizadores personalizados para las páginas de búsqueda, productos y categorías de Amazon, y devuelve datos en formato JSON listos para ser utilizados en tu aplicación.

¿Por qué es mejor utilizar un servicio de scraping profesional que un rastreador?

Aunque el rastreo web puede ser una herramienta útil para extraer datos de Internet, su configuración puede resultar compleja y llevar mucho tiempo. Además, el scraping web puede infringir los términos de servicio de algunos sitios web y provocar que se bloquee tu IP o incluso que se emprendan acciones legales contra ti.

Por otro lado, los servicios profesionales de scraping utilizan técnicas y tecnologías avanzadas para eludir las medidas anti-scraping y extraer datos sin ser detectados. También se encargan del mantenimiento y la escalabilidad de la infraestructura de scraping, lo que te permite centrarte en analizar y utilizar los datos. Además, ofrecen un mayor nivel de precisión y exhaustividad de los datos, ya que son capaces de gestionar casos de uso de extracción de datos más avanzados y pueden encargarse de trabajos de scraping a gran escala.

Resumen

En conclusión, aunque el rastreo web puede ser una herramienta útil para extraer datos de Internet, su configuración puede resultar laboriosa y compleja. Además, el rastreo web puede infringir los términos de servicio de algunos sitios web y puede dar lugar a que se bloquee tu IP o incluso a que se emprendan acciones legales contra ti. Por lo tanto, para trabajos de scraping más avanzados y a gran escala, es mejor utilizar un servicio de scraping profesional.

Si busca una alternativa al rastreo por su cuenta, considere utilizar WebScrapingAPI. WebScrapingAPI es un servicio profesional de scraping web que le permite extraer datos fácilmente de sitios web sin necesidad de crear y mantener su propio scraper web.

Es una solución rápida, fiable y rentable, adecuada para empresas de todos los tamaños.

¿Por qué no lo pruebas hoy mismo? Es gratis y ofrecemos una prueba de 14 días sin necesidad de tarjeta de crédito.

Acerca del autor
Ștefan Răcilă, Desarrollador Full Stack @ WebScrapingAPI
Ștefan RăcilăDesarrollador Full Stack

Stefan Racila es ingeniero de DevOps y Full Stack en WebScrapingAPI, donde se encarga de desarrollar funciones para los productos y de mantener la infraestructura que garantiza la fiabilidad de la plataforma.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.