Cómo raspar eBay en 2024: Guía para principiantes

Python, How to's, 21 de noviembre de 20245 minutos de lectura

eBay es uno de los mayores mercados en línea del mundo, que alberga millones de productos de diversas categorías. El scraping de eBay puede ser muy valioso para tareas como:

  • Comparación de precios
  • Análisis del mercado
  • Seguimiento de las tendencias de los productos

En esta guía, te mostraremos cómo crear un sencillo script en Python para buscar una palabra clave, extraer detalles del producto como título, precio, moneda, disponibilidad, reseñas y valoraciones, y guardar los datos en un archivo CSV. Este tutorial es ideal para principiantes que quieran aprender a hacer web scraping de la forma correcta, con consejos para respetar los términos de servicio y usar proxies de forma responsable.

¿Te has saltado la explicación? Aquí está el código completo

Si lo que buscas es la implementación completa, aquí tienes el script completo en Python para scrapear detalles de productos de eBay usando proxies. Cópialo y pégalo en tu entorno para empezar:

import re
import csv
import time

import requests
from bs4 import BeautifulSoup

proxies = {
    "http": "http://username:[email protected]:6060",
    "https": "http://username:[email protected]:6060",
}

def get_product_information(product_url) -> dict:
    r = requests.get(product_url, proxies=proxies)
    soup = BeautifulSoup(r.text, features="html.parser")

    product_title = soup.find("h1", {"class": "x-item-title__mainTitle"}).text
    product_price = soup.find("div", {"class": "x-price-primary"}).text.split(" ")[-1]
    currency = soup.find("div", {"class": "x-price-primary"}).text.split(" ")[0]

    # locate the element that holds quanity number of product
    quantity_available = soup.find("div", {"class":"x-quantity__availability"})
    if quantity_available is not None:
        # Using regex check if we can locate the strings that holds this number
        regex_pattern = r"\d+\savailable"
        if re.search(regex_pattern, quantity_available.text) is not None:
            quantity_available = re.search(regex_pattern, quantity_available.text).group()
            # After string is located we extract the number by splitting it by space and selecting the first element.
            quantity_available = quantity_available.split(" ")[0]
        else:
            quantity_available = "NA"

    total_reviews = soup.find("span", {"class":"ux-summary__count"})
    if total_reviews is not None:
        total_reviews = total_reviews.text.split(" ")[0]
    else:
        total_reviews = "NA"

    rating = soup.find("span", {"class":"ux-summary__start--rating"})
    if rating is not None:
        rating = rating.text
    else:
        rating = "NA"

    product_info = {
        "product_url": product_url,
        "title": product_title,
        "product_price": product_price,
        "currency": currency,
        "availability": quantity_available,
        "nr_reviews": total_reviews,
        "rating": rating
    }

    return product_info

def save_to_csv(products, csv_file_name="products.csv"):

    # Write the list of dictionaries to a CSV file
    with open(csv_file_name, mode='w', newline='') as csv_file:
        # Create a csv.DictWriter object
        writer = csv.DictWriter(csv_file, fieldnames=products[0].keys())

        # Write the header (keys of the dictionary)
        writer.writeheader()

        # Write the rows (values of the dictionaries)
        writer.writerows(products)

    print(f"Data successfully written to {csv_file_name}")

def main(keyword_to_search: str):
    products = []

    r = requests.get(f"https://www.ebay.com/sch/i.html?_nkw={keyword_to_search}", proxies=proxies)

    soup = BeautifulSoup(r.text, features="html.parser")
    for item in soup.find_all("div", {"class": "s-item__info clearfix"})[2::]:
        item_url = item.find("a").get("href")

        product_info: dict = get_product_information(item_url)
        print(product_info)
        # Adding a 1-second delay between requests to avoid overloading the server and reduce the risk of being blocked
        time.sleep(2)

        products.append(product_info)
    # save data to csv
    save_to_csv(products)


if __name__ == '__main__':
    keywords = "laptop bag"
    main(keywords)

