curl-cffivshttp-2
Curl-cffi is a Python library for implementing curl-impersonate which is a
HTTP client that appears as one of popular web browsers like:
- Google Chrome
- Microsoft Edge
- Safari
- Firefox
Unlike requests
and httpx
which are native Python libraries, curl-cffi
uses cURL and inherits it's powerful features
like extensive HTTP protocol support and detection patches for TLS and HTTP fingerprinting.
Using curl-cffi web scrapers can bypass TLS and HTTP fingerprinting.
Pure Ruby, framework and transport agnostic, implementation of HTTP/2 protocol and HPACK header compression with support for:
- Binary framing parsing and encoding
- Stream multiplexing and prioritization
- Connection and stream flow control
- Header compression and server push
- Connection and stream management
- And more... see API docs
Protocol specifications:
- Hypertext Transfer Protocol Version 2 (RFC 7540)
- HPACK: Header Compression for HTTP/2 (RFC 7541)
Highlights
bypasshttp2tls-fingerprinthttp-fingerprintsyncasync
http2
Example Use
curl-cffi can be accessed as low-level curl client as well as an easy high-level HTTP client:
from curl_cffi import requests
response = requests.get('https://httpbin.org/json')
print(response.json())
# or using sessions
session = requests.Session()
response = session.get('https://httpbin.org/json')
# also supports async requests using asyncio
import asyncio
from curl_cffi.requests import AsyncSession
urls = [
"http://httpbin.org/html",
"http://httpbin.org/html",
"http://httpbin.org/html",
]
async with AsyncSession() as s:
tasks = []
for url in urls:
task = s.get(url)
tasks.append(task)
# scrape concurrently:
responses = await asyncio.gather(*tasks)
# also supports websocket connections
from curl_cffi.requests import Session, WebSocket
def on_message(ws: WebSocket, message):
print(message)
with Session() as s:
ws = s.ws_connect(
"wss://api.gemini.com/v1/marketdata/BTCUSD",
on_message=on_message,
)
ws.run_forever()
require 'http/2'
# GET request
client = HTTP2::Client.new
response = client.get("https://httpbin.org/get")
puts response.body
# POST reuqest
data = { name: "value" }
response = client.post("https://www.example.com", data)