Retour au blog
Guides
Mihnea-Octavian Manolache22 février 202310 min de lecture

Étape par étape : comment contourner Cloudflare et optimiser vos opérations de web scraping

Étape par étape : comment contourner Cloudflare et optimiser vos opérations de web scraping

Comment Cloudflare détecte-t-il les navigateurs sans interface graphique ?

Cloudflare est une entreprise technologique disposant d’un réseau gigantesque. Elle se concentre sur des services tels que le CDN, le DNS et divers systèmes de sécurité en ligne. Son pare-feu d’applications web est généralement conçu pour protéger contre des attaques telles que les DDoS ou le cross-site scripting. Ces dernières années, Cloudflare a ajouté, et d’autres fournisseurs du secteur ont introduit, des systèmes de fingerprinting capables de détecter les navigateurs sans interface graphique. Comme vous pouvez le deviner, l’un des premiers touchés par ces techniques est Selenium. Et comme le secteur du web scraping repose largement sur cette technologie, les scrapers sont également directement touchés.

Avant de passer aux techniques anti-bot, je pense qu’il est important d’aborder la manière dont Cloudflare détecte Selenium. Eh bien, le système peut s’avérer très complexe. Par exemple, il existe des propriétés dans un navigateur qui font défaut à un pilote Web. L’interface `navigator` d’un navigateur dispose même d’une propriété appelée `webdriver` qui indique si un navigateur est contrôlé par un processus automatisé. Et cela le trahit immédiatement. Si vous souhaitez tester cela :

  • Ouvrez les outils de développement de votre navigateur
  • Accédez à la console
  • Tapez la commande suivante : `navigator.webdriver`

Dans votre cas, cela devrait renvoyer « false ». Mais si vous essayez avec Puppeteer ou Selenium, vous obtiendrez « true ». Si vous vous demandez comment Cloudflare exploite cela pour détecter les bots, c'est assez simple. Il leur suffit d'injecter un script comme celui ci-dessous sur le site web de leur partenaire :

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

Bien sûr, dans la réalité, ces fournisseurs utilisent bien d’autres niveaux de détection. Même la taille de l’écran, la disposition du clavier ou les extensions utilisées par les navigateurs servent à identifier spécifiquement un navigateur. Si vous souhaitez comprendre comment fonctionne la détection sans navigateur, consultez mon test simple de service worker. Et cela ne concerne que les navigateurs. Vous pouvez également détecter l'activité des bots en examinant l'adresse IP d'où provient la requête. Par exemple, si vous utilisez des adresses IP de centres de données, vos chances d'être bloqué augmentent à chaque requête. C'est pourquoi il est recommandé d'utiliser des proxys résidentiels ou des proxys FAI lorsque vous développez un web scraper.

Comment contourner Cloudflare avec Selenium

Heureusement, la communauté du web scraping est très active. Et comme il existe une forte demande pour contourner Cloudflare et d'autres fournisseurs anti-bot, il existe des solutions open source dans ce domaine. De grandes choses peuvent être accomplies lorsque les communautés de programmeurs travaillent ensemble ! Pour aller de l'avant, je suggère de suivre ces étapes :

  • Effectuer quelques tests pour voir si Selenium par défaut peut contourner Cloudflare
  • Ajouter des techniques de contournement supplémentaires pour rendre nos scripts plus discrets

Commençons donc par la première étape :

#1 : Selenium par défaut peut-il contourner Cloudflare ?

Je ne suis pas du genre à faire des suppositions. Et cela surtout parce que nous ne savons pas avec certitude comment fonctionnent les systèmes Cloudflare. Ils utilisent toutes sortes de techniques d’obfuscation dans leur code, ce qui rend la rétro-ingénierie plus difficile. C’est pourquoi, au cours de mon expérience en tant que développeur, j’ai appris que les tests sont le meilleur moyen de comprendre le fonctionnement d’un système. Construisons donc un scraper basique et voyons comment il se comporte sur une cible réelle, protégée par Cloudflare.

1.1. Configurer l'environnement

Avec Python, il est préférable d'isoler nos projets dans un seul répertoire. Créons donc un nouveau dossier, ouvrons une fenêtre de terminal et accédons-y :

# 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. Créer un simple scraper web avec Selenium

Maintenant que vous avez correctement configuré votre projet, il est temps d'ajouter du code. Nous n'allons pas créer quelque chose de très sophistiqué ici. Nous avons simplement besoin de ce script à des fins de test. Si vous souhaitez en savoir plus sur le scraping avancé, consultez ce [LIEN](ICI DOIT ÊTRE PUBLIÉ L'ARTICLE) tutoriel sur 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()

Regardez maintenant la capture d'écran. Voici ce que j'ai obtenu :

Bot detection page prompting users to press and hold to confirm they are human

Je pense qu'on peut conclure sans risque que le test a échoué. Le site web ciblé est protégé par Cloudflare et, comme vous pouvez le voir, nous sommes bloqués. Par défaut, Selenium n'est donc pas capable de contourner Cloudflare. Je ne vais pas approfondir la question ni vérifier auprès d'autres fournisseurs de détection de bots. Si vous souhaitez poursuivre les tests, voici quelques cibles et leurs fournisseurs :

Table listing target websites and their bot protection providers, including Kasada and Akamai

#2 : Selenium furtif peut-il contourner Cloudflare ?

Tout d'abord, permettez-moi de clarifier les termes. Par Selenium furtif, j'entends une version de Selenium capable de passer inaperçue et de contourner Cloudflare. Je ne fais référence à aucune technique de dissimulation spécifique. Il existe plusieurs façons d’implémenter des techniques d’évasion dans Selenium. Il existe des paquets qui s’en chargent, ou vous pouvez utiliser la commande `execute_cdp_cmd` pour interagir directement avec l’API Chrome. Cette dernière option vous offre plus de contrôle, mais nécessite plus de travail. Voici un exemple de la manière dont vous pourriez l’utiliser pour modifier la valeur de l’agent utilisateur :

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"

       })