Recuerde actualizar la variable proxies con un nuevo nombre de usuario y contraseña antes de utilizarlos.

Cómo rascaremos eBay

Nuestro método simplifica el proceso, centrándose en cuatro funciones clave:

  • Buscar una palabra clave: Descubra productos introduciendo un término de búsqueda (por ejemplo, "bolsas para portátiles") para obtener artículos relevantes.
  • Extracción de URL de productos: Recopile las URL de los productos listados en la primera página de los resultados de búsqueda para agilizar la recogida de datos.
  • Extracción de información del producto: Para cada URL de producto, navegaremos a la página del producto para recuperar información vital.
  • Guardar datos: Guarde los datos extraídos en un archivo CSV para un acceso y análisis eficientes.

Requisitos previos

Empezar con las herramientas adecuadas es crucial. Necesitarás:

Instalar Python:

Configure su entorno de desarrollo:

  • Seleccione el directorio en el que desea colocar este proyecto. Configure un entorno virtual para mantener las dependencias limpias y aisladas.
mkdir ebay_scraping
cd ebay_scraping
python -m venv venv
source env/bin/activate # En Windows use: venv\Scripts\activate
pip install peticiones bs4

Configuración de proxies:

En este ejemplo usaremos proxies residenciales Proxyscrape rotativos para mantener el anonimato y proteger la ip privada de ser incluida en listas negras.

Explicación del guión

Paso 1: Importar bibliotecas y proxies

Comenzamos importando las librerías necesarias para este proyecto de web scraping que incluyen:

  • CSV: este módulo proporciona clases para leer y escribir datos tabulares en formato CSV. Permite a los programadores escribir fácilmente datos en el formato preferido de Excel o leer datos de archivos generados por Excel sin conocer los detalles precisos del formato CSV.
  • Peticiones: este módulo permite enviar peticiones HTTP utilizando Python.
  • BeautifulSoup4 es un potente analizador html diseñado para extraer la información que necesita de una estructura html.

Importaciones requeridas:

importar csv
importar hora
importar peticiones
from bs4 import BeautifulSoup

Configuración del proxy:

Con el fin de mantener su IP privada minimizando así las posibilidades de obtener su IP en la lista negra de sitios web específicos, se recomienda realizar actividades de web scraping bajo el escudo de proxies, como se mencionó anteriormente vamos a utilizar la rotación Proxyscrape Residencial Proxies para este tutorial, pero se puede utilizar otros proxies o no proxies en absoluto.

proxies = {
   "http": "http://username:[email protected]:6060",
   "https": "http://username:[email protected]:6060",
}

Paso 2: Obtener resultados de búsqueda

Empecemos explicando el proceso de búsqueda que utilizaremos en este tutorial. Consultaremos la URL de eBay con la palabra clave "bolsa para portátil", como se muestra en esta imagen:

Utilizaremos la URL consultada para enviar una solicitud con request.get(). Una vez recibida la respuesta, analizaremos el contenido HTML con BeautifulSoup (bs4) para extraer la URL de cada producto. La siguiente imagen muestra dónde se encuentra la URL de cada producto dentro del HTML.

El enlace del producto se encuentra dentro de un <div> con el elemento clase s-item__info clearfix. Para extraer estos enlaces, utilizamos BeautifulSoup (bs4) para buscar todos <div> con esta clase específica. Una vez que hemos localizado estos elementos, iteramos a través de cada uno para encontrar <a> y extraer los elementos href que contiene la URL del producto.

def main(keyword_to_search: str):
   products = []

   r = requests.get(f"https://www.ebay.com/sch/i.html?_nkw={keyword_to_search}", proxies=proxies)

   soup = BeautifulSoup(r.text, features="html.parser")
   for item in soup.find_all("div", {"class": "s-item__info clearfix"})[2::]:
       item_url = item.find("a").get("href")

       product_info: dict = get_product_information(item_url)
		# Adding a 1-second delay between requests to avoid overloading the server and reduce the risk of being blocked
       time.sleep(1)

       products.append(product_info)
   # save data to csv
   save_to_csv(products)

