Practical Programming
bonnes pratiques de scraping

Web scraping : conseils et bonnes pratiques

Cet article est le cinquième de notre série Web scraping : le guide complet avec tutoriels

La lecture des précédents articles est recommandée. 

En général, il existe deux raisons pour lesquelles une application de web scraping est développée :

  • Pour interfacer un programme avec un programme plus ancien qui ne propose pas d’API
  • Pour collecter des informations sur un site web tiers, souvent sans son autorisation

On ne va pas se mentir, il y a de grandes chances pour que ce soit la deuxième raison qui vous a amené ici. Parce que les entreprises ont réalisé l’importance de leurs données qu’elles cherchent désormais à valoriser, vous serez tôt ou tard confronté à certaines problématiques éthiques, juridiques et techniques

Dans ce guide, j’aborde ces problématiques et vous donne toutes les astuces pour contourner les sécurités anti web scraping

Web scraping et enjeux juridiques

Je ne suis pas avocat, je ne vais donc pas me risquer à vous donner des conseils d’ordre juridique. Sachez toutefois que le web scraping a déjà été considéré comme illégal par des magistrats dans certains contextes. En France, il peut ainsi être qualifié de vol de données (article 323-3 du Code Pénal) et peut également être sanctionné en application de l’article L342-1 du Code de la propriété intellectuelle qui protège les producteurs de bases de données. C’est par exemple sur cette base que EntreParticuliers.com a été condamné à plusieurs centaines de milliers d’euros de dédommagement pour avoir scrapé illégalement Leboncoin. Par ailleurs, ce jugement (TGI de Paris, 1er septembre 2017) avait également retenu la concurrence déloyale

On ne peut pour autant pas dire que le web scraping est une pratique systématiquement illégale et la “zone grise” dans laquelle il se situe parfois est souvent débattue et expliquée, comme dans cet article de seraphin.legal sur le droit des données. En tout état de cause, je ne peux que vous conseiller de vous renseigner de façon extensive sur la légalité de vos actions voire de consulter un avocat spécialisé (ils sont assez rares sur ce sujet) avant de mettre en production une application de web scraping. 

S’il n’est pas toujours interdit par la loi et la jurisprudence selon les contextes et les pratiques (notamment la finalité du scraping et l’utilisation faite des données scrapées), le web scraping est presque toujours interdit par les Conditions d’Utilisation des sites que vous ciblez. Parce que les entreprises sont très soucieuses de la protection de leurs données (et on les comprend), elles mettent généralement en place des protections et sécurités anti-scraping. Si je ne peux rien vous garantir, je peux au moins vous affirmer que suivre une certaine éthique du web scraping vous permet souvent de passer outre ces protections. 

L’éthique du web scraping Le web scraping peut-il être éthique ?

Le web scraping peut créer plusieurs risques pour les propriétaires des sites web : 

  • On l’a dit, le vol de données porte atteinte à la propriété intellectuelle et peut créer une concurrence déloyale ;
  • Un site peut crasher suite à un trop grand nombre de requêtes (sorte d’attaque DDoS involontaire), ce qui peut coûter très cher ;
  • Les mécanismes et algorithmes d’un site peuvent être analysés et manipulés ce qui peut être fort problématique pour certains sites comme les réseaux sociaux.
  • Et de nombreux autres risques possibles selon la méthode et la finalité du web scraping

En tant que web scrapers, nous devons respecter une certaine éthique pour ne pas être assimilés à des hackers malveillants. C’est pourquoi je vous conseille fortement de respecter quelques bonnes pratiques

  • Préférez toujours l’utilisation d’une API publique plutôt que le web scraping ;
  • Utilisez un User Agent qui permet de vous identifier et de connaître vos intentions ;
  • Suivez les instructions du fichier robots.txt et consultez les Conditions d’Utilisation. Entrez en contact avec le site en cas de doute, vous pourrez peut-être négocier quelque chose ;
  • Ne surchargez pas les serveurs d’un site : réalisez vos requêtes à une fréquence raisonnable (par ex. 1 requête/10 secondes) si aucune fréquence n’est conseillée dans le fichier robots.txt ;
  • Ne stockez que les données dont vous avez besoin et ne gardez rien d’autre ;
  • Ne faites pas passer les données que vous collectez comme étant les vôtres ;
  • Scrapez pour créer une valeur nouvelle à de la donnée et pas pour la dupliquer.

