Automatisation de navigateur avec Puppeteer et profils d'empreinte
Guide complet pour integrer Puppeteer avec des profils d'empreinte coherents, le support proxy et le deploiement en production.
Vous préférez la doc produit maintenue ?
Cet article a une page équivalente dans le centre de documentation. Utilisez les docs pour le flux canonique, les flags à jour et la référence durable.
Introduction
Puppeteer est la bibliotheque Node.js de Google pour controler Chrome via le Chrome DevTools Protocol (CDP). Elle fournit une API de haut niveau pour la navigation, la capture d'ecran, l'interaction avec les formulaires, l'interception reseau et bien plus encore. BotBrowser remplace le binaire Chromium standard par un binaire qui produit une empreinte coherente controlee par des fichiers de profil. Puppeteer gere l'automatisation, BotBrowser gere l'identite.
Ce guide couvre l'integration complete : installation, configuration de lancement, gestion du viewport, configuration proxy, acces CDP, deploiement en production sur serveurs Linux et depannage courant. A la fin, vous disposerez d'une configuration Puppeteer + BotBrowser fonctionnelle, prete pour le developpement et la production.
Impact sur la vie privee : pourquoi Puppeteer + BotBrowser
Le Puppeteer standard lance un binaire Chromium de base qui expose l'empreinte reelle de la machine hote. Chaque instance de navigateur partage le meme GPU, les memes polices, la meme resolution d'ecran et les memes caracteristiques de plateforme. Les indicateurs d'automatisation comme navigator.webdriver sont egalement presents, rendant evident que le navigateur est controle par programme.
Avec BotBrowser, chaque instance Puppeteer peut charger un profil d'empreinte different, lui conferant une identite de navigateur unique. L'empreinte est appliquee au niveau du moteur, avant le chargement de toute page et avant l'execution de tout JavaScript. Votre code d'automatisation Puppeteer n'a pas besoin d'etre modifie. Le controle d'identite se fait au niveau de la configuration de lancement.
Cela permet d'executer plusieurs instances Puppeteer concurrentes, chacune avec un profil d'empreinte, un proxy, un fuseau horaire et une locale distincts, le tout depuis la meme machine hote. La separation est nette : Puppeteer controle ce que fait le navigateur, BotBrowser controle ce qu'est le navigateur.
Contexte technique
Pourquoi puppeteer-core et non puppeteer
Le package npm standard puppeteer inclut son propre binaire Chromium. Lors de l'installation, il telecharge une version specifique de Chromium geree par l'equipe Puppeteer. Ce binaire n'inclut pas les capacites de controle d'empreinte de BotBrowser.
Le package puppeteer-core offre la meme API sans navigateurs inclus. Il vous demande de specifier un executablePath au lancement, ce qui est la methode pour pointer Puppeteer vers le binaire BotBrowser.
# Installez puppeteer-core, pas puppeteer
npm install puppeteer-core
Le parametre defaultViewport
Puppeteer a un comportement par defaut critique : il definit un defaultViewport de 800x600 pixels sur chaque nouvelle page. Cela remplace les dimensions du viewport definies dans le profil d'empreinte BotBrowser, causant des incoherences entre la taille d'ecran rapportee (du profil) et la taille reelle du viewport (800x600 de Puppeteer).
Definissez toujours defaultViewport: null pour empecher ce remplacement et laisser le profil BotBrowser controler les dimensions du viewport.
Acces CDP
Puppeteer fournit un acces CDP direct via les objets CDPSession. C'est important pour BotBrowser car certaines fonctionnalites avancees sont controlees par des commandes CDP personnalisees :
// Session CDP au niveau du navigateur
const cdpSession = await browser.target().createCDPSession();
// Commandes CDP BotBrowser
await cdpSession.send('BotBrowser.setCustomHeaders', {
headers: { 'X-Custom': 'value' }
});
Notez que les commandes CDP BotBrowser doivent etre envoyees a la session au niveau du navigateur, pas a une session au niveau de la page. L'utilisation de page.createCDPSession() entrainera une erreur "method not found" pour les commandes specifiques a BotBrowser.
Approches courantes et leurs limites
Utilisation du navigateur inclus de Puppeteer
Le Chromium inclus avec Puppeteer fonctionne pour l'automatisation basique mais n'offre aucun controle d'empreinte. Chaque instance a la meme empreinte, et les signaux d'automatisation sont detectables.
Plugins Stealth
Le package puppeteer-extra-plugin-stealth corrige certains indicateurs d'automatisation par injection JavaScript. Cependant, il opere au mauvais niveau. L'injection JavaScript intervient apres la creation de la page et peut etre detectee par l'analyse temporelle, l'inspection de la chaine de prototypes et d'autres techniques. Elle ne controle pas non plus les signaux au niveau du rendu comme la sortie canvas, les chaines de rendu WebGL ou la disponibilite des polices.
Definition manuelle du User-Agent
Puppeteer permet de definir un User-Agent personnalise avec page.setUserAgent(). Cela modifie un seul signal mais laisse tous les autres (plateforme, polices, GPU, metriques d'ecran) a leurs valeurs reelles. L'incoherence entre le User-Agent et les autres signaux est elle-meme un signal detectable.
L'approche BotBrowser
BotBrowser s'integre a Puppeteer via le parametre standard executablePath dans puppeteer.launch(). Aucun plugin, patch ou middleware n'est necessaire.
Integration sans modification de code
L'ajout de BotBrowser a un projet Puppeteer existant ne necessite que la modification de la configuration de lancement. Tout le code au niveau des pages (selecteurs, navigation, extraction de donnees) reste exactement le meme.
Signaux au niveau du moteur
Le profil d'empreinte est charge lors de l'initialisation du navigateur. Au moment ou Puppeteer se connecte via CDP, tous les signaux sont deja en place. Il n'y a pas de condition de concurrence, pas de phase de configuration, et aucun risque d'exposition de l'empreinte reelle au demarrage.
Compatibilite CDP complete
BotBrowser etend le CDP standard avec des commandes personnalisees pour les fonctionnalites avancees comme les en-tetes personnalises et la configuration par contexte. Toutes les commandes CDP standard continuent de fonctionner comme documente.
Configuration et utilisation
Prerequis
- Binaire BotBrowser (telecharger depuis GitHub)
- Un fichier de profil d'empreinte (format
.enc) - Node.js 18+
npm install puppeteer-core
Assurez-vous que le binaire BotBrowser a les permissions d'execution :
chmod +x /path/to/botbrowser/chrome
Lancement de base
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
],
headless: true,
defaultViewport: null, // Critique : laisser le profil controler le viewport
});
const page = await browser.newPage();
await page.goto('https://example.com');
const title = await page.title();
console.log('Page title:', title);
await browser.close();
})();
Profil + Proxy + Locale
const browser = await puppeteer.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
'--proxy-server=socks5://user:pass@proxy:1080',
'--bot-config-timezone=Europe/London',
'--bot-config-locale=en-GB',
'--bot-config-languages=en-GB,en',
],
headless: true,
defaultViewport: null,
});
Configuration d'identite complete
const browser = await puppeteer.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
'--proxy-server=socks5://user:pass@us-proxy:1080',
'--bot-config-timezone=America/New_York',
'--bot-config-locale=en-US',
'--bot-config-languages=en-US,en',
'--bot-inject-random-history',
'--bot-bookmarks=[{"title":"Google","type":"url","url":"https://www.google.com"}]',
'--bot-cookies=@/path/to/cookies.json',
'--bot-always-active',
],
headless: true,
defaultViewport: null,
});
Identites multiples
async function createSession(profilePath, proxyUrl, timezone) {
const args = [
`--bot-profile=${profilePath}`,
];
if (proxyUrl) args.push(`--proxy-server=${proxyUrl}`);
if (timezone) args.push(`--bot-config-timezone=${timezone}`);
const browser = await puppeteer.launch({
executablePath: '/path/to/botbrowser/chrome',
args,
headless: true,
defaultViewport: null,
});
return browser;
}
// Lancer plusieurs identites distinctes
const sessions = await Promise.all([
createSession('/profiles/win11-us.enc', 'socks5://u:p@us:1080', 'America/New_York'),
createSession('/profiles/win11-de.enc', 'socks5://u:p@de:1080', 'Europe/Berlin'),
createSession('/profiles/android-jp.enc', 'socks5://u:p@jp:1080', 'Asia/Tokyo'),
]);
Interception reseau
const page = await browser.newPage();
// Activer l'interception des requetes
await page.setRequestInterception(true);
page.on('request', request => {
if (request.resourceType() === 'image') {
request.abort();
} else {
request.continue();
}
});
await page.goto('https://example.com');
Capture d'ecran et PDF
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
// Capture d'ecran
await page.screenshot({ path: 'screenshot.png', fullPage: true });
// PDF
await page.pdf({ path: 'page.pdf', format: 'A4' });
Mode headless sur Ubuntu
Pour les serveurs Linux, definissez la variable d'environnement DISPLAY :
const puppeteer = require('puppeteer-core');
// Definir DISPLAY avant le lancement
process.env.DISPLAY = ':10.0';
const browser = await puppeteer.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
],
headless: true,
defaultViewport: null,
});
Ou definissez-le dans le shell avant d'executer votre script :
DISPLAY=:10.0 node script.js
Verification
Verifiez l'integration en examinant les signaux d'empreinte :
const page = await browser.newPage();
await page.goto('https://example.com');
const fingerprint = await page.evaluate(() => ({
userAgent: navigator.userAgent,
platform: navigator.platform,
languages: navigator.languages,
hardwareConcurrency: navigator.hardwareConcurrency,
deviceMemory: navigator.deviceMemory,
webdriver: navigator.webdriver,
screenWidth: screen.width,
screenHeight: screen.height,
innerWidth: window.innerWidth,
innerHeight: window.innerHeight,
dpr: devicePixelRatio,
touchPoints: navigator.maxTouchPoints,
}));
console.log('Fingerprint:', JSON.stringify(fingerprint, null, 2));
Bonnes pratiques
- Definissez toujours
defaultViewport: null. C'est la configuration la plus importante. Sans cela, Puppeteer remplace le viewport du profil par 800x600. - Utilisez
puppeteer-core, pas le package completpuppeteer. Le package complet telecharge un binaire Chromium inutile. - Utilisez des chemins absolus pour
--bot-profileet les autres flags bases sur des fichiers. Les chemins relatifs peuvent etre resolus incorrectement. - Fermez les instances de navigateur lorsque vous avez termine. Chaque instance est un processus Chrome. Ne pas les fermer entraine des fuites de memoire et de CPU.
- Definissez
DISPLAY=:10.0sur les serveurs Linux, meme en mode headless. - Gerez les erreurs correctement. Encapsulez le lancement et la navigation dans des blocs try/catch. Les lancements de navigateur peuvent echouer en raison de dependances manquantes ou de chemins incorrects.
Questions frequentes
Puis-je utiliser le package complet puppeteer au lieu de puppeteer-core ?
Techniquement oui, mais il telechargera un binaire Chromium inutile lors du npm install. Utilisez puppeteer-core pour economiser de l'espace disque et indiquer clairement que vous utilisez un binaire de navigateur personnalise.
Ai-je besoin de puppeteer-extra ou des plugins stealth ?
Non. BotBrowser gere le controle d'empreinte au niveau du moteur. Les plugins stealth ajoutent des corrections au niveau JavaScript qui sont inutiles avec BotBrowser et peuvent interferer avec son fonctionnement.
Pourquoi mon viewport affiche-t-il 800x600 ?
Vous avez oublie de definir defaultViewport: null dans les options de lancement. C'est le comportement par defaut de Puppeteer. Ajoutez defaultViewport: null pour laisser le profil BotBrowser controler le viewport.
Comment gerer l'authentification proxy ?
BotBrowser etend --proxy-server pour accepter les identifiants integres : --proxy-server=socks5://user:pass@host:port. N'utilisez pas page.authenticate() de Puppeteer pour l'authentification proxy, car cela peut desactiver la geo-detection automatique de BotBrowser.
Puis-je utiliser browser.createBrowserContext() pour un proxy par contexte ?
BotBrowser prend en charge le proxy par contexte via son propre mecanisme (ENT Tier1). L'utilisation de createBrowserContext({ proxyServer }) avec la syntaxe compatible Playwright depend de votre version de Puppeteer et de votre niveau BotBrowser.
Comment deboguer si le profil ne se charge pas ?
Verifiez ces problemes courants :
- Le chemin du profil est absolu et le fichier existe
- Le binaire BotBrowser a les permissions d'execution
- Utilisez les flags
--bot-internal --v=1pour activer les logs de debogage - Verifiez la sortie console du navigateur pour les erreurs de chargement du profil
Quelle version de Node.js est requise ?
Node.js 18 ou superieur est recommande. puppeteer-core necessite au minimum Node.js 16.
Puis-je utiliser TypeScript ?
Oui. puppeteer-core inclut les definitions TypeScript :
import puppeteer, { Browser, Page } from 'puppeteer-core';
Resume
L'integration de BotBrowser avec Puppeteer necessite l'installation de puppeteer-core, de pointer executablePath vers le binaire BotBrowser, d'ajouter --bot-profile aux arguments de lancement et de definir defaultViewport: null. Toutes les fonctionnalites standard de Puppeteer fonctionnent sans modification.
Pour des sujets connexes, consultez Premiers pas avec Playwright pour l'equivalent Playwright, Recettes CLI pour les combinaisons de flags, Configuration de serveur headless pour le deploiement en production, et Gestion des profils pour organiser vos profils.
Articles Connexes
Faites passer BotBrowser de la recherche à la production
Utilisez ces guides pour comprendre le modèle, puis passez à la validation multi-plateforme, aux contextes isolés et au déploiement navigateur prêt pour l'échelle.