puppeteer-with-fingerprints
This is the repo for puppeteer-with-fingerprints
, a plugin for the puppeteer framework that allows you to use fingerprints, generate a virtual identity and improve your browser's stealth.
In order to achieve this, the FingerprintSwitcher service is used, which allows you to replace all browser properties, and thus you will act like a completely new user.
About
The library allows you to change browser fingerprints and use puppeteer automation framework with enhanced anonymity.
When using ready-made plugins for frameworks, a minimum of modifications and code changes for migration is required.
Adding a plugin to your project is very easy - it only takes a few lines of code.
You just need to change the browser startup code a bit and add method calls to get and apply fingerprints.
In general, only four basic steps are required, see the example below:
https://user-images.githubusercontent.com/30115373/198843995-2d1a7941-e5e6-4344-9f59-f8bf43adab00.mp4
Browser fingerprinting - is a technique that allows to identify the user by a combination of browser properties, such as - fonts, resolution, list of plugins, navigator properties, etc.
By adding new factors and using browser API in a special way, a site can determine exactly which user is visiting it, even if the user is using a proxy.
When using this package and replacing fingerprints, websites will not be able to identify you from other users, as all these properties and results of API calls will be replaced with values from real devices.
Let's look at a small example of WebGL property substitution.
In the screenshot below, the left column shows the values from the regular browser, and the right column shows the values substituted using ready-made fingerprints.
This result cannot be achieved using only the replacement of various browser properties via JavaScript, that's what this plugin and service is for:
You can learn more about this by following the link to the fingerprint changing service used by plugins to bypass such technologies.
There are many other examples on this website - you can also see a list of pre-made properties from a real fingerprint.
Getting started
To use this plugin in your project, install it with your favorite package manager:
npm i puppeteer-with-fingerprints
pnpm i puppeteer-with-fingerprints
yarn add puppeteer-with-fingerprints
You can also use the puppeteer-core
package instead of puppeteer
to work with this plugin.
Both options will work correctly and do not require additional steps to make the plugin work with them.
Please note that this plugin only supports the default puppeteer
library, wrappers have not been tested and may cause errors.
If you add a plugin to an existing project, then by default you don't need any other dependencies - just use the version you already have installed.
Otherwise, you can install the puppeteer
package separately or along with the plugin:
npm i puppeteer puppeteer-with-fingerprints
npm i puppeteer-core puppeteer-with-fingerprints
But keep in mind that some versions may not be supported. In this case, you will get an error when importing the plugin.
Migration guide
In order to use this plugin in your project, you must install it and import it separately from the puppeteer
package.
Consider an example - evaluating a script in the context of a page:
const { plugin } = require('puppeteer-with-fingerprints');
(async () => {
const browser = await plugin.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(
'Viewport:',
await page.evaluate(() => ({
deviceScaleFactor: window.devicePixelRatio,
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
}))
);
await browser.close();
})();
The minimum change required is to replace the puppeteer#launch()
method call with a plugin#launch()
to properly apply the fingerprint and proxy for your browser.
The same applies to new projects - the new code will need to be written with the changes described here.
It means that the plugin partially replaces the methods of the original library - options and types corresponding to the standard ones are used to launch the browser.
This is directly related to the way the browser is launched, the rest of the interaction with the library does not change, so you can safely use the puppeteer
documentation to work.
You may run into a few small issues when using the plugin, for example:
- Launching the browser will take a little longer.
- Some standard options may not be supported.
The first point is due to the need to configure the browser before launching.
You can speed up this process by saving and reusing your fingerprints so you don't have to request them from the service every time.
If you use unsupported options, you will get corresponding errors at startup, so you can easily fix it.
For example, the plugin does not support launching other browsers than its built-in one:
const { plugin, UNSUPPORTED_OPTIONS } = require('puppeteer-with-fingerprints');
console.log(UNSUPPORTED_OPTIONS);
await plugin.launch({ channel: 'chrome-canary' });
Launching the browser
You can launch the browser in two different ways. There are two methods for this - launch and spawn.
The first one uses the native launcher of the library, the integration with which is implemented in a specific plugin.
This does not apply to the base library and this method cannot be used with it.
The launch method uses the framework's built-in methods to launch the browser under the hood and, accordingly, accepts the same options.
The only difference is the presence of additional code inside the plugin that applies the fingerprint and proxy. The sample code may look something like this:
const { plugin } = require('puppeteer-with-fingerprints');
const browser = await plugin.launch({
args: ['--mute-audio'],
headless: true,
});
In this case, a launcher derived from the main exported type of the framework is used, and the plugin method itself uses its launch function.
The parameters and return type of the launch method are exactly the same as the original ones and are not modified in any way.
You can use the official API documentation to learn more about them.
The spawn method works in a similar way, but uses a separate mechanism to launch the browser.
It just starts the process, but doesn't connect to it for automation - you can do it yourself later.
This method returns a running browser instance that can be used to connect to an existing session using puppeteer
:
const puppeteer = require('puppeteer');
const { plugin } = require('puppeteer-with-fingerprints');
const chrome = await plugin.spawn({ headless: true });
const browser = await puppeteer.connect({
browserWSEndpoint: chrome.url,
});
await browser.close();
await chrome.close();
If possible, use it only in extreme cases. It is much more convenient to use the launch method to launch the browser, which minimizes the number of steps for proper initialization and configuration.
Annotations are described for all plugins methods directly in the library code via the TypeScript declarations, so when using it you will be able to see hints for all options and types.
You can also find out about it directly here and here.
Advanced usage
In order to change the fingerprint and proxy for your browser, you should use special separate methods:
- useProxy - to change the proxy configuration.
- useFingerprint - to change the fingerprint configuration.
These methods directly affect only the next launch of the browser. That is, you should always use them before using the launch
plugin method.
You cannot change the settings once the browser is launched - more specifically, an already launched instance will not be affected by the new configuration.
But you can safely change the options for the next run, or for a separate browser instance with a different unique configuration.
You can also chain calls, since both methods return the current plugin instance. It does not matter in which order the settings will be applied. It might look like this:
The use of these methods is very similar - they both take two parameters, the first of which is the configuration data itself, and the second is additional options.
const { plugin } = require('puppeteer-with-fingerprints');
const browser = await plugin.useProxy().useFingerprint().launch({
headless: true,
timeout: 0,
args: [],
});
If these methods have not been called, the fingerprint and proxy will not be changed. In this case, all the specific settings will be left in their original values.
Fingerprint and proxy are not applied instantly when calling methods. Instead, the configuration is saved and used directly when the browser is launched using the launch or spawn methods.
Thus, you can pre-configure the plugin in a certain way, or change something immediately before launching the browser.
Fingerprint usage
The useFingerprint
method takes two parameters.
The first is a string with fingerprint data that you can request from the service.
The second is additional options for applying a fingerprint, most of which are applied automatically - for example, the safe replacement of the BatteryAPI and AudioAPI properties:
const { plugin } = require('browser-with-fingerprints');
const fingerprint = await plugin.fetch('', {
tags: ['Microsoft Windows', 'Chrome'],
});
plugin.useFingerprint(fingerprint, {
safeElementSize: true,
safeBattery: false,
});
In order to obtain fingerprints you should use the fetch plugin method.
Pass the service key as the first argument and additional parameters as the second, if necessary:
const { plugin } = require('puppeteer-with-fingerprints');
const fingerprint = await plugin.fetch('SERVICE_KEY', {
tags: ['Microsoft Windows', 'Chrome'],
minBrowserVersion: 98,
timeLimit: '15 days',
});
You can reuse fingerprints instead of requesting new ones each time.
To do this, you can save them to a file or to a database - use any option convenient for you.
In this way, you can speed up the process of launching the browser with the parameters you need, organize your storage, filter and sort fingerprints locally, and much more:
const { readFile, writeFile } = require('fs').promises;
const { plugin } = require('puppeteer-with-fingerprints');
const fingerprint = await plugin.fetch('', {
tags: ['Microsoft Windows', 'Chrome'],
});
await writeFile('fingerprint.json', fingerprint);
plugin.useFingerprint(await readFile('fingerprint.json', 'utf8'));
You can learn more about the options directly when adding these methods - just use the built-in annotations.
You can use any tags, filters and settings if you have a service key.
The premium version has the most advanced functionality, although for many tasks the free one will be enough.
If you specify an empty string as the first argument, the free version will be used.
But note that you won't be able to use other tags than the default ones, as well as some options:
const fingerprint = await plugin.fetch('', {
tags: ['Microsoft Windows', 'Chrome'],
minBrowserVersion: 105,
});
First of all, this concerns the options that filter fingerprints in one way or another, as well as the use of PerfectCanvas technology.
There are other limitations when using the free version - for example, limiting the number of requests in a certain period of time.
To see the differences and limits of different versions, visit the service website, which is listed just below in the section with additional information.
Proxy usage
In order to set up a proxy, you should use the useProxy
method.
The first parameter of this method is a string with information about the proxy.
The second parameter is additional options that will be applied to the browser, for example, automatic change of language and time zone:
const { plugin } = require('puppeteer-with-fingerprints');
plugin.useProxy('127.0.0.1:8080', {
changeTimezone: true,
changeGeolocation: true,
});
The browser supports two types of proxies - https and socks5.
It is better to always specify the proxy type in the address line - otherwise, https will be used by default.
You can use aliases - http instead of https and socks instead of socks5.
Proxies with authorization (with login and password) are also supported.
In general, when specifying addresses, you can use many different formats, for example:
127.0.0.1:8080
https://127.0.0.1:8080
socks5://127.0.0.1:8181
username:password@127.0.0.1:8080
socks:127.0.0.1:8080:username:password
https://username:password:127.0.0.1:8080
In order to preserve some compatibility, the proxy can be obtained from the arguments you specified.
The proxy-server
option will be used as the value, and all other options will be set to their default values.
But this will be done only if you did not call the appropriate method for the proxy configuration:
const { plugin } = require('puppeteer-with-fingerprints');
const browser = await plugin.launch({
args: ['--proxy-server=https://127.0.0.1:8080'],
});
It's better to replace such code with the useProxy
method. This is much more convenient because you can immediately set the additional options you need.
More info
If you are having problems with the default plugin, or want to create multiple instances with different settings, you can use a separate exported createPlugin
method.
It allows you to create a standalone plugin instance that is used in the same way as a standard one. It takes a puppeteer compatible launcher object as a parameter:
const puppeteer = require('puppeteer');
const { createPlugin } = require('puppeteer-with-fingerprints');
const plugin1 = createPlugin({
launch: (options) => puppeteer.launch(options),
});
const plugin2 = createPlugin(puppeteer);
Use this with caution and only in extreme cases - for example, if you are using a wrapper library. It is much safer to work with a standard instance.
If you want to learn more about fingerprint substitution technology, explore the list of replaceable properties and various options, such as tags, get or configure your service key, use this link.
There you can also get a test fingerprint and see ready-made values that can be applied to your browser.
More examples
Please take a look at the examples directory with ready-made real code examples.
You can run them yourself by cloning the repository locally and installing the dependencies.
Architecture
This plugin uses the FingerprintSwitcher service to get fingerprints.
The resulting fingerprints are used later directly when working with the browser and are applied in a special way using a custom configuration files.
There are some limitations in using the plugin, which may be critical or non-critical depending on your task.
For example, for the correct operation of the fingerprint substitution technology, a custom browser with various patches is required.
It will be used automatically when working with plugins.
Also keep in mind that all plugins only work on the Windows operating system.
This is a forced measure due to the presence of some critical Windows-only dependencies, without which the plugins would not work correctly.
If you install or run the libraries on other platforms, you will get the corresponding errors.
The plugin architecture can be summarized as the following diagram:
All plugins can only work with the Chrome browser, which comes bundled with the libraries and loads automatically.
The path to the executable file is defined on the plugin side and cannot be changed.
It means that you will not be able to use not only other versions of Chrome or Chromium, but also other browser engines.
The same goes for some framework-specific launch options.
Alternatives
Check out other ready-made plugins for popular automation frameworks that have a similar API and architecture:
Also check out BAS - a great alternative to automate the Chrome browser without programming skills.
It also supports fingerprint substitution, has simple and powerful multithreading and other advantages.
Testing
The excellent mocha framework is used for tests in this library.
Use the command line or ready-made scripts if you want to run them yourself.
You can also use the FINGERPRINT_CWD variable to specify the directory where the engine will be stored, for example:
FINGERPRINT_CWD="../plugin-engine"
You can define it in any way convenient for you, but by default variables are read from the env files using the dotenv library.
License
Copyright © 2022 - 2022, CheshireCaat. Released under the MIT license.