<h1 align="center">
BrowserForge
</h1>
<p align="center">
<a href="https://github.com/daijro/browserforge/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/daijro/browserforge.svg?color=yellow">
</a>
<a href="https://python.org/">
<img src="https://img.shields.io/badge/python-3.8‐3.12-blue">
</a>
<a href="https://pypi.org/project/browserforge/">
<img alt="PyPI" src="https://img.shields.io/pypi/v/browserforge.svg?color=orange">
</a>
<a href="https://pepy.tech/project/browserforge">
<img alt="PyPI" src="https://static.pepy.tech/badge/browserforge">
</a>
<a href="https://github.com/ambv/black">
<img src="https://img.shields.io/badge/code%20style-black-black.svg">
</a>
<a href="https://github.com/PyCQA/isort">
<img src="https://img.shields.io/badge/imports-isort-yellow.svg">
</a>
<a href="http://mypy-lang.org">
<img src="http://www.mypy-lang.org/static/mypy_badge.svg">
</a>
</p>
<h4 align="center">
🎠Intelligent browser header & fingerprint generator
</h4>
---
## What is it?
BrowserForge is a browser header and fingerprint generator that mimics the frequency of different browsers, operating systems, and devices found in the wild.
It is a reimplementation of [Apify's fingerprint-suite](https://github.com/apify/fingerprint-suite) in Python.
## Features
- Uses a Bayesian generative network to mimic actual web traffic
- Extremely fast runtime (0.1-0.2 miliseconds)
- Easy and simple for humans to use
- Extensive customization options for browsers, operating systems, devices, locales, and HTTP version
- Written with type safety
## Installation
```
pip install browserforge
python -m browserforge update
```
**Note:** The `browserforge update` command is needed to download model definitions. If the command is not run, files will be downloaded on the first import.
<hr width=50>
## Usage
## Generating Headers
### Simple usage
```py
>>> from browserforge.headers import HeaderGenerator
>>> headers = HeaderGenerator()
>>> headers.generate()
{'sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"', 'Sec-Ch-Ua-Mobile': '?0', 'Sec-Ch-Ua-Platform': '"Windows"', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Sec-Fetch-Site': '?1', 'Sec-Fetch-Mode': 'same-site', 'Sec-Fetch-User': 'document', 'Sec-Fetch-Dest': 'navigate', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Accept-Language': 'en-US;q=1.0'}
```
### Using with requests
Headers can be added to a session in [requests](https://github.com/psf/requests) (or similar libraries) by assigning them to the `headers` attribute:
```py
import requests
session = requests.Session()
# Set the session headers
session.headers = headers.generate()
```
<details>
<summary>Parameters for HeaderGenerator</summary>
```
Parameters:
browser (Union[ListOrString, Iterable[Browser]], optional): Browser(s) or Browser object(s).
os (ListOrString, optional): Operating system(s) to generate headers for.
device (ListOrString, optional): Device(s) to generate the headers for.
locale (ListOrString, optional): List of at most 10 languages for the Accept-Language header. Default is 'en-US'.
http_version (Literal[1, 2], optional): Http version to be used to generate headers. Defaults to 2.
strict (bool, optional): Throws an error if it cannot generate headers based on the input. Defaults to False.
```
</details>
<details>
<summary>Parameters for HeaderGenerator.generate</summary>
```
Generates headers using the default options and their possible overrides.
Parameters:
browser (Optional[Iterable[Union[str, Browser]]], optional): Browser(s) to generate the headers for.
os (Optional[ListOrString], optional): Operating system(s) to generate the headers for.
device (Optional[ListOrString], optional): Device(s) to generate the headers for.
locale (Optional[ListOrString], optional): Language(s) to include in the Accept-Language header.
http_version (Optional[Literal[1, 2]], optional): HTTP version to be used to generate headers.
user_agent (Optional[ListOrString], optional): User-Agent(s) to use.
request_dependent_headers (Optional[Dict[str, str]], optional): Known values of request-dependent headers.
strict (Optional[bool], optional): If true, throws an error if it cannot generate headers based on the input.
```
</details>
### Constraining headers
#### Single constraint
Set constraints for browsers by passing the optional strings below:
```py
headers = HeaderGenerator(
browser='chrome',
os='windows',
device='desktop',
locale='en-US',
http_version=2
)
```
#### Multiple constraints
Set multiple constraints to select from. Options are selected based on their actual frequency in the wild:
```py
headers = HeaderGenerator(
browser=('chrome', 'firefox', 'safari', 'edge'),
os=('windows', 'macos', 'linux', 'android', 'ios'),
device=('desktop', 'mobile'),
locale=('en-US', 'en', 'de'),
http_version=2
)
```
#### Browser specifications
Set specificiations for browsers, including version ranges and HTTP version:
```py
from browserforge.headers import Browser
browsers = [
Browser(name='chrome', min_version=100, max_version=110),
Browser(name='firefox', max_version=80, http_version=1),
Browser(name='edge', min_version=95),
]
headers = HeaderGenerator(browser=browsers)
```
Note that all constraints passed into the `HeaderGenerator` constructor can be overridden by passing them into the `generate` method.
#### Generate headers given User-Agent
Headers can be generated given an existing user agent:
```py
>>> headers.generate(user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36')
```
Select from multiple User-Agents based on their frequency in the wild:
```py
>>> headers.generate(user_agent=(
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0'
))
```
<hr width=50>
## Generating Fingerprints
### Simple usage
Initialize FingerprintGenerator:
```py
from browserforge.fingerprints import FingerprintGenerator
fingerprints = FingerprintGenerator()
fingerprints.generate()
```
<details>
<summary>Parameters for FingerprintGenerator</summary>
```
Parameters:
screen (Screen, optional): Screen constraints for the generated fingerprint.
strict (bool, optional): Whether to raise an exception if the constraints are too strict. Default is False.
mock_webrtc (bool, optional): Whether to mock WebRTC when injecting the fingerprint. Default is False.
slim (bool, optional): Disables performance-heavy evasions when injecting the fingerprint. Default is False.
**header_kwargs: Header generation options for HeaderGenerator
```
</details>
<details>
<summary>Parameters for FingerprintGenerator.generate</summary>
```
Generates a fingerprint and a matching set of ordered headers using a combination of the default options specified in the constructor and their possible overrides provided here.
Parameters:
screen (Screen, optional): Screen constraints for the generated fingerprint.
strict (bool, optional): Whether to raise an exception if the constraints are too strict.
mock_webrtc (bool, optional): Whether to mock WebRTC when injecting the fingerprint. Default is False.
slim (bool, optional): Disables performance-heavy evasions when injecting the fingerprint. Default is False.
**header_kwargs: Additional header generation options for HeaderGenerator.generate
```
</details>
<details>
<summary>Example response</summary>
```
Fingerprint(screen=ScreenFingerprint(availHeight=784,
availWidth=1440,
availTop=25,
availLeft=0,
colorDepth=30,
height=900,
pixelDepth=30,
width=1440,
devicePixelRatio=2,
pageXOffset=0,
pageYOffset=0,
innerHeight=0,
outerHeight=718,
outerWidth=1440,
innerWidth=0,
screenX=0,
clientWidth=0,
clientHeight=19,
hasHDR=True),
navigator=NavigatorFingerprint(userAgent='Mozilla/5.0 (Macintosh; '
'Intel Mac OS X 10_15_7) '
'AppleWebKit/537.36 '
'(KHTML, like Gecko) '
'Chrome/121.0.0.0 '
'Safari/537.36',
userAgentData={'architecture': 'arm',
'bitness': '64',
'brands': [{'brand': 'Not '
'A(Brand',
'version': '99'},
{'brand': 'Google '
'Chrome',
'version': '121'},
{'brand': 'Chromium',
'version': '121'}],
'fullVersionList': [{'brand': 'Not '
'A(Brand',
'version': '99.0.0.0'},
{'brand': 'Google '
'Chrome',
'version': '121.0.6167.160'},
{'brand': 'Chromium',
'version': '121.0.6167.160'}],
'mobile': False,
'model': '',
'platform': 'macOS',
'platformVersion': '13.6.1',
'uaFullVersion': '121.0.6167.160'},
doNotTrack=None,
appCodeName='Mozilla',
appName='Netscape',
appVersion='5.0 (Macintosh; Intel '
'Mac OS X 10_15_7) '
'AppleWebKit/537.36 '
'(KHTML, like Gecko) '
'Chrome/121.0.0.0 '
'Safari/537.36',
oscpu=None,
webdriver=False,
language='en-US',
languages=['en-US'],
platform='MacIntel',
deviceMemory=8,
hardwareConcurrency=10,
product='Gecko',
productSub='20030107',
vendor='Google Inc.',
vendorSub=None,
maxTouchPoints=0,
extraProperties={'globalPrivacyControl': None,
'installedApps': [],
'isBluetoothSupported': False,
'pdfViewerEnabled': True,
'vendorFlavors': ['chrome']}),
headers={'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US;q=1.0',
'Sec-Fetch-Dest': 'navigate',
'Sec-Fetch-Mode': 'same-site',
'Sec-Fetch-Site': '?1',
'Sec-Fetch-User': 'document',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X '
'10_15_7) AppleWebKit/537.36 (KHTML, like '
'Gecko) Chrome/121.0.0.0 Safari/537.36',
'sec-ch-ua': '"Not A(Brand";v="99", "Google '
'Chrome";v="121", "Chromium";v="121"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"'},
videoCodecs={'h264': 'probably', 'ogg': '', 'webm': 'probably'},
audioCodecs={'aac': 'probably',
'm4a': 'maybe',
'mp3': 'probably',
'ogg': 'probably',
'wav': 'probably'},
pluginsData={'mimeTypes': ['Portable Document '
'Format~~application/pdf~~pdf',
'Portable Document '
'Format~~text/pdf~~pdf'],
'plugins': [{'description': 'Portable Document Format',
'filename': 'internal-pdf-viewer',
'mimeTypes': [{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'PDF '
'Viewer',
'suffixes': 'pdf',
'type': 'application/pdf'},
{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'PDF '
'Viewer',
'suffixes': 'pdf',
'type': 'text/pdf'}],
'name': 'PDF Viewer'},
{'description': 'Portable Document Format',
'filename': 'internal-pdf-viewer',
'mimeTypes': [{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'Chrome '
'PDF '
'Viewer',
'suffixes': 'pdf',
'type': 'application/pdf'},
{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'Chrome '
'PDF '
'Viewer',
'suffixes': 'pdf',
'type': 'text/pdf'}],
'name': 'Chrome PDF Viewer'},
{'description': 'Portable Document Format',
'filename': 'internal-pdf-viewer',
'mimeTypes': [{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'Chromium '
'PDF '
'Viewer',
'suffixes': 'pdf',
'type': 'application/pdf'},
{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'Chromium '
'PDF '
'Viewer',
'suffixes': 'pdf',
'type': 'text/pdf'}],
'name': 'Chromium PDF Viewer'},
{'description': 'Portable Document Format',
'filename': 'internal-pdf-viewer',
'mimeTypes': [{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'Microsoft '
'Edge '
'PDF '
'Viewer',
'suffixes': 'pdf',
'type': 'application/pdf'},
'Document '
'Format',
'enabledPlugin': 'Microsoft '
'Edge '
'PDF '
'Viewer',
'suffixes': 'pdf',
'type': 'text/pdf'}],
'name': 'Microsoft Edge PDF Viewer'},
{'description': 'Portable Document Format',
'filename': 'internal-pdf-viewer',
'mimeTypes': [{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'WebKit '
'built-in '
'PDF',
'suffixes': 'pdf',
'type': 'application/pdf'},
{'description': 'Portable '
'Document '
'Format',
'enabledPlugin': 'WebKit '
'built-in '
'PDF',
'suffixes': 'pdf',
'type': 'text/pdf'}],
'name': 'WebKit built-in PDF'}]},
battery={'charging': False,
'chargingTime': None,
'dischargingTime': 29940,
'level': 0.98},
videoCard=VideoCard(renderer='ANGLE (Apple, ANGLE Metal Renderer: '
'Apple M2 Pro, Unspecified Version)',
vendor='Google Inc. (Apple)'),
multimediaDevices={'micros': [{'deviceId': '',
'groupId': '',
'kind': 'audioinput',
'label': ''}],
'speakers': [{'deviceId': '',
'groupId': '',
'kind': 'audiooutput',
'label': ''}],
'webcams': [{'deviceId': '',
'groupId': '',
'kind': 'videoinput',
'label': ''}]},
fonts=['Arial Unicode MS', 'Gill Sans', 'Helvetica Neue', 'Menlo']
mockWebRTC: False,
slim: False)
```
</details>
### Constraining fingerprints
#### Screen width/height
Constrain the minimum/maximum screen width and height:
```py
from browserforge.fingerprints import Screen
screen = Screen(
min_width=100
max_width=1280
min_height=400
max_height=720
)
fingerprints = FingerprintGenerator(screen=screen)
```
Note: Not all bounds need to be defined.
#### Browser specifications
`FingerprintGenerator` and `FingerprintGenerator.generate` inherit the same parameters from `HeaderGenerator`.
Because of this, user agents, browser specifications, device types, and operating system constrains can also be passed into `FingerprintGenerator.generate`.
Here is a usage example:
```py
fingerprint.generate(browser='chrome', os='windows')
```
<hr width=50>
## Injecting Fingerprints
BrowserForge is fully compatible with your existing Playwright and Pyppeteer code. You only have to change your context/page initialization.
### Playwright
#### Async API:
```py
# Import the AsyncNewContext injector
from browserforge.injectors.playwright import AsyncNewContext
async def main():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch()
# Create a new async context with the injected fingerprint
context = await AsyncNewContext(browser, fingerprint=fingerprint)
page = await context.new_page()
...
```
Replace `await browser.new_context` with `await AsyncNewContext` in your existing Playwright code.
<details>
<summary>Parameters for AsyncNewContext</summary>
```
Injects an async_api Playwright context with a Fingerprint.
Parameters:
browser (Browser): The browser to create the context in
fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated
fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed
**new_context_options: Other options for the new context
```
</details>
#### Sync API:
```py
# Import the NewContext injector
from browserforge.injectors.playwright import NewContext
def main():
with sync_playwright() as playwright:
browser = playwright.chromium.launch()
# Create a new context with the injected fingerprint
context = NewContext(browser, fingerprint=fingerprint)
page = context.new_page()
...
```
Replace `browser.new_context` with `NewContext` in your existing Playwright code.
<details>
<summary>Parameters for NewContext</summary>
```
Injects a sync_api Playwright context with a Fingerprint.
Parameters:
browser (Browser): The browser to create the context in
fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated
fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed
**new_context_options: Other options for the new context
```
</details>
#### Undetected-Playwright
[Undetected-Playwright](https://github.com/kaliiiiiiiiii/undetected-playwright-python) is also supported in the `browserforge.injectors.undetected_playwright` package. The usage is the same as the Playwright injector.
### Pyppeteer
```py
# Import the NewPage injector
from browserforge.injectors.pyppeteer import NewPage
from pyppeteer import launch
async def test():
browser = await launch()
# Create a new page with the injected fingerprint
page = await NewPage(browser, fingerprint=fingerprint)
...
```
Replace `browser.newPage` with `NewPage` in your existing Pyppeteer code.
<details>
<summary>Parameters for NewPage</summary>
```
Injects a Pyppeteer browser object with a Fingerprint.
Parameters:
browser (Browser): The browser to create the context in
fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated
fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed
```
</details>
<hr width=50>
## Uninstall
To fully remove all files, run the following commands:
```
python -m browserforge remove
pip uninstall browserforge
```
---
Raw data
{
"_id": null,
"home_page": "https://github.com/daijro/browserforge",
"name": "browserforge",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "client, headers, fingerprint, generator, browser, http, scraping, requests, playwright",
"author": "daijro",
"author_email": "daijro.dev@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/e4/69/ba87f839a1675496d89af88d03f2cb45d7b1a686496b3855ed0ced1bfe69/browserforge-1.1.2.tar.gz",
"platform": null,
"description": "<h1 align=\"center\">\n BrowserForge\n</h1>\n\n<p align=\"center\">\n <a href=\"https://github.com/daijro/browserforge/blob/main/LICENSE\">\n <img src=\"https://img.shields.io/github/license/daijro/browserforge.svg?color=yellow\">\n </a>\n <a href=\"https://python.org/\">\n <img src=\"https://img.shields.io/badge/python-3.8‐3.12-blue\">\n </a>\n <a href=\"https://pypi.org/project/browserforge/\">\n <img alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/browserforge.svg?color=orange\">\n </a>\n <a href=\"https://pepy.tech/project/browserforge\">\n <img alt=\"PyPI\" src=\"https://static.pepy.tech/badge/browserforge\">\n </a>\n <a href=\"https://github.com/ambv/black\">\n <img src=\"https://img.shields.io/badge/code%20style-black-black.svg\">\n </a>\n <a href=\"https://github.com/PyCQA/isort\">\n <img src=\"https://img.shields.io/badge/imports-isort-yellow.svg\">\n </a>\n <a href=\"http://mypy-lang.org\">\n <img src=\"http://www.mypy-lang.org/static/mypy_badge.svg\">\n </a>\n</p>\n\n<h4 align=\"center\">\n \ud83c\udfad Intelligent browser header & fingerprint generator\n</h4>\n\n---\n\n## What is it?\n\nBrowserForge is a browser header and fingerprint generator that mimics the frequency of different browsers, operating systems, and devices found in the wild.\n\nIt is a reimplementation of [Apify's fingerprint-suite](https://github.com/apify/fingerprint-suite) in Python.\n\n## Features\n\n- Uses a Bayesian generative network to mimic actual web traffic\n- Extremely fast runtime (0.1-0.2 miliseconds)\n- Easy and simple for humans to use\n- Extensive customization options for browsers, operating systems, devices, locales, and HTTP version\n- Written with type safety\n\n## Installation\n\n```\npip install browserforge\npython -m browserforge update\n```\n\n**Note:** The `browserforge update` command is needed to download model definitions. If the command is not run, files will be downloaded on the first import.\n\n<hr width=50>\n\n## Usage\n\n## Generating Headers\n\n### Simple usage\n\n```py\n>>> from browserforge.headers import HeaderGenerator\n>>> headers = HeaderGenerator()\n>>> headers.generate()\n{'sec-ch-ua': '\"Chromium\";v=\"122\", \"Not(A:Brand\";v=\"24\", \"Google Chrome\";v=\"122\"', 'Sec-Ch-Ua-Mobile': '?0', 'Sec-Ch-Ua-Platform': '\"Windows\"', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Sec-Fetch-Site': '?1', 'Sec-Fetch-Mode': 'same-site', 'Sec-Fetch-User': 'document', 'Sec-Fetch-Dest': 'navigate', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Accept-Language': 'en-US;q=1.0'}\n```\n\n### Using with requests\n\nHeaders can be added to a session in [requests](https://github.com/psf/requests) (or similar libraries) by assigning them to the `headers` attribute:\n\n```py\nimport requests\nsession = requests.Session()\n# Set the session headers\nsession.headers = headers.generate()\n```\n\n<details>\n<summary>Parameters for HeaderGenerator</summary>\n\n```\nParameters:\n browser (Union[ListOrString, Iterable[Browser]], optional): Browser(s) or Browser object(s).\n os (ListOrString, optional): Operating system(s) to generate headers for.\n device (ListOrString, optional): Device(s) to generate the headers for.\n locale (ListOrString, optional): List of at most 10 languages for the Accept-Language header. Default is 'en-US'.\n http_version (Literal[1, 2], optional): Http version to be used to generate headers. Defaults to 2.\n strict (bool, optional): Throws an error if it cannot generate headers based on the input. Defaults to False.\n```\n\n</details>\n\n<details>\n<summary>Parameters for HeaderGenerator.generate</summary>\n\n```\nGenerates headers using the default options and their possible overrides.\n\nParameters:\n browser (Optional[Iterable[Union[str, Browser]]], optional): Browser(s) to generate the headers for.\n os (Optional[ListOrString], optional): Operating system(s) to generate the headers for.\n device (Optional[ListOrString], optional): Device(s) to generate the headers for.\n locale (Optional[ListOrString], optional): Language(s) to include in the Accept-Language header.\n http_version (Optional[Literal[1, 2]], optional): HTTP version to be used to generate headers.\n user_agent (Optional[ListOrString], optional): User-Agent(s) to use.\n request_dependent_headers (Optional[Dict[str, str]], optional): Known values of request-dependent headers.\n strict (Optional[bool], optional): If true, throws an error if it cannot generate headers based on the input.\n```\n\n</details>\n\n### Constraining headers\n\n#### Single constraint\n\nSet constraints for browsers by passing the optional strings below:\n\n```py\nheaders = HeaderGenerator(\n browser='chrome',\n os='windows',\n device='desktop',\n locale='en-US',\n http_version=2\n)\n```\n\n#### Multiple constraints\n\nSet multiple constraints to select from. Options are selected based on their actual frequency in the wild:\n\n```py\nheaders = HeaderGenerator(\n browser=('chrome', 'firefox', 'safari', 'edge'),\n os=('windows', 'macos', 'linux', 'android', 'ios'),\n device=('desktop', 'mobile'),\n locale=('en-US', 'en', 'de'),\n http_version=2\n)\n```\n\n#### Browser specifications\n\nSet specificiations for browsers, including version ranges and HTTP version:\n\n```py\nfrom browserforge.headers import Browser\n\nbrowsers = [\n Browser(name='chrome', min_version=100, max_version=110),\n Browser(name='firefox', max_version=80, http_version=1),\n Browser(name='edge', min_version=95),\n]\nheaders = HeaderGenerator(browser=browsers)\n```\n\nNote that all constraints passed into the `HeaderGenerator` constructor can be overridden by passing them into the `generate` method.\n\n#### Generate headers given User-Agent\n\nHeaders can be generated given an existing user agent:\n\n```py\n>>> headers.generate(user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36')\n```\n\nSelect from multiple User-Agents based on their frequency in the wild:\n\n```py\n>>> headers.generate(user_agent=(\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0'\n))\n```\n\n<hr width=50>\n\n## Generating Fingerprints\n\n### Simple usage\n\nInitialize FingerprintGenerator:\n\n```py\nfrom browserforge.fingerprints import FingerprintGenerator\nfingerprints = FingerprintGenerator()\nfingerprints.generate()\n```\n\n<details>\n<summary>Parameters for FingerprintGenerator</summary>\n\n```\nParameters:\n screen (Screen, optional): Screen constraints for the generated fingerprint.\n strict (bool, optional): Whether to raise an exception if the constraints are too strict. Default is False.\n mock_webrtc (bool, optional): Whether to mock WebRTC when injecting the fingerprint. Default is False.\n slim (bool, optional): Disables performance-heavy evasions when injecting the fingerprint. Default is False.\n **header_kwargs: Header generation options for HeaderGenerator\n```\n\n</details>\n\n<details>\n<summary>Parameters for FingerprintGenerator.generate</summary>\n\n```\nGenerates a fingerprint and a matching set of ordered headers using a combination of the default options specified in the constructor and their possible overrides provided here.\n\nParameters:\n screen (Screen, optional): Screen constraints for the generated fingerprint.\n strict (bool, optional): Whether to raise an exception if the constraints are too strict.\n mock_webrtc (bool, optional): Whether to mock WebRTC when injecting the fingerprint. Default is False.\n slim (bool, optional): Disables performance-heavy evasions when injecting the fingerprint. Default is False.\n **header_kwargs: Additional header generation options for HeaderGenerator.generate\n```\n\n</details>\n\n<details>\n<summary>Example response</summary>\n\n```\nFingerprint(screen=ScreenFingerprint(availHeight=784,\n availWidth=1440,\n availTop=25,\n availLeft=0,\n colorDepth=30,\n height=900,\n pixelDepth=30,\n width=1440,\n devicePixelRatio=2,\n pageXOffset=0,\n pageYOffset=0,\n innerHeight=0,\n outerHeight=718,\n outerWidth=1440,\n innerWidth=0,\n screenX=0,\n clientWidth=0,\n clientHeight=19,\n hasHDR=True),\n navigator=NavigatorFingerprint(userAgent='Mozilla/5.0 (Macintosh; '\n 'Intel Mac OS X 10_15_7) '\n 'AppleWebKit/537.36 '\n '(KHTML, like Gecko) '\n 'Chrome/121.0.0.0 '\n 'Safari/537.36',\n userAgentData={'architecture': 'arm',\n 'bitness': '64',\n 'brands': [{'brand': 'Not '\n 'A(Brand',\n 'version': '99'},\n {'brand': 'Google '\n 'Chrome',\n 'version': '121'},\n {'brand': 'Chromium',\n 'version': '121'}],\n 'fullVersionList': [{'brand': 'Not '\n 'A(Brand',\n 'version': '99.0.0.0'},\n {'brand': 'Google '\n 'Chrome',\n 'version': '121.0.6167.160'},\n {'brand': 'Chromium',\n 'version': '121.0.6167.160'}],\n 'mobile': False,\n 'model': '',\n 'platform': 'macOS',\n 'platformVersion': '13.6.1',\n 'uaFullVersion': '121.0.6167.160'},\n doNotTrack=None,\n appCodeName='Mozilla',\n appName='Netscape',\n appVersion='5.0 (Macintosh; Intel '\n 'Mac OS X 10_15_7) '\n 'AppleWebKit/537.36 '\n '(KHTML, like Gecko) '\n 'Chrome/121.0.0.0 '\n 'Safari/537.36',\n oscpu=None,\n webdriver=False,\n language='en-US',\n languages=['en-US'],\n platform='MacIntel',\n deviceMemory=8,\n hardwareConcurrency=10,\n product='Gecko',\n productSub='20030107',\n vendor='Google Inc.',\n vendorSub=None,\n maxTouchPoints=0,\n extraProperties={'globalPrivacyControl': None,\n 'installedApps': [],\n 'isBluetoothSupported': False,\n 'pdfViewerEnabled': True,\n 'vendorFlavors': ['chrome']}),\n headers={'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',\n 'Accept-Encoding': 'gzip, deflate, br',\n 'Accept-Language': 'en-US;q=1.0',\n 'Sec-Fetch-Dest': 'navigate',\n 'Sec-Fetch-Mode': 'same-site',\n 'Sec-Fetch-Site': '?1',\n 'Sec-Fetch-User': 'document',\n 'Upgrade-Insecure-Requests': '1',\n 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X '\n '10_15_7) AppleWebKit/537.36 (KHTML, like '\n 'Gecko) Chrome/121.0.0.0 Safari/537.36',\n 'sec-ch-ua': '\"Not A(Brand\";v=\"99\", \"Google '\n 'Chrome\";v=\"121\", \"Chromium\";v=\"121\"',\n 'sec-ch-ua-mobile': '?0',\n 'sec-ch-ua-platform': '\"macOS\"'},\n videoCodecs={'h264': 'probably', 'ogg': '', 'webm': 'probably'},\n audioCodecs={'aac': 'probably',\n 'm4a': 'maybe',\n 'mp3': 'probably',\n 'ogg': 'probably',\n 'wav': 'probably'},\n pluginsData={'mimeTypes': ['Portable Document '\n 'Format~~application/pdf~~pdf',\n 'Portable Document '\n 'Format~~text/pdf~~pdf'],\n 'plugins': [{'description': 'Portable Document Format',\n 'filename': 'internal-pdf-viewer',\n 'mimeTypes': [{'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'PDF '\n 'Viewer',\n 'suffixes': 'pdf',\n 'type': 'application/pdf'},\n {'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'PDF '\n 'Viewer',\n 'suffixes': 'pdf',\n 'type': 'text/pdf'}],\n 'name': 'PDF Viewer'},\n {'description': 'Portable Document Format',\n 'filename': 'internal-pdf-viewer',\n 'mimeTypes': [{'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'Chrome '\n 'PDF '\n 'Viewer',\n 'suffixes': 'pdf',\n 'type': 'application/pdf'},\n {'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'Chrome '\n 'PDF '\n 'Viewer',\n 'suffixes': 'pdf',\n 'type': 'text/pdf'}],\n 'name': 'Chrome PDF Viewer'},\n {'description': 'Portable Document Format',\n 'filename': 'internal-pdf-viewer',\n 'mimeTypes': [{'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'Chromium '\n 'PDF '\n 'Viewer',\n 'suffixes': 'pdf',\n 'type': 'application/pdf'},\n {'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'Chromium '\n 'PDF '\n 'Viewer',\n 'suffixes': 'pdf',\n 'type': 'text/pdf'}],\n 'name': 'Chromium PDF Viewer'},\n {'description': 'Portable Document Format',\n 'filename': 'internal-pdf-viewer',\n 'mimeTypes': [{'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'Microsoft '\n 'Edge '\n 'PDF '\n 'Viewer',\n 'suffixes': 'pdf',\n 'type': 'application/pdf'},\n 'Document '\n 'Format',\n 'enabledPlugin': 'Microsoft '\n 'Edge '\n 'PDF '\n 'Viewer',\n 'suffixes': 'pdf',\n 'type': 'text/pdf'}],\n 'name': 'Microsoft Edge PDF Viewer'},\n {'description': 'Portable Document Format',\n 'filename': 'internal-pdf-viewer',\n 'mimeTypes': [{'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'WebKit '\n 'built-in '\n 'PDF',\n 'suffixes': 'pdf',\n 'type': 'application/pdf'},\n {'description': 'Portable '\n 'Document '\n 'Format',\n 'enabledPlugin': 'WebKit '\n 'built-in '\n 'PDF',\n 'suffixes': 'pdf',\n 'type': 'text/pdf'}],\n 'name': 'WebKit built-in PDF'}]},\n battery={'charging': False,\n 'chargingTime': None,\n 'dischargingTime': 29940,\n 'level': 0.98},\n videoCard=VideoCard(renderer='ANGLE (Apple, ANGLE Metal Renderer: '\n 'Apple M2 Pro, Unspecified Version)',\n vendor='Google Inc. (Apple)'),\n multimediaDevices={'micros': [{'deviceId': '',\n 'groupId': '',\n 'kind': 'audioinput',\n 'label': ''}],\n 'speakers': [{'deviceId': '',\n 'groupId': '',\n 'kind': 'audiooutput',\n 'label': ''}],\n 'webcams': [{'deviceId': '',\n 'groupId': '',\n 'kind': 'videoinput',\n 'label': ''}]},\n fonts=['Arial Unicode MS', 'Gill Sans', 'Helvetica Neue', 'Menlo']\n mockWebRTC: False,\n slim: False)\n```\n\n</details>\n\n### Constraining fingerprints\n\n#### Screen width/height\n\nConstrain the minimum/maximum screen width and height:\n\n```py\nfrom browserforge.fingerprints import Screen\n\nscreen = Screen(\n min_width=100\n max_width=1280\n min_height=400\n max_height=720\n)\n\nfingerprints = FingerprintGenerator(screen=screen)\n```\n\nNote: Not all bounds need to be defined.\n\n#### Browser specifications\n\n`FingerprintGenerator` and `FingerprintGenerator.generate` inherit the same parameters from `HeaderGenerator`.\n\nBecause of this, user agents, browser specifications, device types, and operating system constrains can also be passed into `FingerprintGenerator.generate`.\n\nHere is a usage example:\n\n```py\nfingerprint.generate(browser='chrome', os='windows')\n```\n\n<hr width=50>\n\n## Injecting Fingerprints\n\nBrowserForge is fully compatible with your existing Playwright and Pyppeteer code. You only have to change your context/page initialization.\n\n### Playwright\n\n#### Async API:\n\n```py\n# Import the AsyncNewContext injector\nfrom browserforge.injectors.playwright import AsyncNewContext\n\nasync def main():\n async with async_playwright() as playwright:\n browser = await playwright.chromium.launch()\n # Create a new async context with the injected fingerprint\n context = await AsyncNewContext(browser, fingerprint=fingerprint)\n page = await context.new_page()\n ...\n```\n\nReplace `await browser.new_context` with `await AsyncNewContext` in your existing Playwright code.\n\n<details>\n<summary>Parameters for AsyncNewContext</summary>\n\n```\nInjects an async_api Playwright context with a Fingerprint.\n\nParameters:\n browser (Browser): The browser to create the context in\n fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated\n fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed\n **new_context_options: Other options for the new context\n```\n\n</details>\n\n#### Sync API:\n\n```py\n# Import the NewContext injector\nfrom browserforge.injectors.playwright import NewContext\n\ndef main():\n with sync_playwright() as playwright:\n browser = playwright.chromium.launch()\n # Create a new context with the injected fingerprint\n context = NewContext(browser, fingerprint=fingerprint)\n page = context.new_page()\n ...\n```\n\nReplace `browser.new_context` with `NewContext` in your existing Playwright code.\n\n<details>\n<summary>Parameters for NewContext</summary>\n\n```\nInjects a sync_api Playwright context with a Fingerprint.\n\nParameters:\n browser (Browser): The browser to create the context in\n fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated\n fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed\n **new_context_options: Other options for the new context\n```\n\n</details>\n\n#### Undetected-Playwright\n\n[Undetected-Playwright](https://github.com/kaliiiiiiiiii/undetected-playwright-python) is also supported in the `browserforge.injectors.undetected_playwright` package. The usage is the same as the Playwright injector.\n\n### Pyppeteer\n\n```py\n# Import the NewPage injector\nfrom browserforge.injectors.pyppeteer import NewPage\nfrom pyppeteer import launch\n\nasync def test():\n browser = await launch()\n # Create a new page with the injected fingerprint\n page = await NewPage(browser, fingerprint=fingerprint)\n ...\n```\n\nReplace `browser.newPage` with `NewPage` in your existing Pyppeteer code.\n\n<details>\n<summary>Parameters for NewPage</summary>\n\n```\nInjects a Pyppeteer browser object with a Fingerprint.\n\nParameters:\n browser (Browser): The browser to create the context in\n fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated\n fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed\n```\n\n</details>\n\n<hr width=50>\n\n## Uninstall\n\nTo fully remove all files, run the following commands:\n\n```\npython -m browserforge remove\npip uninstall browserforge\n```\n\n---\n\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Intelligent browser header & fingerprint generator",
"version": "1.1.2",
"project_urls": {
"Homepage": "https://github.com/daijro/browserforge",
"Repository": "https://github.com/daijro/browserforge"
},
"split_keywords": [
"client",
" headers",
" fingerprint",
" generator",
" browser",
" http",
" scraping",
" requests",
" playwright"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "8457e8e1b8f0610a1e9da088839c40706886a960c4804c0ff021a5a0cd160b5c",
"md5": "bd74ed760e64a6343718b2f4f7e7285b",
"sha256": "91eae5b85adb32dfc4d3245e46660d4cf25dd023326a4d4611ccaaaf1cca9207"
},
"downloads": -1,
"filename": "browserforge-1.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "bd74ed760e64a6343718b2f4f7e7285b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 39593,
"upload_time": "2024-04-03T03:14:30",
"upload_time_iso_8601": "2024-04-03T03:14:30.123216Z",
"url": "https://files.pythonhosted.org/packages/84/57/e8e1b8f0610a1e9da088839c40706886a960c4804c0ff021a5a0cd160b5c/browserforge-1.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e469ba87f839a1675496d89af88d03f2cb45d7b1a686496b3855ed0ced1bfe69",
"md5": "b6be928a792d632a87d15c13cdd79d7f",
"sha256": "41eb344c9a58d84d7840bfc916243a2136ca48c47da34e0534063918ebe7770f"
},
"downloads": -1,
"filename": "browserforge-1.1.2.tar.gz",
"has_sig": false,
"md5_digest": "b6be928a792d632a87d15c13cdd79d7f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 35013,
"upload_time": "2024-04-03T03:14:31",
"upload_time_iso_8601": "2024-04-03T03:14:31.926826Z",
"url": "https://files.pythonhosted.org/packages/e4/69/ba87f839a1675496d89af88d03f2cb45d7b1a686496b3855ed0ced1bfe69/browserforge-1.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-03 03:14:31",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "daijro",
"github_project": "browserforge",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "browserforge"
}