{"id":22134150,"url":"https://github.com/cheshirecaat/selenium-with-fingerprints","last_synced_at":"2025-04-04T22:01:40.652Z","repository":{"id":97238394,"uuid":"495526542","full_name":"CheshireCaat/selenium-with-fingerprints","owner":"CheshireCaat","description":"Anonymous automation via selenium with fingerprint replacement technology.","archived":false,"fork":false,"pushed_at":"2025-03-07T14:26:49.000Z","size":959,"stargazers_count":99,"open_issues_count":1,"forks_count":14,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-28T21:01:35.670Z","etag":null,"topics":["automation","browser","browser-fingerprint","browser-fingerprinting","chrome","chromedriver","chromium","detection-evasion","device-fingerprint","device-fingerprinting","devtools","fingerprint","fingerprinting","headless","privacy","privacy-protection","security","selenium","stealth","stealth-mode"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CheshireCaat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-23T18:22:45.000Z","updated_at":"2025-03-22T14:26:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"85bb087a-dd6d-4b9e-9514-f9b4c2492493","html_url":"https://github.com/CheshireCaat/selenium-with-fingerprints","commit_stats":{"total_commits":19,"total_committers":1,"mean_commits":19.0,"dds":0.0,"last_synced_commit":"4597a4769f88af99defaa67ed035201545708d42"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheshireCaat%2Fselenium-with-fingerprints","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheshireCaat%2Fselenium-with-fingerprints/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheshireCaat%2Fselenium-with-fingerprints/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheshireCaat%2Fselenium-with-fingerprints/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CheshireCaat","download_url":"https://codeload.github.com/CheshireCaat/selenium-with-fingerprints/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256092,"owners_count":20909240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","browser","browser-fingerprint","browser-fingerprinting","chrome","chromedriver","chromium","detection-evasion","device-fingerprint","device-fingerprinting","devtools","fingerprint","fingerprinting","headless","privacy","privacy-protection","security","selenium","stealth","stealth-mode"],"created_at":"2024-12-01T19:09:54.818Z","updated_at":"2025-04-04T22:01:40.622Z","avatar_url":"https://github.com/CheshireCaat.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# selenium-with-fingerprints\n\nThis is the repo for `selenium-with-fingerprints`, a plugin for the [selenium](https://github.com/SeleniumHQ/selenium) framework that allows you to change a browser fingerprint, generate a virtual identity and improve your browser's stealth.\n\nIn order to achieve this, the [FingerprintSwitcher](https://fp.bablosoft.com) service is used, which allows you to replace a list of important browser properties, and thus you will act like a completely new user.\n\n**WARNING:** plugin is still in beta stage, it means that bugs may happen, including critical.\n\nAdding a plugin to your project is very easy - it only takes a few lines of code.\nYou just need to change the browser startup code a bit and add method calls to get and apply fingerprints.\nThe rest of the code can remain unchanged.\nIn general, only **four** basic steps are required, see the example below (code from the example may differ slightly from the real one):\n\nhttps://user-images.githubusercontent.com/30115373/198843827-f20b628f-49f2-4d13-8ee4-1c72ae490f2e.mp4\n\nCurrent supported engine version - **133.0.6943.99**.\n\n**IMPORTANT NOTE:** plugin only work on **Windows** operating system, it cannot be installed and used on **Linux**, **macOS** and other systems!\n\n## About\n\nThis library allows you to change browser fingerprint and use **selenium** automation framework with enhanced anonymity.\nIn order to migrate and use it, a minimum of modifications and code changes is required.\n\n**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.\nBy 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.\nWhen 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.\n\nLet's look at a small example of **WebGL** property substitution.\nIn 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.\nThis result cannot be achieved using only the replacement of various browser properties via **JavaScript**, that's what this plugin and service is for:\n\n![WebGL](https://github.com/CheshireCaat/browser-with-fingerprints/raw/master/assets/webgl.jpg)\n\nYou can learn more by following this [link](https://fp.bablosoft.com/#capabilities).\n\n## Installation\n\nTo use this plugin in your project, install it with your favorite package manager:\n\n```bash\nnpm i selenium-with-fingerprints\n# or\npnpm i selenium-with-fingerprints\n# or\nyarn add selenium-with-fingerprints\n```\n\nThe `selenium-webdriver` package must also be installed. If this package is already installed, you can skip this step:\n\n```bash\nnpm i selenium-webdriver\n```\n\nBut keep in mind that some versions may not be supported. In this case, you will get an error when importing the plugin.\nYou can always find supported version numbers [here](package.json#L65).\n\nPlease note that this plugin only supports the default `selenium` library, wrappers have not been tested and may cause errors.\nAlso, according to the [architecture](#architecture) section, this plugin can only be installed and used on **Windows** operating system.\n\n## Dependencies\n\nIn order for the plugin to work correctly, just like in the standard framework, a certain version of `chromedriver` must be installed.\nYou can manually install the desired version of the driver, add the path to it in the **PATH** environment variable, and so on.\nBut it's best and safer to use a ready-made [npm](https://www.npmjs.com/package/chromedriver) package:\n\n```bash\nnpm i chromedriver@132.0.1\n```\n\nIf you're not sure which version to install, use the current supported engine version number.\nAfter the previous step, just add the package import at the very beginning of your code:\n\n```js\nrequire('chromedriver');\n```\n\nYou can look at the examples in the corresponding folder - each uses a similar approach.\nFor more information, also refer to the documentation for the original framework.\n\n## Creating new project\n\nHere's how to start working on a project from scratch.\n\nFirst you need to import the `selenium-with-fingerprints` library:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n```\n\nNo need to require the `selenium-webdriver`.\n\nAfter that, you need to obtain the fingerprint from the server and apply it:\n\n```js\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\nconst fingerprint = await plugin.fetch({\n  tags: ['Microsoft Windows', 'Chrome'],\n});\n\nplugin.useFingerprint(fingerprint);\n```\n\nWhen this code is executed, the `fingerprint` variable will contain the data required to apply the fingerprint.\nIt's a string, you can save it to a file and use it later.\nRunning this code for the first time can be very slow. Additional time is needed to download the browser.\n\nFinally, you need to create the browser instance:\n\n```js\nconst driver = await plugin.launch();\n```\n\nThe parameters of the launch method are the same as the corresponding method in the selenium library, [link](https://www.selenium.dev/selenium/docs/api/javascript/Builder.html#build).\nThe `driver` variable will contain an instance of the [WebDriver](https://www.selenium.dev/selenium/docs/api/javascript/WebDriver.html) class defined in the selenium library.\nIt means that it can be used to write a new or use an existing selenium script without any changes.\nYou need to rely on the documentation of the original framework on how to use control browser - [link](https://www.selenium.dev/selenium/docs/api/javascript/).\n\nHere is the complete code, you can copy/paste it and try:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\n(async () =\u003e {\n  // Get a fingerprint from the server:\n  const fingerprint = await plugin.fetch({\n    tags: ['Microsoft Windows', 'Chrome'],\n  });\n\n  // Apply fingerprint:\n  plugin.useFingerprint(fingerprint);\n\n  // Launch the browser instance:\n  const driver = await plugin.launch();\n\n  // The rest of the code is the same as for a standard `selenium` library:\n  await driver.get('https://example.com');\n\n  // Print the browser viewport size:\n  console.log(\n    'Viewport:',\n    await driver.executeScript(() =\u003e ({\n      deviceScaleFactor: window.devicePixelRatio,\n      width: document.documentElement.clientWidth,\n      height: document.documentElement.clientHeight,\n    }))\n  );\n\n  await driver.quit();\n})();\n```\n\nAlso take a look at the **TypeScript** declarations [here](src/index.d.ts) for more details about the exported classes, methods, and properties.\nThanks to them, when using the library, auto-completion with detailed descriptions will work.\n\n## Migration\n\nThere are a few steps required to start using fingerprints for your existing project:\n\n1. Import `selenium-with-fingerprints` instead of `selenium-webdriver`.\n2. Call the `useFingerprint` and/or `useProxy` methods to apply the fingerprint and proxy before starting the browser.\n3. Launch the browser using the `plugin.launch` method (the `plugin` variable was imported in the first step).\n4. The rest of the code can be left unchanged.\n\nConsider you have the following project using the selenium:\n\n```js\n/* Without fingerprints */\nconst { until, Builder, By } = require('selenium-webdriver');\n\n(async () =\u003e {\n  const driver = await new Builder().forBrowser('chrome').build();\n\n  await driver.get('https://browserleaks.com/canvas');\n  const el = await driver.wait(until.elementLocated(By.id('crc')));\n\n  await driver.wait(until.elementTextContains(el, '✔'));\n  console.log('Canvas signature:', await el.getText());\n\n  await driver.quit();\n})();\n```\n\nIt verifies the canvas signature by visiting [this](https://browserleaks.com/canvas) URL and parsing the corresponding value.\nNo matter how many times you run this test on the same machine, the results will be the **same**.\nThis is because this test depends on the hardware you are using - if the hardware stays the same, the results will also be the same.\nBut if we change the fingerprint, the results will be different.\n\nLet's modify this project to add fingerprint support. The updated code will look like this:\n\n```js\n/* With fingerprints */\n\n// Import `selenium-with-fingerprints` instead of `selenium-webdriver`\n// const { Builder } = require('selenium-webdriver');\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\n(async () =\u003e {\n  // Obtain a fingerprint from the server. The resulting variable contains a string - it can be stored for later use:\n  const fingerprint = await plugin.fetch({\n    tags: ['Microsoft Windows', 'Chrome'],\n  });\n\n  // Apply fingerprint - after calling the `useFingerprint` method, the browser will be launched with a fingerprint:\n  plugin.useFingerprint(fingerprint);\n\n  // Replace `builder.build` method call with `plugin.launch`:\n  // const driver = await new Builder().forBrowser('chrome').build();\n  const driver = await plugin.launch({ builder: new Builder().forBrowser('chrome') });\n\n  // The rest of the code is the same as for the standard `selenium` library:\n  await driver.get('https://browserleaks.com/canvas');\n  const el = await driver.wait(until.elementLocated(By.id('crc')));\n\n  await driver.wait(until.elementTextContains(el, '✔'));\n  console.log('Canvas signature:', await el.getText());\n\n  await driver.quit();\n})();\n```\n\nAfter running the updated code, a new fingerprint will be applied each time, so the scores will be different for each run.\n\n## Common problems\n\nYou can find information about known issues related to updates, as well as ways to solve them in [this](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/MIGRATION.md) guide.\n\n## Launching the browser\n\nYou can launch the browser in two different ways. There are two methods for this - **launch** and **spawn**.\n\nThe parameters and return type of the **launch** method are exactly the same as for `Builder.build` method.\nYou can use the official [API](https://www.selenium.dev/selenium/docs/api/javascript/Builder.html#build) documentation to learn more about them.\nThe **launch** method also has the same purpose - to start a new browser instance with the given parameters and connect to it.\n\nIn addition to the standard functionality, it allows you to change the fingerprint and proxy using the `useFingerprint` and `useProxy` methods.\nA detailed description and annotations can also be found [here](src/index.d.ts#L49).\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\nconst browser = await plugin.launch({ builder: new Builder() });\n```\n\nThe **spawn** method works in a similar way, but uses a separate mechanism to launch the browser.\nThe main difference is that this method just starts the process, but doesn't connect to it for automation - you can do it yourself later.\n\nThis method returns a running browser instance that can be used to connect to an existing session using `selenium`:\n\n```js\nconst { Builder } = require('selenium-webdriver');\nconst { Options } = require('selenium-webdriver/chrome');\nconst { plugin } = require('selenium-with-fingerprints');\n\nconst chrome = await plugin.spawn({ headless: true });\n\nconst driver = await new Builder()\n  .forBrowser('chrome')\n  .setChromeOptions(new Options().debuggerAddress(`localhost:${chrome.port}`))\n  .build();\n\nawait driver.quit();\nawait chrome.close();\n```\n\nAt [this](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/plugin/launcher/index.d.ts#L54) link you can find a detailed description of all the options allowed for **spawn** method.\nThe same goes for the return type declaration, details of which can be found [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/plugin/launcher/index.d.ts#L6).\n\nIf 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.\n\nAnnotations 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.\nYou can also find out about it directly [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts) and [here](src/index.d.ts).\n\n## Configuring plugin\n\nAt the moment, it is possible to change the service key, working folder and timeout for requests to the engine, which is used when fetching, applying fingerprints, and so on:\n\n```js\n// Set the fingerprint service key for all plugin methods that require it.\nplugin.setServiceKey('SERVICE_KEY');\n\n// Set the folder where the plugin engine will be installed:\nplugin.setWorkingFolder('./engine');\n\n// Set the timeout used when fetching fingerprints and so on:\nplugin.setRequestTimeout(5 * 60000);\n\n// Set the timeout used when installing/downloading engine:\nplugin.setEngineTimeout(10 * 60000);\n```\n\nThe methods from the example above change the settings globally, that is, for all instances of the plugin.\n\nThe default values are the `./data` directory for the working folder and `300000` milliseconds for the request timeout.\n\nAn empty string is used for the fingerprint service key by default, which means that the free version of the service will be used.\n\n## Configuring browser\n\nIn order to change the fingerprint and proxy for your browser, you should use special separate methods:\n\n- **useProxy** - to change the proxy configuration.\n- **useProfile** - to change the profile configuration.\n- **useFingerprint** - to change the fingerprint configuration.\n\nThese methods directly affect only the next launch of the browser. So you should always use them before using the `launch` plugin method.\n\nYou cannot change the settings once the browser is launched - more specifically, an already launched instance will not be affected by the new configuration.\nBut you can safely change the options for the next run, or for a separate browser instance with a different unique configuration.\n\nYou can also **chain** calls, since all these methods return the current plugin instance. It does not matter in which order the settings will be applied. It might look like this:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\nconst fingerprint = await plugin.fetch({\n  tags: ['Microsoft Windows', 'Chrome'],\n});\n\nplugin.useProxy('127.0.0.1:8080').useFingerprint(fingerprint);\n```\n\nUse these links to see a detailed description of the methods:\n\n- [This](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L94) one for the **useFingerprint** method\n  (also see additional options [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/fingerprint.d.ts#L4)).\n- [This](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L124) one for the **useProfile** method\n  (also see additional options [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/profile.d.ts#L4)).\n- [This](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L152) one for the **useProxy** method\n  (also see additional options [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/proxy.d.ts#L24)).\n\nThe usage of these methods is very similar - each takes two parameters, the first of which is the configuration data itself, and the second is additional options.\nThe fingerprint and proxy will not be changed unless the appropriate method is used. In this case, all settings related to browser fingerprinting will remain at their original values.\n\nFingerprint and proxy aren't applied instantly when calling methods. Instead, the configuration is saved and used directly when the browser is launched using the **launch** or **spawn** methods.\nThus, you can pre-configure the plugin in a certain way, or change something immediately before launching the browser.\n\n### Configuring browser version\n\nYou can change the browser version right while using the plugin - the engine may come with several different builds of the browser.\n\nIn order to do this, use the **useBrowserVersion** method.\nThe `default` value means that the latest available version will be used:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Use a specific version:\nplugin.useBrowserVersion('128.0.6613.85');\n\n// Use the latest available version:\nplugin.useBrowserVersion('default');\n```\n\nIf you specify an unavailable or invalid version, an appropriate error will be thrown when the browser starts.\nAlso keep in mind that this property only affects a specific instance of the plugin, not the entire library.\n\nIn order to get a list of available versions shipped with the engine, use the **versions** method.\nIt returns a list of browser versions as strings or objects with additional information, depending on the format passed:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\n// The list of versions is always sorted in descending order:\nawait plugin.versions('extended').then((versions) =\u003e {\n  // The latest available browser version will be used:\n  plugin.useBrowserVersion(versions[0]['browser_version']);\n});\n```\n\nThanks to this, you can, for example, use the version that corresponds to a certain fingerprint, and vice versa.\n\n### Fingerprint usage\n\nIn order to change the fingerprint, you need to run the `useFingerprint` method before starting the browser, i.e. before using the plugin's `launch` method.\n\nThe `useFingerprint` method takes two parameters.\nThe first is a string with fingerprint data that you can request from the service.\nThe 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:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\nconst fingerprint = await plugin.fetch({\n  tags: ['Microsoft Windows', 'Chrome'],\n});\n\nplugin.useFingerprint(fingerprint, {\n  // It's disabled by default.\n  safeElementSize: true,\n  // It's enabled by default.\n  safeBattery: false,\n});\n```\n\nIn order to obtain fingerprints you should use the **fetch** plugin method.\nPass the service key as the first argument for the **serviceKey** and additional parameters for the **fetch**, if necessary:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\nconst fingerprint = await plugin.fetch({\n  tags: ['Microsoft Windows', 'Chrome'],\n  // Fetch fingerprints only with a browser version higher than 130:\n  minBrowserVersion: 130,\n  // Fetch fingerprints only with a browser version lower than 132:\n  maxBrowserVersion: 132,\n  // Fetch fingerprints only collected in the last 15 days:\n  timeLimit: '15 days',\n});\n```\n\nIn order to use filters and many other settings from the example above, you will need a premium key, the same applies to tags that differ from the default ones:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\nplugin.setServiceKey('SERVICE_KEY');\n\n// In order to use custom tags you need the premium key:\nconst fingerprint = await plugin.fetch({\n  tags: ['Android', 'Chrome'],\n});\nplugin.useFingerprint(fingerprint);\n\nawait plugin.launch();\n```\n\nAll possible settings for **fetch** method, as well as their descriptions, you can find [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/fetch.d.ts#L35).\n\nThe special `current` value can be used to filter fingerprints by browser version - in this case, the version installed for the plugin will be used.\nIt can be very convenient as the browser and fingerprint versions will be exactly the same and you don't have to enter the exact values in multiple places.\n\nYou can **reuse** fingerprints instead of requesting new ones each time.\nTo do this, you can save them to a file or to a database - use any option convenient for you.\nIn 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:\n\n```js\nconst { readFile, writeFile } = require('fs/promises');\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\n// Save the fingerprint to a file:\nconst fingerprint = await plugin.fetch({\n  tags: ['Microsoft Windows', 'Chrome'],\n});\nawait writeFile('fingerprint.json', fingerprint);\n\n// Load fingerprint from file at next run:\nplugin.useFingerprint(await readFile('fingerprint.json', 'utf8'));\n```\n\nYou can learn more about the options directly when adding these methods - just use the built-in [annotations](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L214).\n\nYou can use any [tags](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/fetch.d.ts#L13), filters\n(e.g. [time](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/fetch.d.ts#L6) limit) and settings if you have a service key.\n\nIf you specify an empty string as the first argument for the `fetch` or the `setServiceKey` method, the free version will be used.\nFor a free version you won't be able to use other tags than the default ones, as well as some other filters:\n\n```js\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\nconst fingerprint = await plugin.fetch({\n  // You can only use these tags with the free version:\n  tags: ['Microsoft Windows', 'Chrome'],\n  // You also cannot use such filters in the free version:\n  // minBrowserVersion: 130,\n});\n```\n\nIn the free version, the [PerfectCanvas](https://wiki.bablosoft.com/doku.php?id=perfectcanvas) technology is also not available.\nThere are other limitations when using the free version - for example, limiting the number of requests in a certain period of time.\nTo see the differences and limits of different versions, visit [this](https://fp.bablosoft.com/#pricing) website.\n\nYou can buy a key [here](https://bablosoft.com/directbuy/FingerprintSwitcher/2) to avoid limitations.\n\n### Profile usage\n\nIn order to use a specific browser profile, you can, among other options, use the `useProfile` method.\nAs the first parameter, it takes the path to the profile folder - the same value that you specify, for example, for the `user-data-dir` argument.\nThe second parameter is additional options that are primarily responsible for loading fingerprint and proxy data from the profile folder:\n\n```js\nconst path = require('path');\nconst { plugin } = require('selenium-with-fingerprints');\n\n// Set the service key for the plugin (you can buy it here https://bablosoft.com/directbuy/FingerprintSwitcher/2).\n// Leave an empty string to use the free version.\nplugin.setServiceKey('');\n\n// The key may be required if the fingerprint will be used from the profile.\nplugin.useProfile(path.resolve('./profile'), {\n  // Don't load fingerprint from profile folder:\n  loadFingerprint: false,\n  // Don't load proxy from profile folder:\n  loadProxy: false,\n});\n```\n\nBy default, the plugin will load proxy and fingerprint data from the profile folder, if they are written there.\nYou can change this behavior by setting the options to `false` - for example, if you are not sure that the stored proxy is working.\nPlease note that if you add your fingerprint or proxy through the appropriate methods, then the data you specified will be used regardless of the options.\n\nYou can also use other options to set the path to the profile folder, such as the `userDataDir` option, if you don't need additional settings:\n\n```js\nconst path = require('path');\nconst { Builder } = require('selenium-webdriver');\nconst { Options } = require('selenium-webdriver/chrome');\nconst { plugin } = require('selenium-with-fingerprints');\n\nconst options = new Options().addArguments(\n  // Browser arguments can be used as well:\n  `--user-data-dir=${path.resolve('./profile')}`\n);\n\nconst browser = await plugin.launch({ builder: new Builder().setChromeOptions(options) });\n```\n\nAfter launching a browser with your profile, the fingerprint and proxy data you specified will always be stored in the profile folder.\nThis setting itself is saved between browser launches, that is, it behaves in the same way as other similar methods.\nTo run different profiles, you need to call this method again with different values for the profile directory.\n\nYou can learn more about the parameters and additional options for this method [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L124)\nand [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/profile.d.ts#L4).\n\n#### Temporary profiles\n\nSince version `1.3.0` the plugin uses its own logic to configure browser profiles.\nThis primarily applies to situations where you don't specify options like `user-data-dir` yourself.\n\nEach framework makes temporary profiles in such cases in completely different places, but for the convenience and correct operation of some fingerprint components, a different solution is used.\nIf you do not specify the path to the profile yourself, then the engine will create its own temporary one - such a profile will be located directly in the engine folder, for example:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\n// The profile will be located in the `data/profiles/UNIQUE_ID` folder:\nconst browser = await plugin.launch();\n```\n\nIf you specify the path yourself, then everything will work as usual - just the plugin will add additional components, like `widevine` or default extensions, to the specified profile.\n\nAlso keep in mind that if you specify your own folder for the engine using the `setWorkingFolder` method, then the profile path will be adjusted.\n\n### Proxy usage\n\nIn order to set up a proxy, you should use the `useProxy` method.\nThe first parameter of this method is a string with information about the proxy.\nThe second parameter is additional options that will be applied to the browser, for example, automatic change of language and time zone:\n\n```js\nconst { plugin } = require('selenium-with-fingerprints');\n\nplugin.useProxy('127.0.0.1:8080', {\n  // Change browser timezone according to proxy:\n  changeTimezone: true,\n  // Replace browser geolocation according to proxy:\n  changeGeolocation: true,\n});\n```\n\nYou can learn more about the parameters and additional options for this method [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L152)\nand [here](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/proxy.d.ts#L24).\n\nThe browser supports two types of proxies - **https** and **socks5**.\nIt is better to always specify the proxy type in the address line - otherwise, **https** will be used by default.\n\nYou can use aliases - **http** instead of **https** and **socks** instead of **socks5**.\nProxies with authorization (with login and password) are also supported.\n\nIn general, when specifying addresses, you can use many different formats, for example:\n\n- `127.0.0.1:8080`\n- `https://127.0.0.1:8080`\n- `socks5://127.0.0.1:8181`\n- `username:password@127.0.0.1:8080`\n- `socks:127.0.0.1:8080:username:password`\n- `https://username:password:127.0.0.1:8080`\n\nIn order to preserve compatibility with the original library syntax, the proxy can be obtained from the arguments you specified.\nThe `proxy-server` option will be used as the value, and all other options will be set to their default values.\nBut this will be done only if you didn't call the appropriate method for the proxy configuration:\n\n```js\nconst { Builder } = require('selenium-webdriver');\nconst { Options } = require('selenium-webdriver/chrome');\nconst { plugin } = require('selenium-with-fingerprints');\n\nconst options = new Options().addArguments(\n  // The syntax for specifying an argument value\n  // is exactly the same as for using a separate method.\n  '--proxy-server=https://127.0.0.1:8080'\n);\n\nconst browser = await plugin.launch({ builder: new Builder().setChromeOptions(options) });\n```\n\nIt'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.\n\n### More info\n\nIf 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](https://fp.bablosoft.com) link.\nThere you can also get a test fingerprint and see ready-made values that can be applied to your browser.\n\n### More examples\n\nPlease take a look at the [examples](examples) directory with ready-made real code examples.\nYou can run them yourself by cloning the repository locally and installing the dependencies.\n\n## Architecture\n\nThis plugin uses the [FingerprintSwitcher](https://fp.bablosoft.com) service to get fingerprints.\nThe resulting fingerprints are used later directly when working with the browser and are applied in a special way using a custom configuration files.\n\nThere are some **limitations** in using the package, which may be critical or non-critical depending on your task.\nFor example, for the correct operation of the fingerprint substitution technology, a custom browser with various patches is required.\nThis browser is downloaded and installed automatically the first time the **API** methods are called.\nIt also implies a limitation - it will be impossible to use standard and other various engines.\n\nFingerprints aren't generated, but downloaded from the service, as they are collected from real devices.\nIt greatly improves the anonymity and quality of the substitution of various properties.\n\nAlso keep in mind that this package only work on the **Windows** operating system.\nIf you install or run it on other platforms, you will get the corresponding errors.\nThis is a forced measure due to the presence of some critical **Windows-only** dependencies without which this implementation will not work.\n\nThe plugin architecture can be summarized as the following diagram:\n\n![Architecture](https://github.com/CheshireCaat/browser-with-fingerprints/raw/master/assets/plugin.jpg)\n\nAll packages can only work with the **Chrome** browser, which comes bundled with the libraries and loads automatically.\nThe path to the executable file is defined on the plugin side and cannot be changed.\nIt means that you will not be able to use not only other versions of **Chrome** or **Chromium**, but also other browser engines.\nThe same goes for some framework-specific launch options.\n\nThis library tries to replicate the interfaces of the **selenium** framework as much as possible.\nThus, it's convenient to use it not only for new projects, but also when migrating from the original version to this plugin.\nFor things not related to launching the browser and the plugin directly, it's better to use the methods and properties of the original library.\n\n### Limitations\n\nPlease **note** that there are some restrictions at the moment:\n\n- Only **Windows** operating system is supported.\n- Parallel launch of browsers is synchronized between calls.\n- Working with **workers** is possible only when specifying a separate working folder for each of them.\n\nAlso, there is no guarantee that each of these items will be changed in the future.\n\n## Alternatives\n\nCheck out other ready-made plugins for popular automation frameworks that have a similar **API** and architecture:\n\n- Plugin for **puppeteer** - [puppeteer-with-fingerprints](https://github.com/CheshireCaat/puppeteer-with-fingerprints)\n- Plugin for **playwright** - [playwright-with-fingerprints](https://github.com/CheshireCaat/playwright-with-fingerprints)\n\nAlso check out [BAS](https://bablosoft.com/shop/BrowserAutomationStudio) - a great alternative to automate the **Chrome** browser without programming skills.\nIt also supports fingerprint substitution, has simple and powerful multithreading and other advantages.\n\n## Documentation\n\nHere you can find a brief description of methods and classes, as well as links to them.\n\n#### [Tag](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/fetch.d.ts#L13)\n\nDescribes a tag value that can be used to filter fingerprints.\n\n---\n\n#### [Time](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/fetch.d.ts#L6)\n\nDescribes a time limit that can be used to filter fingerprints.\n\n---\n\n### [Version](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L16)\n\nDescribes an object that provides complete information about the available browser version.\n\n---\n\n#### [plugin.versions(format?)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L64)\n\n- `format` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The output format of the returned result.\n\nReturns: **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\u0026lt;Version[]|string[]\u003e** The list of objects with detailed version information, or a list of strings.\n\nGet a list of all available browser versions.\n\n---\n\n#### [plugin.spawn(options?)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L250)\n\n- `options` **[Options](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/plugin/launcher/index.d.ts#L54)?** Launcher options that only apply to the browser when using the `spawn` method.\n\nReturns: **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\u0026lt;Browser\u003e** Promise which resolves to a browser instance.\n\nLaunches a browser instance with given arguments and options when specified.\n\n---\n\n#### [plugin.launch(options?)](src/index.d.ts#L49)\n\n- `options` **[LaunchOptions](src/index.d.ts#L7)?** Set of configurable options to set on the browser.\n\nReturns: **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\u0026lt;Selenium.WebDriver\u003e** Promise which resolves to a browser instance.\n\nLaunches **selenium** and launches a browser instance with given arguments and options when specified.\n\n---\n\n#### [plugin.fetch(options?)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L214)\n\n- `options` **[FetchOptions](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/fetch.d.ts#L35)?** Set of configurable options for getting a browser fingerprint.\n\nReturns: **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)\u0026lt;string\u003e** Promise which resolves to a fingerprint string.\n\nObtain a fingerprint using the specified service key and additional options.\n\n---\n\n#### [plugin.useBrowserVersion(version)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L175)\n\n- `value` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Version value as a string.\n\nReturns: **this** The same plugin instance with an updated settings (for optional chaining).\n\nSet the current browser version used by the plugin instance.\n\n---\n\n#### [plugin.useProxy(value?, options?)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L152)\n\n- `value` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Proxy value as a string.\n- `options` **[ProxyOptions](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/proxy.d.ts#L24)?** Set of configurable options for applying a proxy.\n\nSet the proxy settings using the specified proxy as a string and additional options when specified.\n\nReturns: **this** The same plugin instance with an updated settings (for optional chaining).\n\n---\n\n#### [plugin.useProfile(value?, options?)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L124)\n\n- `value` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Profile value as a string.\n- `options` **[ProfileOptions](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/profile.d.ts#L4)?** Set of configurable options for applying a profile.\n\nReturns: **this** The same plugin instance with an updated settings (for optional chaining).\n\nSet the profile settings using the specified profile as a string and additional options when specified.\n\n---\n\n#### [plugin.useFingerprint(value?, options?)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L94)\n\n- `value` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Fingerprint value as a string.\n- `options` **[FingerprintOptions](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/types/fingerprint.d.ts#L4)?** Set of configurable options for applying a fingerprint.\n\nSet the fingerprint settings using the specified fingerprint as a string and additional options when specified.\n\nReturns: **this** The same plugin instance with an updated settings (for optional chaining).\n\n---\n\n#### [plugin.setWorkingFolder(folder)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L301)\n\n- `folder` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The working folder that the plugin engine will use.\n\nSet the working folder that the plugin uses to work with the engine.\n\n---\n\n#### [plugin.setRequestTimeout(timeout)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L267)\n\n- `timeout` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The request timeout that the plugin engine will use.\n\nSet the timeout that the plugin uses when executing requests (pass `0` to disable it).\n\n---\n\n#### [plugin.setEngineTimeout(timeout)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L284)\n\n- `timeout` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The engine timeout that the plugin engine will use.\n\nSet the timeout that the plugin uses when fetching engine (pass `0` to disable it).\n\n---\n\n#### [plugin.setServiceKey(key)](https://github.com/CheshireCaat/browser-with-fingerprints/blob/master/src/index.d.ts#L318)\n\n- `key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The service key for obtaining and applying a fingerprint.\n\nSet the fingerprint service key for all plugin methods that require it.\n\n---\n\n## Troubleshooting\n\nIf you encounter any issue or bug, please use the [issues](https://github.com/CheshireCaat/selenium-with-fingerprints/issues) section of the repository.\n\nPlease describe the problem in as much detail as possible when creating tickets - indicate the sequence of actions (steps) to repeat the problem, error output, and so on.\n\nIf the code is large, attach it as files or use sandboxes. At the same time, it's better to remove from it areas that do not relate to the problem - it will be much easier to figure it out.\nFormat your code and wrap it in special **markdown** tags if you're adding it to an issue report, for example:\n\n```js\n// your code\n```\n\nPlease be careful not to attach various **secrets** in your code or screenshots - for example, fingerprint service keys, account passwords, and so on.\nIn the case of service keys, this can lead to their blocking without a refund.\n\nIf the recommendations are not followed, your ticket may be ignored.\n\n## Testing\n\nThe excellent [mocha](https://github.com/mochajs/mocha) framework is used for tests in this library.\nUse the command line or ready-made scripts if you want to run them yourself.\n\nYou can also use the **FINGERPRINT_CWD** environment variable to specify the directory where the engine will be stored, for example:\n\n```properties\nFINGERPRINT_CWD=\"../plugin-engine\"\n```\n\nThe **FINGERPRINT_TIMEOUT** variable can be set if it's necessary to change the default timeout for executing engine methods, such as applying or fetching a fingerprint:\n\n```properties\nFINGERPRINT_TIMEOUT=300000\n```\n\nYou can define it in any way convenient for you, but by default variables are read from the **env** files using the [dotenv](https://github.com/motdotla/dotenv) library.\n\n## License\n\nCopyright © 2025, [CheshireCaat](https://github.com/CheshireCaat). Released under the [MIT](LICENSE.md) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheshirecaat%2Fselenium-with-fingerprints","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcheshirecaat%2Fselenium-with-fingerprints","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheshirecaat%2Fselenium-with-fingerprints/lists"}