scrapy-impersonate

repository·master·Indexed 42 days ago

https://github.com/jxlil/scrapy-impersonate

A Scrapy download handler that integrates curl_cffi to impersonate TLS signatures and JA3 fingerprints of web browsers. It allows requests to mimic browsers like Chrome, Firefox, Safari, Edge, and Tor, and includes a RandomBrowserMiddleware for browser rotation.

Tokens
1.9K
Snippets
6
Records
7
Agent score
4%

What's inside scrapy-impersonate

  1. How RandomBrowserMiddleware works

    master

    The scrapy_impersonate.RandomBrowserMiddleware rotates the impersonated browser across chrome, firefox, safari, edge, and tor by default.

    You can restrict the set of browsers used for rotation by setting the IMPERSONATE_BROWSERS setting in your Scrapy configuration (e.g., IMPERSONATE_BROWSERS = ["chrome", "firefox"]).

  2. Activate scrapy-impersonate in Scrapy

    master

    To enable impersonation, you must perform three steps in your Scrapy settings:

    1. Replace Download Handlers: Update DOWNLOAD_HANDLERS to use scrapy_impersonate.ImpersonateDownloadHandler for both http and https.
    2. Set User-Agent: Set USER_AGENT = "" (an empty string). This allows curl_cffi to automatically select the correct User-Agent matching the impersonated browser.
    3. Use Asyncio Reactor: Ensure you are using the asyncio-based Twisted reactor for proper asynchronous execution by setting TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor".
    DOWNLOAD_HANDLERS = {
        "http": "scrapy_impersonate.ImpersonateDownloadHandler",
        "https": "scrapy_impersonate.ImpersonateDownloadHandler",
    }
    
    USER_AGENT = ""
    
    TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"
  3. Configure impersonate_curl_options for libcurl

    master

    Use the impersonate_curl_options key in Request.meta to pass raw libcurl options through. Keys can be CurlOpt members or their names. These options take precedence over the handler's default settings.

    A common use case is pinning header order to bypass WAFs that check for stable browser header sequences (requires curl_cffi >= 0.16.0 for HTTPHEADER_ORDER).

    yield scrapy.Request(
        "https://tls.browserleaks.com/json",
        dont_filter=True,
        meta={
            "impersonate": "chrome",
            "impersonate_curl_options": {
                "HTTPHEADER_ORDER": "Host,Connection,User-Agent,Accept,Referer",
            },
        },
    )
  4. Configure impersonate_args for curl_cffi

    master

    Use the impersonate_args key in Request.meta to pass arguments directly to curl_cffi.

    Warning: allow_redirects is forced to False by the handler so that Scrapy manages redirects. Enabling it via impersonate_args can lead to redirect-based SSRF vulnerabilities.

    Commonly used arguments:

    • http_version: Set to "v3" to use HTTP/3.
    • doh_url: Resolve DNS over HTTPS (requires curl_cffi >= 0.16.0).
    • interface: Bind the request to a specific network interface or local source address.
    • extra_fp: Fine-tune fingerprint details on top of the impersonated browser.
    yield scrapy.Request(
        "https://tls.browserleaks.com/json",
        dont_filter=True,
        meta={
            "impersonate": "chrome124",
            "impersonate_args": {
                "verify": False,
                "timeout": 10,
            },
        },
    )
  5. Use impersonation in Scrapy Requests

    master

    To trigger impersonation for a specific request, set the impersonate key in the Request.meta dictionary. You can also pass additional arguments to curl_cffi via impersonate_args or raw libcurl options via impersonate_curl_options.

    import scrapy
    
    class ImpersonateSpider(scrapy.Spider):
        name = "impersonate_spider"
        custom_settings = {
            "TWISTED_REACTOR": "twisted.internet.asyncioreactor.AsyncioSelectorReactor",
            "USER_AGENT": "",
            "DOWNLOAD_HANDLERS": {
                "http": "scrapy_impersonate.ImpersonateDownloadHandler",
                "https": "scrapy_impersonate.ImpersonateDownloadHandler",
            },
            "DOWNLOADER_MIDDLEWARES": {
                "scrapy_impersonate.RandomBrowserMiddleware": 1000,
            },
        }
    
        def start_requests(self):
            yield scrapy.Request(
                "https://tls.browserleaks.com/json",
                meta={"impersonate": "chrome124"}
            )
  6. Reference: Supported browser impersonation targets

    master

    The following browser identifiers can be used with the impersonate key. You can also use floating values like "chrome", "safari", "safari_ios", or "firefox" to let curl_cffi pick the most recent fingerprint.

    Chrome:
    - chrome99 (Windows 10)
    - chrome99_android (Android 12)
    - chrome100 (Windows 10)
    - chrome101 (Windows 10)
    - chrome104 (Windows 10)
    - chrome107 (Windows 10)
    - chrome110 (Windows 10)
    - chrome116 (Windows 10)
    - chrome119 (macOS Sonoma)
    - chrome120 (macOS Sonoma)
    - chrome123 (macOS Sonoma)
    - chrome124 (macOS Sonoma)
    - chrome131 (macOS Sonoma)
    - chrome131_android (Android 14)
    - chrome133a (macOS Sequoia)
    - chrome136 (macOS Sequoia)
    - chrome142 (macOS Tahoe)
    - chrome145 (macOS Tahoe, HTTP/3)
    - chrome146 (macOS Tahoe, HTTP/3)
    
    Edge:
    - edge99 (Windows 10)
    - edge101 (Windows 10)
    
    Safari:
    - safari153 (macOS Big Sur)
    - safari155 (macOS Monterey)
    - safari170 (macOS Sonoma)
    - safari172_ios (iOS 17.2)
    - safari180 (macOS Sequoia)
    - safari180_ios (iOS 18.0)
    - safari184 (macOS Sequoia)
    - safari184_ios (iOS 18.4)
    - safari260 (macOS Tahoe)
    - safari260_ios (iOS 26.0)
    - safari2601 (macOS Tahoe)
    
    Firefox:
    - firefox133 (macOS Sonoma)
    - firefox135 (macOS Sonoma)
    - firefox144 (macOS Tahoe)
    - firefox147 (macOS Tahoe, HTTP/3)
    
    Tor:
    - tor145 (macOS Sonoma)