Voltar ao blogue
Guias
Mihnea-Octavian Manolache2 de maio de 202310 min de leitura

Saiba como contornar a deteção do Cloudflare com o melhor navegador Selenium

Saiba como contornar a deteção do Cloudflare com o melhor navegador Selenium

Como é que a Cloudflare detecta navegadores sem cabeça?

A Cloudflare é uma empresa de tecnologia com uma rede gigante. Concentram-se em serviços como CDN, DNS e vários sistemas de segurança online. A sua Web Application Firewall é normalmente concebida para proteger contra ataques como DDoS ou cross site scripting. Nos últimos anos, a Cloudflare e outros fornecedores do sector introduziram sistemas de impressão digital, capazes de detetar navegadores sem cabeça. Como se pode imaginar, um dos primeiros afectados por estas técnicas é o Selenium. E como a indústria de scraping da Web depende muito desta tecnologia, os scrapers também são diretamente afectados.

Antes de avançar para as técnicas anti-bot, penso que é importante discutir como o cloudflare detecta o Selenium. Bem, o sistema pode ser muito complexo. Por exemplo, existem propriedades em um navegador que um web driver não possui. A interface `navigator` em um navegador tem até mesmo uma propriedade chamada `webdriver` que indica se um navegador é controlado por automação. E isso é um sinal de alerta instantâneo. Se quiseres experimentar:

  • Abra as ferramentas de desenvolvimento do seu navegador
  • Navegar para a consola
  • Digite o seguinte comando: `navigator.webdriver`

No seu caso, ele deve retornar `false`. Mas se você tentar com o Puppeteer ou Selenium, você obterá `true`. Se você está se perguntando como o Cloudflare aproveita isso para detetar bots, bem, é bem simples. Tudo o que eles precisam fazer é injetar um script como o abaixo no site de seu parceiro:

// 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')

Claro que, na vida real, há muitos mais níveis de deteção que estes fornecedores utilizam. Até o tamanho do ecrã, a disposição do teclado ou os plug-ins utilizados pelos browsers são utilizados para identificar especificamente um browser. Se estiver interessado em saber como funciona a deteção sem navegador, veja o meu teste simples de trabalhador de serviço. E isto apenas se nos cingirmos ao browser. Você também pode detetar a atividade de bots examinando o endereço IP de onde a solicitação se origina. Por exemplo, se você estiver usando IPs de datacenter, suas chances de ser bloqueado aumentam a cada solicitação. É por isso que se recomenda a utilização de proxies residenciais ou de ISP quando se está a construir um web scraper.

Como contornar o Cloudflare com o Selenium

Felizmente, a comunidade de raspagem da Web é muito ativa. E como existe uma grande procura para contornar o Cloudflare e outros fornecedores anti-bot, existem soluções de código aberto nessa área. É possível fazer grandes coisas quando as comunidades de programação trabalham em conjunto! Para avançar, sugiro que sigamos estes passos:

  • Execute alguns testes para ver se o Selenium padrão pode contornar o Cloudflare
  • Adicionar algumas evasões extra para tornar os nossos scripts mais furtivos

Vamos então começar com o nosso primeiro passo:

#1: O Selenium padrão pode contornar o Cloudflare?

Não sou do género de fazer suposições. E isso deve-se sobretudo ao facto de não sabermos ao certo como funcionam os sistemas da Cloudflare. Eles usam todo tipo de ofuscação em seu código, o que dificulta a engenharia reversa. É por isso que, ao longo da minha experiência como desenvolvedor, aprendi que testar é a melhor maneira de entender como um sistema funciona. Então, vamos construir um scraper básico e ver como ele se comporta em um alvo real, protegido pelo Cloudflare.

1.1. Configurar o ambiente

Com Python, é melhor isolarmos os nossos projectos dentro de um único diretório. Por isso, vamos criar uma nova pasta, abrir uma janela de terminal e navegar até ela:

# Criar um novo ambiente virtual e ativá-lo

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

