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

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

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


Scrape Ninja

ScrapeNinja is a web scraping API with two engines: fast, with high performance and TLS fingerprint; and slower with a real browser under the hood.

ScrapeNinja handles headless browsers, proxies, timeouts, retries, and helps with data extraction, so you can just get the data in JSON. Rotating proxies are available out of the box on all subscription plans.


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 impersonatation 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]

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.

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.

Sponsor

Buy Me A Coffee

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.9.0.tar.gz (144.1 kB view details)

Uploaded Source

Built Distributions

curl_cffi-0.9.0-cp38-abi3-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.8+ Windows x86-64

curl_cffi-0.9.0-cp38-abi3-win32.whl (1.1 MB view details)

Uploaded CPython 3.8+ Windows x86

curl_cffi-0.9.0-cp38-abi3-musllinux_1_1_x86_64.whl (7.8 MB view details)

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

curl_cffi-0.9.0-cp38-abi3-musllinux_1_1_aarch64.whl (7.8 MB view details)

Uploaded CPython 3.8+ musllinux: musl 1.1+ ARM64

curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.4 MB view details)

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

curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl (6.8 MB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ i686

curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ ARM64

curl_cffi-0.9.0-cp38-abi3-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.8+ macOS 11.0+ ARM64

curl_cffi-0.9.0-cp38-abi3-macosx_10_9_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.8+ macOS 10.9+ x86-64

File details

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

File metadata

  • Download URL: curl_cffi-0.9.0.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.9.0.tar.gz
Algorithm Hash digest
SHA256 4818e074b61cb209bd8d4d0d03783313d4773e6b51f8b815e25aad9cc146a7b7
MD5 020a41efdda00f2788d9ec23774cd48f
BLAKE2b-256 9f7dc326faf5a772a11011dcc30aca5b64c197bcf59fdd9b90bf28b700d6d682

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: curl_cffi-0.9.0-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.9

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 81ba09622e68f8392236212dd0afd75dcd18cbe1be16467deb4d441d62cfc8a3
MD5 0951a44b805746685f54d91d252b9beb
BLAKE2b-256 e5497207356b343d9aa3590461035eabcef838af4c8d042ddac687fce878a999

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-win32.whl.

File metadata

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

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-win32.whl
Algorithm Hash digest
SHA256 202145686c5ebc00635b9b15cc8afa82523f14197a640b618bb09d59e74889ba
MD5 a762e2607bf8845f7d8c8ec84a332707
BLAKE2b-256 f30f3eab3d6170813947c7ba2971ec516322be2678a088f190ead0bf45d7e596

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ea8f0511bc6882d30a985ddc53fa26d109f2977715d4851aef162bfa308cd2a8
MD5 618dd3b3ecac87dd442ff48d3dbd730c
BLAKE2b-256 1176f2c551acfb6538c3932734b83ae7b87baf7b795852b6600a7519ff68bb05

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 752a4686c062a8bd6e25961845ea812704ba089a0e6863957deb2a30590105bb
MD5 02b2d998b0ad3d007c11039b0483c6cb
BLAKE2b-256 e33b0b11dfcdd4dcbefa025e8049f9479ace3321435afb6f78e3394cea395591

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7f41bd0a5dafe3fe19319da1c31302a40634ec4779769ca3d954d8673eb2b4f2
MD5 52f1227ed75d7d08043c2f109a23d6f1
BLAKE2b-256 c12f75c971a345737c330d98fe75f7ef538209d77aa3f1197752766566815bac

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 7b1177203e47d3248ccb250e63983eaddf39fce5332f91cc2993ea54cae5aa21
MD5 824da0e02a00af0e10bedae8f11da7bf
BLAKE2b-256 2827d0cbb7a7cc9c444688c06cb41271d7ee7d429966d77dbaedbf19dd52d30e

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 26d61c5b5c59e9c4a006cba35feccd73c75ce981db0da89a3da88dd280ead7a0
MD5 3531ad34cfa05a0876d6bc3f469db6a1
BLAKE2b-256 3d7afeda016a35e904f0e4f753d41677f343e63271373b9c3648183e8f29ca76

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7968c3ea37bec96bbe4b623c0fa59c09d3cdaf173da2e0a516b19db52f05caa4
MD5 95e6f59db54cf911d54689bdb8d3c671
BLAKE2b-256 2a88c3dfdf28448fad4be68a37cf758941583e4c1ff300b4e384197bedfda493

See more details on using hashes here.

File details

Details for the file curl_cffi-0.9.0-cp38-abi3-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for curl_cffi-0.9.0-cp38-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 429a14e724898b7001be2776caa87c294e8062f0ac652619df5854eeae6e156c
MD5 008d435707a815068524898ad815d3b8
BLAKE2b-256 2a96befafab403a12a25e9fca376da20512b5962a2bf5810921c2fd27c01e96f

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