Paso 3: Extracción de información sobre el producto

Presentación de la obtener_informacion_del_producto función. Esta función toma una URL de producto como entrada, envía una solicitud a esa URL y luego utiliza BeautifulSoup (bs4) para analizar la información del producto utilizando normas específicas y patrones regex.

def get_product_information(product_url) -> dict:
   r = requests.get(product_url, proxies=proxies)
   soup = BeautifulSoup(r.text, features="html.parser")

   product_title = soup.find("h1", {"class": "x-item-title__mainTitle"}).text
   product_price = soup.find("div", {"class": "x-price-primary"}).text.split(" ")[-1]
   currency = soup.find("div", {"class": "x-price-primary"}).text.split(" ")[0]

   # locate the element that holds quanity number of product
   quantity_available = soup.find("div", {"class":"x-quantity__availability"})
   if quantity_available is not None:
       # Using regex check if we can locate the strings that holds this number
       regex_pattern = r"\d+\savailable"
       if re.search(regex_pattern, quantity_available.text) is not None:
           quantity_available = re.search(regex_pattern, quantity_available.text).group()
           # After string is located we extract the number by splitting it by space and selecting the first element.
           quantity_available = quantity_available.split(" ")[0]
       else:
           quantity_available = "NA"

   total_reviews = soup.find("span", {"class":"ux-summary__count"})
   if total_reviews is not None:
       total_reviews = total_reviews.text.split(" ")[0]
   else:
       total_reviews = "NA"

   rating = soup.find("span", {"class":"ux-summary__start--rating"})
   if rating is not None:
       rating = rating.text
   else:
       rating = "NA"

   product_info = {
       "product_url": product_url,
       "title": product_title,
       "product_price": product_price,
       "currency": currency,
       "availability": quantity_available,
       "nr_reviews": total_reviews,
       "rating": rating
   }

   return product_info

Por último, organizamos las entidades de producto analizadas en un diccionario, que es devuelto por la función.

Paso 4: Guardar los resultados

Es hora de almacenar estos resultados en un archivo CSV utilizando la herramienta nativa de Python csv biblioteca. En save_to_csv(productos) la función acepta productos como entrada, que es una lista de diccionarios que contienen detalles de productos como se ha descrito anteriormente. A continuación, estos datos se guardan en un archivo CSV con el nombre nombre_archivo_csv que, por defecto, es "productos.csv".

def save_to_csv(products, csv_file_name="products.csv"):

   # Write the list of dictionaries to a CSV file
   with open(csv_file_name, mode='w', newline='') as csv_file:
       # Create a csv.DictWriter object
       writer = csv.DictWriter(csv_file, fieldnames=products[0].keys())

       # Write the header (keys of the dictionary)
       writer.writeheader()

       # Write the rows (values of the dictionaries)
       writer.writerows(products)

   print(f"Data successfully written to {csv_file_name}")

Conclusión

En este tutorial, demostramos cómo scrapear eBay construyendo un script en Python que busca una palabra clave, extrae detalles del producto y guarda los datos en un archivo CSV. Este proceso pone de relieve técnicas esenciales de scraping como el manejo de elementos HTML, el uso de proxies para el anonimato y el respeto de las prácticas éticas de scraping. Este script puede mejorarse aún más incorporando la función de paginación y la posibilidad de procesar varias palabras clave.

Recuerda siempre realizar el scraping de forma responsable, respetar las condiciones de servicio de los sitios web y utilizar herramientas como la limitación de velocidad para evitar interrupciones. Para que sus tareas de scraping sean más fiables y eficientes, considere la posibilidad de explorar nuestros servicios proxy de alta calidad en ProxyScrape. Tanto si necesita proxies residenciales, para centros de datos o móviles, tenemos todo lo que necesita. Eche un vistazo a nuestras ofertas para llevar sus proyectos de web scraping al siguiente nivel.

¡Feliz raspado!