Volver al blog
Guías
Mihnea-Octavian Manolache22 de febrero de 202310 min de lectura

Paso a paso: Cómo evitar Cloudflare y mejorar tus esfuerzos de Web Scraping

Paso a paso: Cómo evitar Cloudflare y mejorar tus esfuerzos de Web Scraping

¿Cómo detecta Cloudflare los navegadores headless?

Cloudflare es una empresa tecnológica con una red gigantesca. Se centra en servicios como CDN, DNS y diversos sistemas de seguridad en línea. Su cortafuegos de aplicaciones web suele estar diseñado para proteger contra ataques como los DDoS o el cross-site scripting. En los últimos años, Cloudflare ha incorporado, al igual que otros proveedores del sector, sistemas de identificación (fingerprinting) capaces de detectar navegadores sin interfaz gráfica. Como es de suponer, uno de los primeros afectados por estas técnicas es Selenium. Y dado que el sector del web scraping depende en gran medida de esta tecnología, los scrapers también se ven directamente afectados.

Antes de pasar a las técnicas antibots, creo que es importante explicar cómo detecta Cloudflare a Selenium. Bueno, el sistema puede resultar bastante complejo. Por ejemplo, hay propiedades en un navegador de las que carece un controlador web. La interfaz `navigator` de un navegador cuenta incluso con una propiedad llamada `webdriver` que indica si el navegador está siendo controlado de forma automatizada. Y eso es una señal inequívoca. Si quieres probarlo:

  • Abra las herramientas de desarrollo de su navegador
  • Navegar a la consola
  • Escriba el siguiente comando: `navigator.webdriver`

En tu caso, debería devolver `false`. Pero si lo intentas con Puppeteer o Selenium, obtendrás `true`. Si te estás preguntando cómo Cloudflare aprovecha esto para detectar bots, pues es bastante sencillo. Todo lo que necesitan hacer es inyectar un script como el siguiente en el sitio web de su socio:

// detection-script.js

const webdriver = navigator.webdriver

// If webdriver returns true, display a reCaptcha

// In this example, I am transferring the user to a Cloudflare challenge page.

// But you get the idea

if ( webdriver ) location.replace('https://cloudflarechallenge.com')

Por supuesto, en la vida real, estos proveedores utilizan muchos más niveles de detección. Incluso el tamaño de la pantalla, la distribución del teclado o los complementos que utilizan los navegadores se emplean para identificar de forma específica un navegador. Si te interesa saber cómo funciona la detección sin navegador, echa un vistazo a mi sencilla prueba de service workers. Y eso solo si nos ceñimos al navegador. También puedes detectar la actividad de bots analizando la dirección IP desde la que se origina la solicitud. Por ejemplo, si utilizas direcciones IP de centros de datos, tus posibilidades de ser bloqueado aumentan con cada solicitud. Por eso se recomienda utilizar proxies residenciales o de ISP cuando se crea un rastreador web.

Cómo evitar Cloudflare con Selenium

Afortunadamente, la comunidad de web scraping es muy activa. Y como hay tanta demanda para eludir Cloudflare y otros proveedores anti-bot, existen soluciones de código abierto en ese ámbito. Se pueden conseguir grandes cosas cuando las comunidades de programadores trabajan juntas. Para avanzar, sugiero que sigamos estos pasos:

  • Haz algunas pruebas para ver si Selenium, en su configuración predeterminada, puede eludir Cloudflare
  • Añade algunas evasiones adicionales para que nuestros scripts sean más sigilosos

Así que empecemos con nuestro primer paso:

#1: ¿Puede Selenium por defecto eludir Cloudflare?

No soy de los que hacen suposiciones. Y eso es especialmente porque no sabemos con certeza cómo funcionan los sistemas de Cloudflare. Utilizan todo tipo de ofuscación con su código, lo que dificulta la ingeniería inversa. Por eso, a lo largo de mi experiencia como desarrollador, aprendí que probar es la mejor manera de entender cómo funciona un sistema. Así que vamos a construir un scraper básico y ver cómo se comporta en un objetivo real, protegido por Cloudflare.

1.1. Configurar el entorno

Con Python, es mejor aislar nuestros proyectos dentro de un único directorio. Así que vamos a crear una nueva carpeta, abrir una ventana de terminal y navegar hasta ella:

# Crea un nuevo entorno virtual y actívalo

~ » python3 -m venv env && source env/bin/activate

# Instala las dependencias

~ » python3 -m pip install selenium

# Crea un nuevo archivo .py y abre el proyecto en tu IDE

~ » touch app.py && code .

1.2. Construir un raspador web simple con Selenium

