Cómo scrapear sitios web de comercio electrónico con Python

Comentarios: 0

Para el análisis de la competencia, el seguimiento de precios y la investigación de mercado es importante raspar datos de productos de sitios web de comercio electrónico. Puedes utilizar Python para scrapear datos de páginas de productos de forma eficiente. En esta guía, demostraremos cómo scrapear información de productos de tiendas online utilizando una combinación de peticiones y lxml.

El scraping de comercio electrónico implica extraer detalles de productos como nombres, precios e ID de tiendas online. Python, con sus versátiles librerías, hace que esta tarea sea eficiente y sencilla. En esta guía, vamos a scrapear información de productos del sitio web de Costco.

Escribir un script para extraer datos de productos

Antes de sumergirte en el proceso de scraping, asegúrate de tener instaladas las librerías necesarias de Python:

pip install requests
pip install lxml

Nos centraremos en extraer nombres de productos, características de productos y marcas de productos de páginas de productos específicas del sitio web.

Paso 1. Entender la estructura HTML del sitio web

Para extraer datos de cualquier sitio web, es necesario comprender la estructura de la página web. Abra una página web e inspeccione los elementos que desea raspar (por ejemplo, nombre del producto, marca de características, etc).

Paso 2. Enviar peticiones HTTP

En primer lugar, utilizaremos la librería requests para enviar peticiones HTTP GET a las páginas de producto. También configuraremos las cabeceras de las peticiones para imitar una petición real del navegador.


import requests

# Lista de URL de productos a raspar
urls = [
    "https://www.costco.com/kirkland-signature-men's-sneaker.product.4000216649.html",
    "https://www.costco.com/adidas-ladies'-puremotion-shoe.product.4000177646.html"
]

headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-US,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'sec-ch-ua': '"Not/A)Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
    'sec-ch-ua-mobile': '?0',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
}

# Recorrer cada URL y enviar una solicitud GET
for url in urls:
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        html_content = response.text
        # El tratamiento posterior se añadirá en etapas posteriores
    else:
        print(f"Failed to retrieve {url}. Status code: {response.status_code}")

Paso 3. Extracción de datos mediante XPath y lxml

Usando lxml, extraeremos los puntos de datos necesarios del HTML parseado.

from lxml import html

# Lista para almacenar los datos raspados
scraped_data = []

# Recorrer cada URL y enviar una solicitud GET
for url in urls:
    response = requests.get(url)
    if response.status_code == 200:
        html_content = response.content
        # Analizar contenido HTML con lxml
        tree = html.fromstring(html_content)
        
        # Extraer datos mediante XPath

        product_name = tree.xpath('//h1[@automation-id="productName"]/text()')[0].strip()
        product_feature = tree.xpath('//ul[@class="pdp-features"]//li//text()')
        product_brand = tree.xpath('//div[@itemprop="brand"]/text()')[0].strip()
        
        # Añadir los datos extraídos a la lista
        scraped_data.append({'Product Name': product_name, 'Product Feature': product_feature, 'Brand': product_brand})
    else:
        print(f"Failed to retrieve {url}. Status code: {response.status_code}")

# Imprimir los datos raspados
for item in scraped_data:
    print(item)

Paso 4. Abordar los posibles problemas

Los sitios web suelen implementar medidas anti-bot. Utilizar proxies y rotar los agentes de usuario puede ayudar a evitar la detección.

Usar proxies con autorización de IP:


proxies = {
    'http': 'http://your_proxy_ip:your_proxy_port',
    'https': 'https://your_proxy_ip:your_proxy_port'
}
response = requests.get(url, proxies=proxies)

Rotación de agentes de usuario:


import random

user_agents = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
    # Añadir más agentes de usuario según sea necesario
]

headers['user-agent'] = random.choice(user_agents)

response = requests.get(url, headers=headers)

Paso 5. Guardar los datos en un archivo CSV

Por último, guardaremos los datos scrapeados en un archivo CSV para su posterior análisis.

import csv

csv_file = 'costco_products.csv'
fieldnames = ['Product Name', 'Product Feature', 'Brand']