Suivre ces bonnes pratiques vous permettra d’être éthique dans votre web scraping et de prouver votre bonne foi et vos bonnes intentions. La plupart du temps, cela vous permettra également de passer entre les mailles des systèmes de sécurité anti scraping. Pour les moments où ça ne suffit pas, il y a les techniques de contournement

Web scraping Bypass : comment contourner les systèmes de sécurité

Vous l’avez compris, les entreprises tiennent à leurs données et mettent en place des sécurités anti-scraping pour se prémunir des risques liés au web scraping. Ces systèmes parfois assez complexes se basent généralement sur plusieurs facteurs pour identifier un client comme étant un bot et l’empêcher d’accéder au site: fréquence des requêtes, cookies, IPs, honeypots (pièges à bot), viewport, captchas…

En scrapant différents sites utilisant des systèmes de protection variés, vous saurez plus facilement identifier quelle technologie de protection est en place et comment elle fonctionne. Pour certaines, une simple désactivation du Javascript ou un changement d’User Agent peuvent par exemple suffire à ne pas être “flaggé” comme bot et donc à pouvoir scraper. Pour d’autres, il faudra comprendre l’algorithme de repérage et le déjouer de façon plus complexe, par exemple à l’aide de cookies cryptés ou de tokens d’authentification récupérés depuis un client “sain” pour simuler des requêtes AJAX… 

Faire ici une liste des technologies existantes et de solutions possibles serait contre-productif car cette liste ne pourrait être exhaustive ni être à jour constamment. En revanche, je vous ai préparé une liste assez complète de bonnes pratiques de web scraping à mettre en place techniquement pour ne pas être détecté, avec pour certaines un code d’exemple pour Puppeteer (voir notre article Web scraping : quels langages et technologies choisir). Pour une performance optimale et un minimum de risques, ces bonnes pratiques sont à utiliser conjointement avec les conseils donnés plus haut à propos de l’éthique du web scraping. 

Faire tourner les IPs via proxy ou VPN (IP rotation)

Vous le savez très certainement, une requête HTTP permet à un client de communiquer avec un serveur, les deux étant identifiés par une adresse IP. Si, par mégarde, votre client dédié au web scraping est identifié comme étant un bot (par exemple, en réalisant des requêtes trop fréquemment), son adresse IP pourra être bannie par le serveur. Il sera alors impossible d’accéder à tout ou partie du site web depuis cette adresse IP pendant un certain temps voire pour toujours. 

Rassurez-vous, ce cas de figure est assez rare (de ma propre expérience en tout cas), surtout si vous respectez à la lettre l’éthique du web scraping évoquée plus haut. Dans la plupart des cas, l’affichage des pages web depuis une adresse IP “flaggée” (considérée par le système de sécurité comme étant un bot) sera simplement conditionné à un captcha, dont on parlera plus tard. Dans le pire des scénarios, l’IP est bannie à tout jamais.

Si cela arrive, vous devez mettre en place une rotation d’adresse IP pour ce site web, c’est à dire effectuer vos requêtes depuis différentes adresses IP. Cela réduira le volume de requêtes par adresse IP et donc le risque d’être détecté. De plus, si un client est détecté et son IP est bannie, il vous restera les autres adresses IP pour continuer le scraping. 

IP rotation via VPN pour le web scraping

Si vous réalisez votre web scraping en local (depuis votre ordinateur), il peut être très facile de mettre en place une rotation d’IP via un simple VPN (Virtual Private Network). Il existe de nombreux VPN sur le marché dont des gratuits et la plupart proposent une multitude d’adresses IP réparties aux quatre coins de la planète. Les VPN sont des sortes de proxys plus complets : ils ne sécurisent pas seulement les requêtes HTTP mais tout le trafic réseau de votre ordinateur. Leur grand avantage est de proposer une interface qui vous permet de passer d’une adresse IP à une autre en quelques secondes très facilement.

IP rotation via Proxy pour le web scraping

Si vous hébergez vos scripts de web scraping sur un serveur distant ou dans le cloud, vous pouvez masquer l’adresse IP de votre serveur et réaliser une rotation d’adresses IP grâce à des serveurs proxy. Concrètement, cela vous permet de faire passer toutes vos requêtes de web scraping par un ou plusieurs serveurs tiers (les serveurs proxy) avant d’être dirigées vers le serveur du site web ciblé. Ces proxys vont alors collecter les réponses à vos requêtes et les renvoyer vers votre serveur. Il existe de nombreux fournisseurs de serveurs proxy sur le marché dont certains – plus chers – sont spécialistes du web scraping et gèrent la rotation eux-mêmes. 
Il est facile de mettre en place une rotation d’adresse IP via proxy avec Puppeteer pour Node.js. Selon la structure de votre code, vous pouvez la faire au niveau du client ou à chaque requête.

