Voltar ao blogue
Guias
Mihnea-Octavian ManolacheLast updated on Mar 31, 20268 min read

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

Hoje em dia, o web scraping tornou-se uma tarefa verdadeiramente desafiante. Se já alguma vez criou um web scraper com um navegador headless, certamente já se deparou com alguns sistemas anti-bot. E contornar o Cloudflare, o Datadome ou qualquer outro fornecedor de soluções anti-bot, aliás, não é tarefa fácil. Tem de pensar primeiro em estratégias de evasão e, depois, implementá-las em produção. E, mesmo assim, podem existir cenários que nunca tenha previsto.

No entanto, sem pelo menos uma implementação mínima destas técnicas de evasão, as suas hipóteses de ser detetado e bloqueado são muito elevadas. É por isso que o tema do artigo de hoje é como contornar a deteção do Cloudflare. E a maioria das técnicas que vamos discutir aplica-se também a outros fornecedores de deteção. A título de referência, vamos concentrar-nos no Selenium para ver se conseguimos torná-lo furtivo. Ao longo do artigo, entre outros aspetos, irei discutir:

  • Métodos de deteção de bots
  • Técnicas gerais de evasão anti-bot
  • Técnicas avançadas de evasão para o Selenium

Como é que o Cloudflare deteta navegadores headless?

A Cloudflare é uma empresa de tecnologia com uma rede gigantesca. Concentra-se em serviços como CDN, DNS e vários sistemas de segurança online. O seu Web Application Firewall é normalmente concebido para proteger contra ataques como DDoS ou cross site scripting. Nos últimos anos, a Cloudflare adicionou, e outros fornecedores na área introduziram, sistemas de fingerprinting, capazes de detetar navegadores headless. Como se pode imaginar, um dos primeiros afetados por estas técnicas é o Selenium. E como a indústria de web scraping depende fortemente desta tecnologia, os scrapers também são diretamente afetados.

Antes de avançarmos para as técnicas anti-bot, penso que é importante discutir como o Cloudflare deteta o Selenium. Bem, o sistema pode ser muito complexo. Por exemplo, existem propriedades num navegador que faltam a um web driver. A interface `navigator` num navegador tem até uma propriedade chamada `webdriver` que indica se um navegador é controlado por automação. E isso é uma pista imediata. Se quiser experimentar:

  • Abra as ferramentas de programador do seu navegador
  • Navegue até à consola
  • Digite o seguinte comando: `navigator.webdriver`

No seu caso, deve devolver `false`. Mas se o experimentar com o Puppeteer ou o Selenium, obterá `true`. Se está a perguntar-se como é que o Cloudflare aproveita isto para detetar bots, bem, é bastante simples. Tudo o que precisam de fazer é inserir um script como o que se segue no site do 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, existem muitos mais níveis de deteção que estes fornecedores utilizam. Até mesmo o tamanho do ecrã, o layout do teclado ou os plugins utilizados pelos navegadores são usados para identificar especificamente um navegador. Se estiver interessado em saber como funciona a deteção sem navegador, consulte o meu teste simples de service worker. E isso é apenas se se limitar ao navegador. Também é possível detetar atividade de bots analisando o endereço IP de onde a solicitação se origina. Por exemplo, se estiver a utilizar IPs de centros de dados, as suas hipóteses de ser bloqueado aumentam a cada solicitação. É por isso que se recomenda utilizar proxies residenciais ou de ISP quando estiver a criar um web scraper.

Como contornar o Cloudflare com o Selenium

Felizmente, a comunidade de web scraping é muito ativa. E como existe tanta procura para contornar o Cloudflare e outros fornecedores anti-bot, existem soluções de código aberto nessa área. É possível alcançar grandes resultados quando as comunidades de programação trabalham em conjunto! De agora em diante, sugiro que sigamos estes passos:

  • Executar alguns testes para verificar se o Selenium padrão consegue contornar o Cloudflare
  • Adicionar algumas evasões extra aos nossos scripts para os tornar mais furtivos

Então, vamos começar com o nosso primeiro passo:

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

Não sou do tipo que faz suposições. E isso deve-se especialmente ao facto de não sabermos ao certo como funcionam os sistemas da Cloudflare. Eles utilizam todo o tipo de ofuscação no seu código, o que torna mais difícil a engenharia reversa. É por isso que, ao longo da minha experiência como programador, aprendi que testar é a melhor forma de compreender como um sistema funciona. Vamos, então, criar um scraper básico e ver como ele se comporta num alvo real, protegido pelo Cloudflare.

1.1. Configurar o ambiente

Com o Python, é melhor isolar os nossos projetos dentro de um único diretório. Então, vamos criar uma nova pasta, abrir uma janela de terminal e navegar até ela:

# Create a new virtual environment and activate it

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

# Install dependencies

~ » python3 -m pip install selenium

# Create a new .py file and open the project inside your IDE

~ » touch app.py && code .

1.2. Criar um scraper web simples com Selenium