Mais vous devrez passer par le CDP et identifier les API qui vous permettent d'effectuer toutes les modifications nécessaires. Pour l'instant, testons donc avec quelques paquets.

1.1. Selenium furtif

Il existe au moins deux paquets que vous pouvez utiliser pour rendre Selenium furtif. À ce stade, cependant, aucun d’entre eux ne garantit de contourner Cloudflare. Une fois de plus, nous devons tester pour voir si l’un d’eux fonctionne. Tout d'abord, examinons `selenium-stealth`. Ce package est un wrapper autour de `puppeteer-extra-plugin-stealth`, ce qui permet d'utiliser les techniques d'évasion de Puppeteer avec Selenium sous Python. Pour l'utiliser, vous devez d'abord l'installer. Ouvrez une fenêtre de terminal et entrez cette commande :

# Install selenium-stealth

~ » python3 -m pip install selenium-stealth

Tout est prêt. Nous pouvons l'utiliser pour rendre notre scraper précédent plus furtif :

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()

L'exécution du script m'a donné des résultats différents cette fois-ci, par rapport aux paramètres Selenium par défaut :

Snipes website homepage banner featuring a model in a North Face jacket

La deuxième option que vous pouvez utiliser est `undetected_chromedriver`. Celle-ci est décrite comme un « chromedriver Selenium optimisé ». Testons-la :

# Install undetected_chromedriver

~ » python3 -m pip install undetected_chromedriver

Le code est très similaire à notre script par défaut. La principale différence réside dans le nom du package. Voici un scraper basique utilisant `undetected_chromedriver` ; voyons s’il peut contourner 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()

Une fois de plus, l'exécution du script fonctionne bien pour moi. Il semble qu'au moins ces deux paquets parviennent à contourner la protection de Cloudflare. Du moins à court terme. À vrai dire, il y a de fortes chances que, si vous utilisez ces scripts de manière intensive, Cloudflare finisse par repérer votre adresse IP et la bloque.

Je vais donc vous présenter une troisième option : l'API de scraping Web.

1.2. Selenium avec l'API Web Scraping

Web Scraping API dispose d’une fonctionnalité incroyable appelée « Mode Proxy ». Vous pouvez en savoir plus ici. Mais ce que je tiens à souligner ici, c’est que notre Mode Proxy peut être intégré avec succès à Selenium. De cette façon, vous avez accès à toutes les fonctionnalités de contournement que nous avons mises en place. Et laissez-moi vous dire que nous avons une équipe dédiée qui travaille sur des techniques de contournement personnalisées. En termes techniques, nous gérons la rotation des adresses IP, nous utilisons divers proxys, nous résolvons les captchas et nous utilisons l’API de Chrome pour modifier en permanence notre empreinte digitale. En termes non techniques, cela se traduit par moins de tracas pour vous et un taux de réussite plus élevé. Vous bénéficiez en gros de la version la plus furtive de Selenium qui soit. Et voici comment cela fonctionne :

# Install selenium-wire

~ » python3 -m pip install selenium-wire

Nous utilisons `selenium-wire` pour utiliser Selenium avec un proxy. Voici le 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 vous exécutez ce script plusieurs fois, vous verrez que l'adresse IP change à chaque fois. C'est notre système de rotation d'IP. En arrière-plan, il intègre également des techniques d'évasion. Vous n'avez même pas besoin de vous en soucier. Nous nous chargeons de contourner Cloudflare afin que vous puissiez vous concentrer davantage sur l'analyse des données.

Conclusions

Si vous souhaitez créer un scraper capable de contourner Cloudflare, vous devez tenir compte de nombreux facteurs. Même une équipe dédiée travaillant 24 h/24 et 7 j/7 ne peut garantir que les techniques d'évasion fonctionneront à chaque fois. En effet, à chaque nouvelle version de navigateur, il est possible que de nouvelles fonctionnalités soient ajoutées à l'API. Et certaines de ces fonctionnalités peuvent être utilisées pour identifier et détecter les bots.

J'irais même jusqu'à dire que le meilleur navigateur pour contourner Cloudflare et d'autres fournisseurs est celui que vous créez vous-même. Et nous en avons créé un chez Web Scraping API. Nous le partageons désormais avec vous. Alors, bon scraping !

À propos de l'auteur
Mihnea-Octavian Manolache, Développeur Full Stack @ WebScrapingAPI
Mihnea-Octavian ManolacheDéveloppeur Full Stack

Mihnea-Octavian Manolache est ingénieur Full Stack et DevOps chez WebScrapingAPI, où il développe des fonctionnalités pour les produits et assure la maintenance de l'infrastructure qui garantit le bon fonctionnement de la plateforme.

Commencez à créer

Prêt à faire évoluer votre système de collecte de données ?

Rejoignez plus de 2 000 entreprises qui utilisent WebScrapingAPI pour extraire des données Web à l'échelle de l'entreprise, sans aucun coût d'infrastructure.