Rotation IP avec Puppeteer au niveau du client

Nécessite le module proxy-chain

const proxies = {
  'useragent1': 'http://user:pass@XX.XXX.XX.XXX:XXXXX',
  'useragent2': 'http://user:pass@XX.XXX.XX.XXX:XXXXX',
  'useragent3': 'http://user:pass@XX.XXX.XX.XXX:XXXXX'
}; 
const server = new ProxyChain.Server({
  port: 8000,
  prepareRequestFunction: ({request}) => {
  const userAgent = request.headers['user-agent'];
  const proxy = proxies[userAgent];
  return {
    upstreamProxyUrl: proxy
  };
 }
}); 
server.listen(() => console.log('Le proxy fonctionne !'));

Rotation IP avec Puppeteer pour chaque requête

Nécessite le module puppeteer-page-proxy

const useProxy = require('puppeteer-page-proxy');
 
await page.setRequestInterception(true);
page.on('request', async request => {
    if (request.resourceType() === 'image') {
        request.abort();
    } else {
        await useProxy(request, 'http://user:pass@XX.XXX.XX.XXX:XXXXX');
    }
});

Rotation d’IP : attention à la localisation

Que vous optiez pour un proxy ou un VPN, vérifiez systématiquement le pays rattaché à l’adresse IP car l’utilisation de tel ou tel pays peut changer le contenu collecté par votre script de web scraping : beaucoup de sites multilingues se basent sur la localisation de l’adresse IP pour choisir quelle version du site afficher. De plus, certains sites ne sont pas disponibles dans certains pays et se basent sur l’adresse IP pour assurer la restriction. 

Enfin, certains systèmes de sécurité seront plus stricts envers certaines adresses IP telles que les adresses localisées en Chine ou en Russie et tiennent des blacklists contenant par exemple des adresses IP fournies par VPN. Mon conseil est donc de tester des offres sans engagement proposant un grand nombre d’adresses différentes, régulièrement mises à jour, dans le pays du site ciblé (une IP française pour scraper un site français). 

Quid de TOR ?

Il n’est pas éthique d’utiliser TOR pour anonymiser vos requêtes. La raison est que si votre script est détecté et que son IP est bannie, cela empêchera tous les utilisateurs de TOR localisés sur ce noeud de sortie d’accéder au site. De plus, utiliser TOR est bien plus lent que d’utiliser un proxy. 

Randomiser les tailles de viewport

Quand je travaillais en agence web, on avait l’habitude de repérer les bots dans Google Analytics en se fiant à la taille du viewport. Il est important de randomiser les tailles de viewport, c’est à dire de non seulement utiliser un viewport différent de celui par défaut mais surtout d’utiliser des viewports différents par client. Si ce n’est pas généralement un facteur très important aux yeux des systèmes de protection anti web scraping, cela vous rend plus difficile à repérer à l’oeil nu. 

Exemple de randomisation basique de taille de viewport avec Puppeteer

await page.setViewport({
    width: 1920 + Math.floor(Math.random() * 100),
    height: 3000 + Math.floor(Math.random() * 100),
    deviceScaleFactor: 1,
    hasTouch: false,
    isLandscape: false,
    isMobile: false,
});

Randomiser les User Agents

L’éthique du web scraping nous oblige à utiliser un User Agent identifiable. Il peut cependant arriver que, quand bien même vous respectez toutes les règles du web scraping éthique, votre User Agent soit la cause d’une détection par le système de protection en place. Dans ce cas, vous pouvez être amené à randomiser les User Agents, c’est-à-dire en utiliser des différents pour chaque client. Vous pouvez obtenir des User Agents aléatoires ou télécharger des listes de User Agents sur ce site internet ou utiliser un anonymisateur d’User Agent

Exemple d’anonymisation d’User Agent avec Puppeteer

Nécessite le module puppeteer-extra-plugin-anonymize-ua

const puppeteer = require('puppeteer-extra')
puppeteer.use(require('puppeteer-extra-plugin-anonymize-ua')())
// ou
puppeteer.use(require('puppeteer-extra-plugin-anonymize-ua')({
  customFn: (ua) => 'MonAgentCustom/' + ua.replace('Chrome', Custom)})
)
const browser = await puppeteer.launch()

Passer le téléchargement de ressources inutiles au web scraping

Pour ne pas surcharger inutilement les serveurs du site ciblé et obtenir un meilleur temps d’exécution, désactivez le téléchargement des ressources inutiles au web scraping telles que les feuilles de style, les polices ou encore les images