Agora que configurou o seu projeto com sucesso, é hora de adicionar algum código. Não vamos criar nada sofisticado aqui. Precisamos apenas deste script para fins de teste. Se quiser aprender sobre scraping avançado, consulte este tutorial [LINK](AICI TREBUIE POSTAT ARTICOLUL) sobre o Pyppeteer.

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

# Set Chrome to open in headless mode

options = Options()

options.headless = True

# Create a new Chrome instance and navigate to target

driver = webdriver.Chrome(options=options)

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

# Give it some time to load

time.sleep(10)

# Take screenshot of page

driver.get_screenshot_as_file('screenshot.png')

# Close browser

driver.quit()

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

Acho que podemos concluir com segurança que o teste falhou. O site alvo está protegido pelo Cloudflare e, como pode ver, estamos a ser bloqueados. Portanto, por predefinição, o Selenium não consegue contornar o Cloudflare. Não vou aprofundar o assunto nem verificar com outros fornecedores de deteção de bots. Se quiser testar mais, aqui estão alguns alvos e os seus fornecedores:

#2: O Selenium furtivo consegue contornar o Cloudflare?

Em primeiro lugar, deixem-me esclarecer os termos. Por Selenium «stealthy» refiro-me a uma versão do Selenium que consegue passar despercebida e contornar o Cloudflare. Não me refiro a nenhuma técnica específica de ocultação. Existem algumas formas de implementar técnicas de evasão no Selenium. Existem pacotes que tratam disso, ou 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 poderia usá-la 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 permitem efetuar todas as alterações necessárias. Por isso, por enquanto, vamos testar com alguns pacotes.

1.1. Selenium Stealthy

Existem pelo menos dois pacotes que pode utilizar para tornar o Selenium furtivo. Até ao momento, porém, nenhum deles garante contornar o Cloudflare. Mais uma vez, precisamos de testar e ver se algum deles funciona. Primeiro, 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, tem de o instalar primeiro. Abra uma janela de terminal e digite este comando:

# Install selenium-stealth

~ » python3 -m pip install selenium-stealth

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

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

from selenium_stealth import stealth

import time

# Set Chrome to open in headless mode

options = Options()

options.headless = True

# Create a new Chrome instance

driver = webdriver.Chrome(options=options)

# Apply stealth to your webdriver

stealth(driver,

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

   vendor="Google Inc.",

   platform="Win32",

   webgl_vendor="Intel Inc.",

   renderer="Intel Iris OpenGL Engine",

   fix_hairline=True,

)

# Navigate to target

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

# Give it some time to load

time.sleep(10)

# Take screenshot of page

driver.get_screenshot_as_file('stealth.png')

# Close browser

driver.quit()

Ao executar o script, obtive resultados diferentes desta vez, em comparação com as configurações padrão do Selenium:

A segunda opção que pode utilizar é o `undetected_chromedriver`. Este é descrito como um «chromedriver Selenium otimizado». Vamos testá-lo:

# Install undetected_chromedriver

~ » python3 -m pip install undetected_chromedriver

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

import undetected_chromedriver as uc

import time

# Set Chrome to open in headless mode

options = uc.ChromeOptions()

options.headless = True

# Create a new Chrome instance and maximize the window

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

driver.maximize_window()

# Navigate to target

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

# Give it some time to load

time.sleep(10)

# Take screenshot of page

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

# Close browser

driver.quit()

Mais uma vez, a execução do script correu bem para mim. Parece que, pelo menos, estes dois pacotes conseguem contornar com sucesso a proteção do Cloudflare. Pelo menos a curto prazo. Para dizer a verdade, é provável que, se utilizar estes scripts extensivamente, o Cloudflare detete o seu endereço IP e o bloqueie.

Por isso, deixe-me apresentar-lhe uma terceira opção: a API de Web Scraping.

1.2. Selenium com a API de Web Scraping

A Web Scraping API tem uma funcionalidade incrível chamada Modo Proxy. Pode ler mais sobre isso aqui. Mas o que quero salientar aqui é que o nosso Modo Proxy pode ser integrado com sucesso com o Selenium. Desta forma, obtém 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 gerir rotações de IP, a utilizar vários proxies, a resolver captchas e 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 a versão mais discreta do Selenium que existe. E eis como se faz:

# Install selenium-wire

~ » python3 -m pip install selenium-wire


Estamos a utilizar o `selenium-wire` para utilizar o Selenium com um proxy. 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 sempre. Esse é o nosso sistema de rotação de IP. Em segundo plano, ele também adiciona técnicas de evasão. Nem 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 criar um scraper capaz de contornar o Cloudflare, tem de ter em conta muitos fatores. Uma equipa dedicada pode trabalhar 24 horas por dia, 7 dias por semana, e mesmo assim não há garantia de que as técnicas de evasão funcionem sempre. Isto porque, com cada lançamento de uma nova versão do navegador, existe a possibilidade de serem adicionadas novas funcionalidades à API. E algumas dessas funcionalidades podem ser usadas para identificar e detetar bots.

Diria mesmo que o melhor navegador 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, aproveite o scraping!

Sobre o autor
Mihnea-Octavian Manolache, Desenvolvedor Full Stack @ 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.