Ahora que ya has configurado correctamente tu proyecto, es hora de añadir algo de código. No vamos a crear nada muy complicado aquí. Solo necesitamos este script para hacer pruebas. Si quieres aprender sobre scraping avanzado, echa un vistazo a este [ENLACE](AQUÍ DEBE PUBLICARSE EL ARTÍCULO) sobre Pyppeteer.

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

# Configurar Chrome para que se abra en modo sin interfaz gráfica

options = Options()

options.headless = True

# Crear una nueva instancia de Chrome y navegar hasta la página de destino

driver = webdriver.Chrome(options=options)

driver.get('https://www.snipesusa.com/')

# Espera un momento a que se cargue

time.sleep(10)

# Haz una captura de pantalla de la página

driver.get_screenshot_as_file('screenshot.png')

# Cierra el navegador

driver.quit()

Ahora echa un vistazo a la captura de pantalla. Esto es lo que tengo:

Página de detección de bots que pide a los usuarios que mantengan pulsado para confirmar que son humanos

Creo que podemos concluir que la prueba ha fallado. El sitio web objetivo está protegido por Cloudflare y, como puede ver, se nos bloquea. Así que por defecto, Selenium no es capaz de eludir Cloudflare. No voy a profundizar y comprobar con otros proveedores de detección de bots. Si quieres hacer más pruebas, aquí tienes algunos objetivos y sus proveedores:

Tabla en la que se enumeran los sitios web de destino y sus proveedores de protección contra bots, incluidos Kasada y Akamai

#2: ¿Puede el sigiloso selenio eludir Cloudflare?

En primer lugar, permíteme aclarar los términos. Por «Selenium sigiloso» me refiero a una versión de Selenium que puede pasar desapercibida y eludir Cloudflare. No me refiero a ninguna técnica de ocultación específica. Hay varias formas de implementar técnicas de evasión en Selenium. Existen paquetes que se encargan de ello, o puedes utilizar `execute_cdp_cmd` para interactuar directamente con la API de Chrome. Esta última opción te ofrece más control, pero requiere más trabajo. A continuación te muestro un ejemplo de cómo podrías utilizarla para cambiar el valor del agente de usuario:

driver.execute_cdp_cmd('Emulation.setUserAgentOverride', {

               "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win32; x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",

               "platform": "Win32",

               "acceptLanguage":"ro-RO"

       })

Pero tendrías que pasar por CDP e identificar las APIs que te permiten hacer todos los cambios necesarios. Así que por el momento, vamos a probar con algunos paquetes.

1.1. Selenio sigiloso

Hay al menos dos paquetes que puede utilizar para hacer que Selenium sea sigiloso. Hasta este punto, sin embargo, ninguno de ellos está garantizado para eludir Cloudflare. Una vez más, tenemos que probar y ver si alguno de ellos funciona. En primer lugar, echemos un vistazo a `selenium-stealth`. Este paquete es un wrapper alrededor de `puppeteer-extra-plugin-stealth`, haciendo posible usar las evasiones de Puppeteer con Selenium de Python. Para usarlo, tienes que instalarlo primero. Abre una ventana de terminal e introduce este comando

# Instalar selenium-stealth

~ » python3 -m pip install selenium-stealth

Ya está todo listo. Podemos usarlo para hacer nuestro raspador anterior más sigiloso:

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

from selenium_stealth import stealth

import time

# Configurar Chrome para que se abra en modo sin interfaz gráfica

options = Options()

options.headless = True

# Crear una nueva instancia de Chrome

driver = webdriver.Chrome(options=options)

# Aplicar stealth a tu webdriver

stealth(driver,

   languages=["en-US", "en"],

   vendor="Google Inc.",

   platform="Win32",

   webgl_vendor="Intel Inc.",

   renderer="Intel Iris OpenGL Engine",

   fix_hairline=True,

)

# Navega hasta el destino

driver.get('https://www.snipesusa.com/')

# Dale un poco de tiempo para que se cargue

time.sleep(10)

# Haz una captura de pantalla de la página

driver.get_screenshot_as_file('stealth.png')

# Cierra el navegador

driver.quit()

Al ejecutar el script, esta vez obtuve un resultado diferente al de la configuración predeterminada de Selenium:

Banner de la página de inicio del sitio web de Snipes en el que aparece una modelo con una chaqueta de The North Face

La segunda opción que puedes utilizar es `undetected_chromedriver`. Se describe como un «chromedriver de Selenium optimizado». Probémoslo:

# Instalar undetected_chromedriver

~ » python3 -m pip install undetected_chromedriver