Exemple avec Puppeteer pour Node.js

page.on('request', (req) => {
    if(req.resourceType() == 'stylesheet' || req.resourceType() == 'font' || req.resourceType() == 'image'){
        req.abort();
    } else {
        req.continue();
    }
});

Changer la langue par défaut du client

On en a parlé, certains sites et certaines solutions de protection anti web scraping identifient votre localisation par votre adresse IP mais ils peuvent également utiliser la langue par défaut du navigateur pour déterminer quelle version du site afficher. Certains systèmes de protection vérifient également qu’une langue est bien spécifiée pour le client comme elle le serait chez un utilisateur “normal”. 

Exemple de changement de langue sur Puppeteer pour Node.js

await page.evaluateOnNewDocument(() => {
    Object.defineProperty(navigator, 'languages', {
        get: () => ['en-US', 'en'],
    });
});

Utilisez le stealth mode plugin pour puppeteer

On le répète souvent, l’un des grands avantages de Node.js est l’immense quantité de modules disponibles. Concernant le web scraping avec Puppeteer, le plugin stealth est un must-have. En une ligne, ce plugin automatise un grand nombre de techniques pour éviter la détection par les systèmes anti scraping. Parce qu’elle est intéressante et vous donne un certain aperçu de ce qui se passe dans le monde du web scraping, je vous ai traduit la note laissée par le créateur du plugin en janvier 2020 : 

“Je considère ceci comme une compétition amicale dans un jeu du chat et de la souris plutôt intéressant. Si l’autre équipe (👋) veut détecter un chromium en mode headless, il existe toujours des façons de le faire (j’en ai au moins repéré quelques unes, que je vais déjouer dans de futures mises à jour). Il est probablement impossible de déjouer toutes les méthodes de détection de chromium en mode headless, mais il devrait être possible de les rendre si difficiles que leur coût serait prohibitif, ou de faire en sorte qu’elles déclenchent trop de faux positifs pour être viables.”

Exemple d’utilisation du plugin stealth pour Puppeteer

Nécessite le module puppeteer-extra

const puppeteer = require('puppeteer-extra')
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
puppeteer.use(StealthPlugin())

Désactiver les vérifications WebDriver, Chrome, Notifications et plugins

Certains paramètres du client généré par puppeteer peuvent permettre de faciliter sa détection. Il s’agit du “webdriver check”, du “chrome check”, du “notifications check” et du “plugins check”. Vous pouvez passer ces checks assez facilement si nécessaire en vous inspirant des blocs de code suivants :

Passer le check webdriver

await page.evaluateOnNewDocument(() => {
    Object.defineProperty(navigator, 'webdriver', {
        get: () => false,
    });
});

Passer le check chrome

await page.evaluateOnNewDocument(() => {
    window.chrome = {
        runtime: {},
        // etc.
    };
});

Passer le check notifications:

await page.evaluateOnNewDocument(() => {
    const originalQuery = window.navigator.permissions.query;
    return window.navigator.permissions.query = (parameters) => (
        parameters.name === 'notifications' ?
            Promise.resolve({ state: Notification.permission }) :
            originalQuery(parameters)
    );
});

Passer le check plugins:

await page.evaluateOnNewDocument(() => {
    Object.defineProperty(navigator, 'plugins', {
        get: () => [1, 2, 3, 4, 5],
    });
});

Les tests anti scraping

Il existe un certain nombre de tests publics permettant de tester si votre script est facilement détectable par les systèmes de protection anti web scraping. Il est vivement conseillé d’envoyer votre bot sur ces tests avant de les envoyer sur les sites ciblés afin de vérifier son niveau de “camouflage” : 

Les plugins anti-captcha

Lorsqu’un système de protection anti-bot détecte votre client et le considère comme un bot, il peut réagir de différentes façons, la plus radicale étant le bannissement de votre adresse IP pour une période plus ou moins longue voire définitivement. Une punition moins radicale est de soumettre le client à un captcha. Un captcha peut également être affiché par défaut sur une page à tous les utilisateurs, par exemple sur un formulaire de contact . 

Il existe un certain nombre de modules destinés à la résolution automatique des captchas, notamment pour Puppeteer pour Node.js

Il existe également quelques solutions payantes de résolution de captcha via API.

Lucas Roquilly

Lucas Roquilly

Commenter

Retrouvez nous

N'hésitez pas à nous suivre sur les différents réseaux sociaux !

Most popular

Most discussed

Share This