Skip to main content

libcurl ffi bindings for Python, with impersonation support.

Project description

curl_cffi

PyPI - Downloads PyPI - Python Version PyPI version Generic badge Generic badge

Documentation

Python binding for curl-impersonate fork via cffi.

Unlike other pure python http clients like httpx or requests, curl_cffi can impersonate browsers' TLS/JA3 and HTTP/2 fingerprints. If you are blocked by some website for no obvious reason, you can give curl_cffi a try.

Python 3.9 is the minimum supported version since v0.10.

Sponsors

Maintenance of this project is made possible by all the contributors and sponsors. If you'd like to sponsor this project and have your avatar or company logo appear below click here. 💖


ProxyCurl

Scrape public LinkedIn profile data at scale with Proxycurl APIs. Built for developers, by developers.

  • GDPR, CCPA, SOC2 compliant
  • High rate limit (300 requests/min), Fast (APIs respond in ~2s), High accuracy
  • Fresh data - 88% of data is scraped real-time, other 12% is <29 days
  • Tons of data points returned per profile

SerpAPI

Scrape Google and other search engines from SerpApi's fast, easy, and complete API. 0.66s average response time (≤ 0.5s for Ludicrous Speed Max accounts), 99.95% SLAs, pay for successful responses only.


Bypass Cloudflare with API

Yes Captcha!

Yescaptcha is a proxy service that bypasses Cloudflare and uses the API interface to obtain verified cookies (e.g. cf_clearance). Click here to register: https://yescaptcha.com/i/stfnIO


Features

  • Supports JA3/TLS and http2 fingerprints impersonation, including recent browsers and custome fingerprints.
  • Much faster than requests/httpx, on par with aiohttp/pycurl, see benchmarks.
  • Mimics requests API, no need to learn another one.
  • Pre-compiled, so you don't have to compile on your machine.
  • Supports asyncio with proxy rotation on each request.
  • Supports http 2.0, which requests does not.
  • Supports websocket.
requests aiohttp httpx pycurl curl_cffi
http2
sync
async
websocket
fingerprints
speed 🐇 🐇🐇 🐇 🐇🐇 🐇🐇

Install

pip install curl_cffi --upgrade

This should work on Linux, macOS and Windows out of the box. If it does not work on you platform, you may need to compile and install curl-impersonate first and set some environment variables like LD_LIBRARY_PATH.

To install beta releases:

pip install curl_cffi --upgrade --pre

To install unstable version from GitHub:

git clone https://github.com/lexiforest/curl_cffi/
cd curl_cffi
make preprocess
pip install .

Usage

curl_cffi comes with a low-level curl API and a high-level requests-like API.

requests-like

v0.9:

from curl_cffi import requests

r = requests.get("https://tools.scrapfly.io/api/fp/ja3", impersonate="chrome")

v0.10:

import curl_cffi

# Notice the impersonate parameter
r = curl_cffi.get("https://tools.scrapfly.io/api/fp/ja3", impersonate="chrome")

print(r.json())
# output: {..., "ja3n_hash": "aa56c057ad164ec4fdcb7a5a283be9fc", ...}
# the js3n fingerprint should be the same as target browser

# To keep using the latest browser version as `curl_cffi` updates,
# simply set impersonate="chrome" without specifying a version.
# Other similar values are: "safari" and "safari_ios"
r = curl_cffi.get("https://tools.scrapfly.io/api/fp/ja3", impersonate="chrome")

# To pin a specific version, use version numbers together.
r = curl_cffi.get("https://tools.scrapfly.io/api/fp/ja3", impersonate="chrome124")

# To impersonate other than browsers, bring your own ja3/akamai strings
# See examples directory for details.
r = curl_cffi.get("https://tls.browserleaks.com/json", ja3=..., akamai=...)

# http/socks proxies are supported
proxies = {"https": "http://localhost:3128"}
r = curl_cffi.get("https://tools.scrapfly.io/api/fp/ja3", impersonate="chrome", proxies=proxies)

proxies = {"https": "socks://localhost:3128"}
r = curl_cffi.get("https://tools.scrapfly.io/api/fp/ja3", impersonate="chrome", proxies=proxies)

Sessions

v0.9:

from curl_cffi import requests

s = requests.Session()