# Instalar dependências

~ » python3 -m pip install selenium

# Criar um novo ficheiro .py e abrir o projeto no seu IDE

~ » touch app.py && code .

1.2. Construir um simples raspador da Web com o Selenium

Agora que já configurou o seu projeto com sucesso, está na altura de adicionar algum código. Não vamos criar nada sofisticado aqui. Só precisamos deste script para fins de teste. Se quiser aprender sobre scraping avançado, veja este tutorial [LINK] sobre Pyppeteer.

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

# Configurar o Chrome para abrir em modo headless

options = Options()

options.headless = True

# Criar uma nova instância do Chrome e aceder ao destino

driver = webdriver.Chrome(options=options)

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

# Aguarde um pouco para que carregue

time.sleep(10)

# Capture uma imagem da página

driver.get_screenshot_as_file('screenshot.png')

# Feche o navegador

driver.quit()

Agora veja a captura de ecrã. Eis o que obtive:

Ecrã de verificação de proteção contra bots no site Snipes, solicitando ao utilizador que mantenha premido para confirmar que é humano

Penso que é seguro concluir que o teste falhou. O site visado é protegido pelo Cloudflare e, como você pode ver, estamos sendo bloqueados. Portanto, por padrão, o Selenium não é capaz de contornar o Cloudflare. Não vou me aprofundar e verificar com outros provedores de deteção de bots. Se quiser testar mais, aqui estão alguns alvos e seus fornecedores:

Tabela que lista sites e o fornecedor de proteção contra bots que utilizam, tais como Kasada, Akamai, DataDome e Incapsula

#2: O selénio furtivo pode contornar o Cloudflare?

Em primeiro lugar, deixe-me esclarecer os termos. Por Selenium furtivo quero dizer uma versão do Selenium que pode passar despercebida e contornar o Cloudflare. Não estou me referindo a nenhuma técnica específica de furtividade. Existem algumas maneiras de implementar técnicas de evasão no Selenium. Existem pacotes que tratam disso, ou você pode usar o `execute_cdp_cmd` para interagir diretamente com a API do Chrome. Este último permite mais controlo mas requer mais trabalho. Aqui está um exemplo de como você poderia usá-lo para alterar o valor do agente do utilizador:

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"

       })

Mas teria de passar pelo CDP e identificar as APIs que lhe permitem efetuar todas as alterações necessárias. Por isso, para já, vamos testar com alguns pacotes.

1.1. Selénio furtivo

Há pelo menos dois pacotes que você pode usar para tornar o Selenium furtivo. Até este ponto, porém, nenhum deles é garantido para contornar o Cloudflare. Mais uma vez, precisamos testar e ver se algum deles funciona. Primeiro de tudo, vamos dar uma olhada no `selenium-stealth`. Este pacote é um wrapper em torno do `puppeteer-extra-plugin-stealth`, tornando possível usar as evasões do Puppeteer com o Selenium do Python. Para usá-lo, é necessário instalá-lo primeiro. Abra uma janela de terminal e digite este comando:

# Instalar o selenium-stealth

~ » python3 -m pip install selenium-stealth

Já está tudo pronto. Podemos usá-lo para tornar o nosso raspador anterior mais furtivo:

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

from selenium_stealth import stealth

import time

# Configurar o Chrome para abrir em modo headless

options = Options()

options.headless = True

# Criar uma nova instância do Chrome

driver = webdriver.Chrome(options=options)

# Aplicar stealth ao seu webdriver

stealth(driver,

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

   vendor="Google Inc.",

   platform="Win32",

   webgl_vendor="Intel Inc.",

   renderer="Intel Iris OpenGL Engine",

   fix_hairline=True,

)

# Navegue até ao destino

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

# Dê algum tempo para carregar

time.sleep(10)

# Tire uma captura de ecrã da página

driver.get_screenshot_as_file('stealth.png')

# Feche o navegador

driver.quit()

Desta vez, ao executar o script, obtive alguns resultados diferentes, em comparação com as definições predefinidas do Selenium:

