The Fingerprint injector is a sparse javascript library built for stealth override of browser signatures or so-called fingerprints. Overriding browser fingerprints help simulate real user browsers.
This library can inject fingerprints to playwright
and puppeteer
controlled browsers through a unified interface.
It is recommended to use this library with the Apify fingerprint-generator
to achieve the best results and meet the necessary fingerprint structure.
- Installation
- Usage with the playwright
- Usage with the puppeteer
- Advanced usage with the Browser pool hooks system
- API Reference
npm install fingerprint-injector
This example shows how to use fingerprint injector with browser-pool
plugin system, playwright
firefox browser, and the Apify fingerprint-generator
const { PlaywrightPlugin } = require('browser-pool');
const FingerprintGenerator = require('fingerprint-generator');
const { FingerprintInjector } = require('fingerprint-injector');
// An asynchronous IIFE (immediately invoked function expression)
// allows us to use the 'await' keyword.
(async () => {
const playwrightPlugin = new PlaywrightPlugin(playwright.firefox, pluginOptions);
const fingerprintGenerator = new FingerprintGenerator({
devices: ['desktop'],
browsers: [{ name: 'firefox', minVersion: 88 }],
});
const { fingerprint } = fingerprintGenerator.getFingerprint();
const fingerprintInjector = new FingerprintInjector();
const launchContext = playwrightPlugin.createLaunchContext();
const browser = await playwrightPlugin.launch(launchContext);
// Forward properties to the browserContext
const context = await browser.newContext({
userAgent: fingerprint.userAgent,
locale: fingerprint.navigator.language,
});
// Attach fingerprint
await fingerprintInjector.attachFingerprintToPlaywright(context, fingerprint);
const page = await context.newPage();
})();
This example demonstrates, how to use the fingerprint injector library with puppeteer.
const FingerprintGenerator = require('fingerprint-generator');
const { FingerprintInjector } = require('fingerprint-injector');
const puppeteer = require('puppeteer')
// An asynchronous IIFE (immediately invoked function expression)
// allows us to use the 'await' keyword.
(async () => {
const fingerprintInjector = new FingerprintInjector();
const fingerprintGenerator = new FingerprintGenerator({
devices: ['desktop'],
browsers: [{ name: 'chrome', minVersion: 88 }],
});
const { fingerprint } = fingerprintGenerator.getFingerprint();
const browser = await puppeteer.launch({headless: false})
const page = await browser.newPage();
// Attach fingerprint to page
await fingerprintInjector.attachFingerprintToPuppeteer(page, fingerprint);
// Now you can use the page
await page.goto('https://google.com')
})();
This approach handles injection for both incognito context and persistent context. It is also prepared for usage with both playwright nad puppeteer.
const { BrowserPool, PlaywrightPlugin, PuppeteerPlugin } = require('browser-pool');
const FingerprintGenerator = require('fingerprint-generator');
const { FingerprintInjector } = require('fingerprint-injector');
const playwright = require('playwright');
// An asynchronous IIFE (immediately invoked function expression)
// allows us to use the 'await' keyword.
(async () => {
const pluginOptions = {
launchOptions: {
headless: false,
channel: 'chrome',
},
};
const playwrightPlugin = new PlaywrightPlugin(playwright.chromium, pluginOptions);
const fingerprintGenerator = new FingerprintGenerator({
devices: ['desktop'],
browsers: [{ name: 'chrome', minVersion: 90 }],
operatingSystems: ['linux'],
});
const { fingerprint } = fingerprintGenerator.getFingerprint();
const fingerprintInjector = new FingerprintInjector({ fingerprint });
const browserPool = new BrowserPool({
browserPlugins: [playwrightPlugin],
preLaunchHooks: [(pageId, launchContext) => {
const { useIncognitoPages, launchOptions } = launchContext;
if (useIncognitoPages) {
return;
}
launchContext.launchOptions = {
...launchOptions,
userAgent: fingerprint.userAgent,
viewport: {
width: fingerprint.screen.width,
height: fingerprint.screen.height,
},
};
}],
prePageCreateHooks: [
(pageId, browserController, pageOptions) => {
const { launchContext } = browserController;
if (launchContext.useIncognitoPages && pageOptions) {
pageOptions.userAgent = fingerprint.userAgent;
pageOptions.viewport = {
width: fingerprint.screen.width,
height: fingerprint.screen.height,
};
}
},
],
postPageCreateHooks: [
async (page, browserController) => {
const { browserPlugin, launchContext } = browserController;
if (browserPlugin instanceof PlaywrightPlugin) {
const { useIncognitoPages, isFingerprintInjected } = launchContext;
if (isFingerprintInjected) {
// If not incognitoPages are used we would add the injection script over and over which could cause memory leaks.
return;
}
console.log('Injecting fingerprint to playwright');
const context = page.context();
await fingerprintInjector.attachFingerprintToPlaywright(context, fingerprint);
if (!useIncognitoPages) {
// If not incognitoPages are used we would add the injection script over and over which could cause memory leaks.
launchContext.extend({ isFingerprintInjected: true });
}
} else if (browserPlugin instanceof PuppeteerPlugin) {
console.log('Injecting fingerprint to puppeteer');
await fingerprintInjector.attachFingerprintToPuppeteer(page, fingerprint);
}
},
],
});
const page = await browserPool.newPage();
await page.goto('https://google.com');
})();
All public classes, methods and their parameters can be inspected in this API reference.
Fingerprint injector class.
Adds init script to the browser context, so the fingerprint is changed before every document creation. DISCLAIMER: Since the playwright does not support changing viewport and User-agent after the context is created, you have to set it manually when the context is created. Check the playwright usage example.
Param | Description |
---|---|
browserContext | playwright browser context |
fingerprint | fingerprint from fingerprint-generator |
Adds script that is evaluated before every document creation. Sets User-Agent and viewport using native puppeteer interface
Param | Description |
---|---|
page | puppeteer page |
fingerprint | fingerprint from fingerprint-generator |