Voltar ao blogue
Guias
Mihnea-Octavian Manolache22 de fevereiro de 202310 min de leitura

Passo-a-passo: Como contornar o Cloudflare e melhorar os seus esforços de Web Scraping

Passo-a-passo: Como contornar o Cloudflare e melhorar os seus esforços de Web Scraping

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 é uma indicação imediata. 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 plugins 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 discretos

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 hora de adicionar algum código. Não vamos criar nada de muito complexo aqui. Precisamos apenas deste script para fins de teste. Se quiser aprender sobre scraping avançado, consulte este [LINK](AQUI DEVE SER PUBLICADO O ARTIGOLUL) sobre o 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:

Página de deteção de bots que solicita aos utilizadores que mantenham premido para confirmar que são humanos

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 os sites de destino e os seus fornecedores de proteção contra bots, incluindo a Kasada e a Akamai

#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 lidam com isso, ou você pode usar o `execute_cdp_cmd` para interagir diretamente com a API do Chrome. Esta última opção permite-lhe 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 um resultado diferente, em comparação com as definições predefinidas do Selenium:

Banner da página inicial do site da Snipes, apresentando uma modelo com um casaco da North Face

A segunda opção que pode ser utilizada é o `undetected_chromedriver`. Este é descrito como um 'chromedriver Selenium otimizado'. 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, as chances são de que, se você usar esses scripts extensivamente, o Cloudflare vai pegar o seu endereço IP e bloqueá-lo.

Por isso, deixem-me apresentar-vos 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 trabalho 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, mas mesmo assim não há garantia de que as evasões funcionem sempre. Isso porque, a cada versão do 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.