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:
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.
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.
Nuestro método simplifica el proceso, centrándose en cuatro funciones clave:
Empezar con las herramientas adecuadas es crucial. Necesitarás:
mkdir ebay_scraping
cd ebay_scraping
python -m venv venv
source env/bin/activate # En Windows use: venv\Scripts\activate
pip install peticiones bs4
En este ejemplo usaremos proxies residenciales Proxyscrape rotativos para mantener el anonimato y proteger la ip privada de ser incluida en listas negras.
Comenzamos importando las librerías necesarias para este proyecto de web scraping que incluyen:
importar csv
importar hora
importar peticiones
from bs4 import BeautifulSoup
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",
}
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)
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.
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}")
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!