El código es muy similar a nuestro script por defecto. La principal diferencia está en el nombre del paquete. Aquí tenemos un scraper básico con `undetected_chromedriver` y veamos si puede evitar Cloudflare:

import undetected_chromedriver como uc

import time

# Configurar Chrome para que se abra en modo sin interfaz gráfica

options = uc.ChromeOptions()

options.headless = True

# Crear una nueva instancia de Chrome y maximizar la ventana

driver = uc.Chrome(options=options, executable_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome')

driver.maximize_window()

# Navegar al destino

driver.get('https://www.snipesusa.com/')

# Esperar un poco a que se cargue

time.sleep(10)

# Hacer una captura de pantalla de la página

driver.get_screenshot_as_file('stealth-uc.png')

# Cerrar el navegador

driver.quit()

Una vez más, al ejecutar el script me ha salido bien. Parece que, al menos, estos dos paquetes logran eludir con éxito la protección de Cloudflare. Al menos a corto plazo. A decir verdad, lo más probable es que, si utilizas estos scripts de forma habitual, Cloudflare detecte tu dirección IP y la bloquee.

Pues bien, permíteme presentarte una tercera opción: la API de web scraping.

1.2. Selenium con API de Web Scraping

La API de Web Scraping cuenta con una función increíble llamada «Modo proxy». Puedes leer más al respecto aquí. Pero lo que quiero destacar aquí es que nuestro Modo proxy se puede integrar perfectamente con Selenium. De esta forma, tendrás acceso a todas las funciones de evasión que hemos implementado. Y déjame decirte que contamos con un equipo dedicado que trabaja en técnicas de evasión personalizadas. En términos técnicos, gestionamos rotaciones de IP, utilizamos varios proxies, resolvemos captchas y usamos la API de Chrome para cambiar continuamente nuestra huella digital. En términos no técnicos, esto se traduce en menos complicaciones para ti y una mayor tasa de éxito. Básicamente, obtienes la versión más sigilosa de Selenium que existe. Y así es como se hace:

# Instalar selenium-wire

~ » python3 -m pip install selenium-wire

Estamos usando `selenium-wire` para usar Selenium con un proxy. Ahora aquí está el script:

from seleniumwire import webdriver

import time

# Method to encode parameters

def get_params(object):

   params = ''

   for key,value in object.items():

       if list(object).index(key) < len(object) - 1:

           params += f"{key}={value}."

       else:

           params += f"{key}={value}"

   return params

# Your WSA API key

API_KEY = '<YOUR_API_KEY>'

# Default proxy mode parameters

PARAMETERS = {

   "proxy_type":"datacenter",

   "device":"desktop",

   "render_js":1

}

# Set Selenium to use a proxy

options = {

   'proxy': {

       "http": f"http://webscrapingapi.{ get_params(PARAMETERS) }:{ API_KEY }@proxy.webscrapingapi.com:80",

   }

}

# Create a new Chrome instance

driver = webdriver.Chrome(seleniumwire_options=options)

# Navigate to target

driver.get('https://www.httpbin.org/get')

# Retrieve the HTML documeent from the page

html = driver.page_source

print(html)

# Close browser

driver.quit()

Si ejecutas este script un par de veces, verás como la dirección IP cambia cada vez. Ese es nuestro sistema de rotación de IP. En segundo plano, también añade técnicas de evasión. Ni siquiera necesitas preocuparte por ellas. Nosotros nos encargamos de la parte de evasión de Cloudflare para que puedas centrarte más en analizar los datos.

Conclusiones

Si quieres crear un rastreador capaz de eludir Cloudflare, debes tener en cuenta muchos factores. Un equipo dedicado puede trabajar las 24 horas del día, los 7 días de la semana, y aun así no hay garantía de que las estrategias de elusión funcionen siempre. Esto se debe a que, con cada lanzamiento de una nueva versión del navegador, existe la posibilidad de que se añadan nuevas funciones a la API. Y algunas de estas funciones pueden utilizarse para identificar y detectar bots.

Incluso diría que el mejor navegador para evitar Cloudflare y otros proveedores es el que construyes tú mismo. Y nosotros construimos uno en Web Scraping API. Ahora lo compartimos contigo. Así que ¡disfruta del scraping!

Acerca del autor
Mihnea-Octavian Manolache, desarrollador full stack en WebScrapingAPI
Mihnea-Octavian ManolacheDesarrollador Full Stack

Mihnea-Octavian Manolache es ingeniero Full Stack y DevOps en WebScrapingAPI, donde se encarga de desarrollar funciones para los productos y de mantener la infraestructura que garantiza el buen funcionamiento 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.