|
Título: Ayuda con webscraping y cloudflare............. Publicado por: rasmus en 31 Mayo 2025, 14:50 pm Ayuda estoy pudiendo hacer descargas pero no logro hacer scroll... me gustaria aprender hacer el scraping evitando el bloqueo de cloudflare.
import os import re import requests from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from PIL import Image from io import BytesIO import time import json def configurar_driver(): """Configura Chrome para evitar detección""" chrome_options = Options() chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") chrome_options.add_argument("--disable-blink-features=AutomationControlled") chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) chrome_options.add_experimental_option('useAutomationExtension', False) chrome_options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") driver = webdriver.Chrome(options=chrome_options) driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") return driver def descargar_miniaturas_coleccion(url_coleccion, carpeta_destino="imagenes_hueforge"): """ Descarga específicamente las imágenes de portada/miniatura de la colección """ os.makedirs(carpeta_destino, exist_ok=True) driver = configurar_driver() try: print("🔗 Accediendo a la página de colección...") driver.get(url_coleccion) # Esperar a que cargue WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.TAG_NAME, "body")) ) # Scroll para cargar contenido dinámico print("📜 Cargando todos los elementos...") last_height = driver.execute_script("return document.body.scrollHeight") while True: driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(2) new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height print("🔍 Buscando miniaturas de modelos...") # Múltiples estrategias para encontrar las tarjetas de modelos modelos_encontrados = [] # Estrategia 1: Buscar contenedores de modelos selectores_contenedor = [ "[class*='model-card']", "[class*='model-item']", "[class*='card']", "[data-testid*='model']", "article", ".grid > div", "[class*='collection-item']" ] for selector in selectores_contenedor: try: elementos = driver.find_elements(By.CSS_SELECTOR, selector) print(f"📊 Selector '{selector}': {len(elementos)} elementos") for elemento in elementos: try: # Buscar imagen dentro del contenedor img = elemento.find_element(By.TAG_NAME, "img") src = img.get_attribute("src") # Buscar título del modelo titulo = None selectores_titulo = ["h1", "h2", "h3", "h4", "[class*='title']", "[class*='name']", "a"] for sel_titulo in selectores_titulo: try: elem_titulo = elemento.find_element(By.CSS_SELECTOR, sel_titulo) titulo = elem_titulo.text.strip() if titulo and len(titulo) > 2: break except: continue # Si no encuentra título, usar atributo alt de la imagen if not titulo: titulo = img.get_attribute("alt") or "modelo_sin_titulo" if src and titulo: modelos_encontrados.append({ 'src': src, 'titulo': titulo, 'elemento_html': elemento.get_attribute('outerHTML')[:200] }) except Exception as e: continue except Exception as e: print(f"❌ Error con selector {selector}: {e}") continue # Eliminar duplicados por URL de imagen urls_vistas = set() modelos_unicos = [] for modelo in modelos_encontrados: if modelo['src'] not in urls_vistas: urls_vistas.add(modelo['src']) modelos_unicos.append(modelo) print(f"📊 Miniaturas únicas encontradas: {len(modelos_unicos)}") if len(modelos_unicos) == 0: print("⚠️ No se encontraron miniaturas. Probando método alternativo...") # Método alternativo: todas las imágenes de la página todas_imagenes = driver.find_elements(By.TAG_NAME, "img") print(f"🖼️ Total de imágenes en la página: {len(todas_imagenes)}") for i, img in enumerate(todas_imagenes): src = img.get_attribute("src") alt = img.get_attribute("alt") or f"imagen_{i}" # Filtrar imágenes que parezcan miniaturas de modelos if src and any(keyword in src.lower() for keyword in ['thumb', 'preview', 'model', 'image']): modelos_unicos.append({ 'src': src, 'titulo': alt, 'elemento_html': f"img alt='{alt}'" }) # Guardar información de debug with open(os.path.join(carpeta_destino, "debug_modelos.json"), "w", encoding="utf-8") as f: json.dump(modelos_unicos, f, indent=2, ensure_ascii=False) # Descargar las miniaturas exitos = 0 errores = 0 for i, modelo in enumerate(modelos_unicos): titulo = modelo['titulo'] src = modelo['src'] print(f"⬇️ {i+1}/{len(modelos_unicos)}: {titulo[:50]}...") try: # Limpiar nombre del archivo titulo_limpio = re.sub(r'[<>:"/\\|?*]', '', titulo).strip() titulo_limpio = re.sub(r'\s+', '_', titulo_limpio)[:100] if descargar_imagen(src, titulo_limpio, carpeta_destino): exitos += 1 else: errores += 1 except Exception as e: print(f"❌ Error procesando {titulo}: {e}") errores += 1 print(f"\n📊 RESUMEN:") print(f"✅ Miniaturas descargadas: {exitos}") print(f"❌ Errores: {errores}") print(f"📁 Carpeta: {os.path.abspath(carpeta_destino)}") print(f"🔍 Ver debug_modelos.json para detalles") finally: driver.quit() def descargar_imagen(url, nombre_archivo, carpeta): """Descarga una imagen desde URL""" try: headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Referer": "https://pagina-.com/" } response = requests.get(url, headers=headers, timeout=30) response.raise_for_status() # Verificar que es una imagen válida img = Image.open(BytesIO(response.content)) # Convertir a RGB si es necesario if img.mode in ('RGBA', 'LA', 'P'): img = img.convert('RGB') # Guardar como JPG ruta_archivo = os.path.join(carpeta, f"{nombre_archivo}.jpg") img.save(ruta_archivo, "JPEG", quality=90) print(f"✅ {nombre_archivo}.jpg ({img.size[0]}x{img.size[1]})") return True except Exception as e: print(f"❌ Error descargando {nombre_archivo}: {e}") return False def mostrar_instrucciones_manuales(): """Muestra instrucciones para identificar las miniaturas correctas""" print(""" 🎯 IDENTIFICAR MINIATURAS MANUALMENTE: 1. Abre la colección en tu navegador 2. Presiona F12 → pestaña Elements 3. Click en el selector (flecha) y haz click en una miniatura de reloj 4. Observa el HTML para identificar la estructura Las miniaturas suelen estar en: - <img> dentro de contenedores como .model-card, .grid-item, article - URLs que contienen: thumb, preview, model, small - Tamaños típicos: 200x200, 300x300, 400x400 píxeles 🔧 Script manual para consola del navegador: """) script_manual = ''' // Ejecutar en consola (F12 → Console) // Buscar todas las imágenes que parezcan miniaturas let miniaturas = Array.from(document.querySelectorAll('img')) .filter(img => { let src = img.src; let width = img.naturalWidth || img.width; let height = img.naturalHeight || img.height; // Filtrar por tamaño y URL return src && (width >= 150 && width <= 500) && (height >= 150 && height <= 500) && (src.includes('thumb') || src.includes('preview') || src.includes('model')); }); console.log(`Miniaturas encontradas: ${miniaturas.length}`); // Mostrar información de cada miniatura miniaturas.forEach((img, i) => { console.log(`${i+1}. ${img.alt || 'Sin título'}`); console.log(` URL: ${img.src}`); console.log(` Tamaño: ${img.naturalWidth}x${img.naturalHeight}`); console.log('---'); }); // Descargar automáticamente (puede fallar por seguridad del navegador) miniaturas.forEach((img, i) => { let a = document.createElement('a'); a.href = img.src; a.download = `reloj_${i+1}_${(img.alt || 'modelo').replace(/[^a-zA-Z0-9]/g, '_')}.jpg`; document.body.appendChild(a); a.click(); document.body.removeChild(a); }); ''' print(script_manual) if __name__ == "__main__": url_coleccion = "https://pagina-.com/collections/1715414-wall-clock-hueforge" print("🎯 DESCARGADOR DE MINIATURAS DE COLECCIÓN") print("=" * 50) print("1. Descargar con Selenium (automático)") print("2. Mostrar instrucciones manuales") opcion = input("\nElige opción (1/2): ").strip() if opcion == "1": try: descargar_miniaturas_coleccion(url_coleccion) except Exception as e: print(f"❌ Error: {e}") print("\n💡 Si hay problemas, intenta la opción manual (2)") elif opcion == "2": mostrar_instrucciones_manuales() else: print("❌ Opción no válida") Título: Re: Ayuda con webscraping y cloudflare............. Publicado por: Bryantcore en 8 Junio 2025, 07:51 am Probablemente sea más útil https://github.com/ultrafunkamsterdam/undetected-chromedriver
Título: Re: Ayuda con webscraping y cloudflare............. Publicado por: Danielㅤ en 16 Agosto 2025, 23:45 pm Hola, aquí hay información de como lograr lo que deseas hacer:
https://stackoverflow.com/questions/20986631/how-can-i-scroll-a-web-page-using-selenium-webdriver-in-python https://www.browserstack.com/guide/selenium-scroll-down-python https://www.selenium.dev/documentation/webdriver/actions_api/wheel/ https://www.geeksforgeeks.org/software-testing/selenium-scrolling-a-web-page/ https://scrapeops.io/selenium-web-scraping-playbook/python-selenium-scroll-page/ Saludos Título: Re: Ayuda con webscraping y cloudflare............. Publicado por: @XSStringManolo en 17 Agosto 2025, 07:30 am Difícil ayudarte sin poder probar el código dado que no compartes la url y no descibres el comportamiento.
|