# Escritura de datos en un archivo CSV
try:
    with open(csv_file, mode='w', newline='', encoding='utf-8') as file:
        writer = csv.DictWriter(file, fieldnames=fieldnames)
        writer.writeheader()
        for item in scraped_data:
            writer.writerow(item)
    print(f"Data saved to {csv_file}")
except IOError:
    print(f"Error occurred while writing data to {csv_file}")

Complete code


import requests
import urllib3
from lxml import html
import csv
import random
import ssl

ssl._create_default_https_context = ssl._create_stdlib_context
urllib3.disable_warnings()

# Lista de URL de productos a raspar
urls = [
   "https://www.costco.com/kirkland-signature-men's-sneaker.product.4000216649.html",
   "https://www.costco.com/adidas-ladies'-puremotion-shoe.product.4000177646.html"
]

# cabeceras
headers = {
   'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
   'accept-language': 'en-US,en;q=0.9',
   'cache-control': 'no-cache',
   'dnt': '1',
   'pragma': 'no-cache',
   'sec-ch-ua': '"Not/A)Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
   'sec-ch-ua-mobile': '?0',
   'sec-fetch-dest': 'document',
   'sec-fetch-mode': 'navigate',
   'sec-fetch-site': 'same-origin',
   'sec-fetch-user': '?1',
   'upgrade-insecure-requests': '1',
   'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
}

# Lista de agentes de usuario para solicitudes rotativas
user_agents = [
   'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
   'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
   # Añadir más agentes de usuario según sea necesario
]


# Lista de proxies para solicitudes rotativas
proxies = [
    {'http': 'http://your_proxy_ip:your_proxy_port', 'https': 'https://your_proxy_ip:your_proxy_port'},
    {'http': 'http://your_proxy_ip2:your_proxy_port2', 'https': 'https://your_proxy_ip2:your_proxy_port2'},
    # Añadir más proxies según sea necesario
]

# Lista para almacenar los datos raspados
scraped_data = []

# Recorrer cada URL y enviar una solicitud GET
for url in urls:
   # Elija un agente de usuario aleatorio para las cabeceras de la solicitud
   headers['user-agent'] = random.choice(user_agents)
   # Elija un proxy aleatorio para la solicitud
   proxy = random.choice(proxies)

   # Enviar solicitud HTTP GET a la URL con cabeceras y proxy
   response = requests.get(url, headers=headers, proxies=proxy, verify=False)
   if response.status_code == 200:
       # Almacenar el contenido HTML de la respuesta
       html_content = response.content
       # Analizar contenido HTML con lxml
       tree = html.fromstring(html_content)

       # Extraer datos mediante XPath
       product_name = tree.xpath('//h1[@automation-id="productName"]/text()')[0].strip()
       product_feature = tree.xpath('//ul[@class="pdp-features"]//li//text()')
       product_brand = tree.xpath('//div[@itemprop="brand"]/text()')[0].strip()

       # Añadir los datos extraídos a la lista
       scraped_data.append({'Product Name': product_name, 'Product Feature': product_feature, 'Brand': product_brand})
   else:
       # Imprimir mensaje de error si falla la solicitud
       print(f"Failed to retrieve {url}. Status code: {response.status_code}")

# Configuración del archivo CSV
csv_file = 'costco_products.csv'
fieldnames = ['Product Name', 'Product Feature', 'Brand']

# Escritura de datos en un archivo CSV
try:
   with open(csv_file, mode='w', newline='', encoding='utf-8') as file:
       writer = csv.DictWriter(file, fieldnames=fieldnames)
       writer.writeheader()
       for item in scraped_data:
           writer.writerow(item)
   print(f"Data saved to {csv_file}")
except IOError:
   # Imprimir mensaje de error si falla la escritura en el archivo
   print(f"Error occurred while writing data to {csv_file}")

El uso de Python para scrapear desde sitios de comercio electrónico como Costco es un método eficaz para recopilar información de productos con el fin de analizarla y tomar decisiones estratégicas. La utilización adecuada de librerías como Requests así como Lxml da como resultado procesos de extracción automatizados que pueden manejar contenidos HTML sin olvidar la implementación de una API anti-bot de forma efectiva. Hay que tener en cuenta que siempre se deben seguir protocolos éticos de scraping.

Comentarios:

0 Comentarios