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.

Minimum supported python versions:

  • Since 0.10, Python 3.9
  • 0.9 and below, Python 3.8

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

from curl_cffi import requests

# Notice the impersonate parameter
r = requests.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 = requests.get("https://tools.scrapfly.io/api/fp/ja3", impersonate="chrome")

# To pin a specific version, use version numbers together.
r = requests.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 = requests.get("https://tls.browserleaks.com/json", ja3=..., akamai=...)

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

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

Sessions

s = requests.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.requests import AsyncSession

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

More concurrency:

import asyncio
from curl_cffi.requests 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.requests 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.requests 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.0b2.tar.gz (144.1 kB view details)

Uploaded Source

Built Distributions

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

Uploaded CPython 3.9+ Windows x86-64

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

Uploaded CPython 3.9+ Windows x86

curl_cffi-0.10.0b2-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.0b2-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.0b2-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.0b2-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.0b2-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.0b2-cp39-abi3-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.9+ macOS 11.0+ ARM64

curl_cffi-0.10.0b2-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.0b2.tar.gz.

File metadata

  • Download URL: curl_cffi-0.10.0b2.tar.gz
  • Upload date:
  • Size: 144.1 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.0b2.tar.gz
Algorithm Hash digest
SHA256 55cf4ecd6f40c76054702a08868af5045b801484adac7d62a8c40cc01ec2d642
MD5 8b3eaf427901e4c0ddcf5eed4c07aae6
BLAKE2b-256 cbac64edf103e0fa648ece3dea72f83462f280a31a143e7c0d374784683bc25d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for curl_cffi-0.10.0b2-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5d7ff9ed94cd6424324317ea7ab66a8653c7040727a83c9c97cd51920fb6592d
MD5 24fdf215f0e4a38ae0018b2b96b54927
BLAKE2b-256 1b2f8e7933cac62a88752d8d8156bd0c5ab4e269b1f721a1541afcd4f14c4e3c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: curl_cffi-0.10.0b2-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.0b2-cp39-abi3-win32.whl
Algorithm Hash digest
SHA256 4c9fbc56b795cdb5e9e6d10752bc267d1db5d7831b1d18c5362af571e24ea46b
MD5 901f3f41b146e8e184984ab1814f5746
BLAKE2b-256 5d87dfb61624ff6d68d992c78efb0e99064453e279618a30710a2754bf9cf263

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for curl_cffi-0.10.0b2-cp39-abi3-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 55d771d54df170746461eee4cff8ac03a2821e8dfa453778a37a906dab60f175
MD5 b3a3c93c59e5067218655850c352618d
BLAKE2b-256 6bde147b96a00d70fb1b991b94eb16549776d63853e781c22986bd3ef4b0c9cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for curl_cffi-0.10.0b2-cp39-abi3-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 001f3d93f41ede99669643c346fd8a1690557196559e00fa7eddc5accdb81e5b
MD5 0a5fd46725d75f3dab4fd8afd7ad0bdb
BLAKE2b-256 8cc7625d25764b67290fdcc44d50319c7669c7dcab6650dcb05bda3939630f2c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for curl_cffi-0.10.0b2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c362b8619ef9e5296e2148b42345a679c3bd3a17e39e16b9b99df01305e13b55
MD5 f4a9b306de96760706d046ca25393c9e
BLAKE2b-256 18334e3ccebb99dee9376d6bf34794af02980947f8f9c30207e420d4e6608aa2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for curl_cffi-0.10.0b2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 8906618031c53a6af95eefff501e0043e8d848a7dd6702210cf040b28efbbce3
MD5 09561e60d96750f0a7b5917071ef7f69
BLAKE2b-256 08c64e9ce9c55274cf7598e85f63cc5dd2ce43433f72549c75c90bcf4b387b30

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for curl_cffi-0.10.0b2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4cf40e32f80f77f44e871464ceb8257c3038895436b2a45e7e395e5355d5f4f9
MD5 bc1f649d38746620e447851a73fef74e
BLAKE2b-256 da861472ef895a5d832d0e9bfa3b2c2844c7ca4b5c10cc17e4b68420fb246749

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for curl_cffi-0.10.0b2-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5cdafc6affca68cb6439964a6fe6d4f9e905c5e0e36af86daadc67dd137fc46e
MD5 afd69977b2d24a2bcf0d0abba184218e
BLAKE2b-256 bb91a3d0dbfe029f49b1f3fedf13e45609581ff87d4ec2962f5fbbcc87fb4244

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for curl_cffi-0.10.0b2-cp39-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 13970bc6e0c8f1d53c04b5384722ac3f6de0cc4fc1ea53062a78e58f271e96ed
MD5 c9c0ff4d26b65fd48581fb93d2215d17
BLAKE2b-256 2d0ce6913c15e711bd2d504f7bc23f727ded6e9a3025022ffb642ade9128ac85

See more details on using hashes here.

Supported by

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