v0.10:

s = curl_cffi.Session()

# httpbin is a http test website, this endpoint makes the server set cookies
s.get("https://httpbin.org/cookies/set/foo/bar")
print(s.cookies)
# <Cookies[<Cookie foo=bar for httpbin.org />]>

# retrieve cookies again to verify
r = s.get("https://httpbin.org/cookies")
print(r.json())
# {'cookies': {'foo': 'bar'}}

curl_cffi supports the same browser versions as supported by my fork of curl-impersonate:

Browser versions will be added only when their fingerprints change. If you see a version, e.g. chrome122, were skipped, you can simply impersonate it with your own headers and the previous version.

If you are trying to impersonate a target other than a browser, use ja3=... and akamai=... to specify your own customized fingerprints. See the docs on impersonation for details.

  • chrome99
  • chrome100
  • chrome101
  • chrome104
  • chrome107
  • chrome110
  • chrome116 [1]
  • chrome119 [1]
  • chrome120 [1]
  • chrome123 [3]
  • chrome124 [3]
  • chrome131 [4]
  • chrome133a [5][6]
  • chrome99_android
  • chrome131_android [4]
  • edge99
  • edge101
  • safari15_3 [2]
  • safari15_5 [2]
  • safari17_0 [1]
  • safari17_2_ios [1]
  • safari18_0 [4]
  • safari18_0_ios [4]
  • firefox133 [5]
  • firefox135 [7]

Notes:

  1. Added in version 0.6.0.
  2. Fixed in version 0.6.0, previous http2 fingerprints were not correct.
  3. Added in version 0.7.0.
  4. Added in version 0.8.0.
  5. Added in version 0.9.0.
  6. The version postfix -a(e.g. chrome133a) means that this is an alternative version, i.e. the fingerprint has not been officially updated by browser, but has been observed because of A/B testing.
  7. Added in version 0.10.0.

Asyncio

from curl_cffi import AsyncSession

async with AsyncSession() as s:
    r = await s.get("https://example.com")

More concurrency:

import asyncio
from curl_cffi import AsyncSession

urls = [
    "https://google.com/",
    "https://facebook.com/",
    "https://twitter.com/",
]

async with AsyncSession() as s:
    tasks = []
    for url in urls:
        task = s.get(url)
        tasks.append(task)
    results = await asyncio.gather(*tasks)

WebSockets

from curl_cffi import WebSocket

def on_message(ws: WebSocket, message: str | bytes):
    print(message)

ws = WebSocket(on_message=on_message)
ws.run_forever("wss://api.gemini.com/v1/marketdata/BTCUSD")

For low-level APIs, Scrapy integration and other advanced topics, see the docs for more details.

Asyncio WebSockets

import asyncio
from curl_cffi import AsyncSession

async with AsyncSession() as s:
    ws = await s.ws_connect("wss://echo.websocket.org")
    await asyncio.gather(*[ws.send_str("Hello, World!") for _ in range(10)])
    async for message in ws:
        print(message)

Acknowledgement

  • Originally forked from multippt/python_curl_cffi, which is under the MIT license.
  • Headers/Cookies files are copied from httpx, which is under the BSD license.
  • Asyncio support is inspired by Tornado's curl http client.
  • The synchronous WebSocket API is inspired by websocket_client.
  • The asynchronous WebSocket API is inspired by aiohttp.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

curl_cffi-0.10.0.tar.gz (144.4 kB view details)

Uploaded Source

Built Distributions

curl_cffi-0.10.0-cp39-abi3-win_amd64.whl (1.4 MB view details)

Uploaded CPython 3.9+ Windows x86-64

curl_cffi-0.10.0-cp39-abi3-win32.whl (1.1 MB view details)

Uploaded CPython 3.9+ Windows x86

curl_cffi-0.10.0-cp39-abi3-musllinux_1_1_x86_64.whl (7.8 MB view details)

Uploaded CPython 3.9+ musllinux: musl 1.1+ x86-64

curl_cffi-0.10.0-cp39-abi3-musllinux_1_1_aarch64.whl (7.9 MB view details)

Uploaded CPython 3.9+ musllinux: musl 1.1+ ARM64

curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.4 MB view details)

Uploaded CPython 3.9+ manylinux: glibc 2.17+ x86-64

curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl (6.6 MB view details)

Uploaded CPython 3.9+ manylinux: glibc 2.17+ i686

curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.9+ manylinux: glibc 2.17+ ARM64

curl_cffi-0.10.0-cp39-abi3-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.9+ macOS 11.0+ ARM64

curl_cffi-0.10.0-cp39-abi3-macosx_10_9_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.9+ macOS 10.9+ x86-64

File details

Details for the file curl_cffi-0.10.0.tar.gz.

File metadata

  • Download URL: curl_cffi-0.10.0.tar.gz
  • Upload date:
  • Size: 144.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.9

File hashes

Hashes for curl_cffi-0.10.0.tar.gz
Algorithm Hash digest
SHA256 3e37b35268ca58492f54ed020ae4b50c33ee0debad4145db9f746f04ed466eb0
MD5 d7c376a69c42ba6f8665b56fae7f89c8
BLAKE2b-256 7dc018e408334c480f2cacca02feec8cd01dba9e3f1637cd03fd21b033c2bfa3

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 59389773a1556e087120e91eac1e33f84f1599d853e1bc168b153e4cdf360002
MD5 cebda33db1530d38a2fe3af55c1b9c71
BLAKE2b-256 2680dbc3a5119afe233ddc9dfc14d5b175636443e5d6349f4cdce3eaa9e1523a

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-win32.whl.

File metadata

  • Download URL: curl_cffi-0.10.0-cp39-abi3-win32.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.9+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.9

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-win32.whl
Algorithm Hash digest
SHA256 1e60b8ecc80bfb0da4ff73ac9d194e80482b50ecbb8aefec1b0edaf45fafd80e
MD5 75fd6c7ffa1ec81008519f064a794106
BLAKE2b-256 200f78b0221782c43cba88cb09b74484bc0fc7db09c85ddefaf9817381a9414f

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 04b1d23f0f54f94b8298ed417e6bece85a635d674723cde2b155da686efbf78f
MD5 50635d24b0fa8cb2e2523978b0701d7e
BLAKE2b-256 ee68a83946686cd96f87f1611b26dbee10dc41c7dbfc2558c8f4c762caf975c5

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 f1b0c7b7b81afca15a0e56c593d3c2bdcd4fd4c9ca49b9ded5b9d8076ba78ff9
MD5 8bf310f7311d9e8e25e8cfc26612a6dd
BLAKE2b-256 07540406653d8dbcfa766fe33c43aa19438003bdee03119cb9c1b070b03a10ee

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f03f4b17dc679c82bd3c946feb1ad38749b2ad731d7c26daefaac857d1c72fd9
MD5 2763f41a2c10027caeddcd9b554abf3f
BLAKE2b-256 0950028ab0c0ef9717af285801e7ba5b1d83e42073e06d2c62c7a9e8a0b9a0fa

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 cfc74f09e44d2d8d61b8e8fda3a7004b5bc0217a703fbbe9e16ef8caa1f3d4e4
MD5 f73ffdac6ae4900eeb2099ea40f4c5b6
BLAKE2b-256 241fa51248f89b958216cf29342b8a43befefc62301781576693b25caea5c24f

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 458f53c41bd76d90d8974d60c3a8a0dd902a1af1f9056215cf24f454bcedc6fd
MD5 b82b09c4b81e6391cb6921250c122514
BLAKE2b-256 f758fff44c797abf4a101723f167259801cde5d7bcfc7621bb37baeeb3e03fdc

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3969e4260ad4dab638fb6dbe349623f9f5f022435c7fd21daf760231380367fa
MD5 b35f58d242db54d69f9ae328f1c4241b
BLAKE2b-256 7ccc5dc45cf5f52c82979daef5b414108a39f9eeaa164a6810da1368d307b468

See more details on using hashes here.

File details

Details for the file curl_cffi-0.10.0-cp39-abi3-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.10.0-cp39-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 15053d01c6a3e3c4c5331ce9e07e1dc31ca5aa063babca05d18b1b5aad369fac
MD5 c78f4182f0b7735d6a106f921e09e3df
BLAKE2b-256 566cf3a27db82305540ecab0db688a5977162ed7d64e274c09ea7c9ed3f4a541

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page