Captura de ecrã do site de vendas da Snipes, apresentando um banner promocional da The North Face

A segunda opção que pode ser utilizada é o `undetected_chromedriver`. Este é descrito como um 'chromedriver Selenium optimizado'. Vamos testá-lo:

# Instalar o undetected_chromedriver

~ » python3 -m pip install undetected_chromedriver

O código é muito semelhante ao nosso script predefinido. A principal diferença está no nome do pacote. Aqui está um scraper básico com `undetected_chromedriver` e vamos ver se ele consegue contornar o Cloudflare:

import undetected_chromedriver as uc

import time

# Configurar o Chrome para abrir no modo headless

options = uc.ChromeOptions()

options.headless = True

# Criar uma nova instância do Chrome e maximizar a janela

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

driver.maximize_window()

# Navegar até ao destino

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

# Aguardar algum tempo para carregar

time.sleep(10)

# Capturar imagem da página

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

# Fechar o navegador

driver.quit()

Mais uma vez, a execução do script resultou bem para mim. Parece que pelo menos estes dois pacotes conseguem contornar com sucesso a proteção do Cloudflare. Pelo menos a curto prazo. Verdade seja dita, é provável que, se você usar esses scripts extensivamente, o Cloudflare detecte seu endereço IP e o bloqueie. Por isso, deixe-me apresentar-lhe uma terceira opção: Web Scraping API.

1.2. Selenium com API de raspagem da Web

A API de raspagem da Web tem um recurso incrível chamado Modo Proxy. Você pode ler mais sobre ele aqui. Mas o que eu quero notar aqui é que nosso Modo Proxy pode ser integrado com sucesso ao Selenium. Desta forma, tem acesso a todas as funcionalidades de evasão que implementámos. E deixe-me dizer-lhe que temos uma equipa dedicada a trabalhar em técnicas de evasão personalizadas. Em termos técnicos, estamos a lidar com rotações de IP, estamos a utilizar vários proxies, estamos a resolver captchas e estamos a utilizar a API do Chrome para alterar continuamente a nossa impressão digital. Em termos não técnicos, isto traduz-se em menos complicações da sua parte e numa maior taxa de sucesso. Basicamente, obtém-se a versão mais furtiva do Selenium que existe. E aqui está como isso é feito:

# Instalar o selenium-wire

~ » python3 -m pip install selenium-wire

Estamos a utilizar o `selenium-wire` para utilizar o Selenium com um proxy. Agora aqui está o 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()

Se executar este script algumas vezes, verá como o endereço IP muda de cada vez. Este é o nosso sistema de rotação de IP. Em segundo plano, ele também adiciona técnicas de evasão. Nem sequer precisa de se preocupar com elas. Nós tratamos da parte de contornar o Cloudflare para que se possa concentrar mais na análise dos dados.

Conclusões

Se quiser construir um scraper que possa contornar o Cloudflare, precisa de ter em conta uma série de coisas. Uma equipa dedicada pode trabalhar 24 horas por dia, 7 dias por semana, e mesmo assim não há garantia de que as evasões funcionem sempre. Isso porque, a cada lançamento de versão de navegador, há uma chance de novos recursos serem adicionados à API. E algumas dessas funcionalidades podem ser utilizadas para identificar e detetar bots.

Diria mesmo que o melhor browser para contornar o Cloudflare e outros fornecedores é aquele que você mesmo constrói. E nós construímos um na Web Scraping API. Agora estamos a partilhá-lo consigo. Por isso, divirtam-se a fazer scraping!

Sobre o autor
Mihnea-Octavian Manolache, Desenvolvedor Full Stack na WebScrapingAPI
Mihnea-Octavian ManolacheDesenvolvedor Full Stack

Mihnea-Octavian Manolache é engenheiro Full Stack e DevOps na WebScrapingAPI, onde desenvolve funcionalidades do produto e mantém a infraestrutura que garante o bom funcionamento da plataforma.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.