用 curl_cffi 與 tls-client 繞過 TLS 指紋辨識(2026)

發佈於 2026年6月2日 · 約 9 分鐘閱讀

你買了乾淨的住宅 IP,輪換得完美無缺,第一個請求卻還是吃到 403。問題不在 IP — 出賣你的是你的 TLS 交握。TLS 指紋辨識讓伺服器在讀取你 HTTP 請求的任何一個位元組之前,就能識別出用戶端函式庫。本文解釋 JA3/JA4,說明為何 Python 的 requests 輕易就被偵測出來,並提供以 curl_cffitls-client 模擬真實瀏覽器的可用程式碼。

什麼是 TLS 指紋辨識(JA3 / JA4)?

任何用戶端開啟 HTTPS 連線時,都會送出一個 ClientHello,宣告它的 TLS 版本、加密套件、擴充功能、橢圓曲線,以及這些項目的排列順序。那個排序對建立它的函式庫來說相當獨特。把它雜湊起來,你就得到一個 JA3 指紋(或更新、更穩健的 JA4)。

Chrome 產生一種指紋。Firefox 產生另一種。Python 的 requests(建立在 urllib3 與 OpenSSL 之上)產生的指紋大喊著「自動化」— 而且在數百萬個機器人之間完全一模一樣。反機器人系統會保留這些指紋的封鎖清單。無論你的 IP 多麼住宅級,一個已知的機器人 JA3 都會被標記。

先看看你自己的指紋

修正任何東西之前,先量測它。從你的爬蟲送一個請求到 JIBAO 免費的 JA3/JA4 指紋檢測工具,並與真實 Chrome 顯示的結果比較。如果 JA3 雜湊不同,目標站台就能把你和真人區分開來 — Cloudflare 也一樣。

為何 requests 與 httpx 無法解決這件事

requestshttpx 把 TLS 交給系統的 OpenSSL。你可以整天更改標頭甚至 User-Agent,但底下的交握仍然是 OpenSSL 的,不是 Chrome 的。只偽造標頭而不偽造交握,正是「我複製了瀏覽器的標頭,它還是封鎖我」最常見的原因。你需要一個會模仿瀏覽器實際 TLS 堆疊的用戶端。

用 curl_cffi 修正它

curl_cffi 綁定到 curl-impersonate,那是一個能重現真實瀏覽器 TLS 與 HTTP/2 指紋的 curl 編譯版本。一個參數,你的交握就看起來像 Chrome:

# pip install curl_cffi
from curl_cffi import requests

# impersonate a real Chrome TLS + HTTP/2 fingerprint
r = requests.get(
    "https://tls.browserleaks.com/json",
    impersonate="chrome131",
)
print(r.json()["ja3_hash"])   # now matches real Chrome

它的 API 與 requests 一致,所以遷移現有的爬蟲大多只是改一行 import。支援的目標包含近期的 Chrome、Edge、Safari 與 Firefox 編譯版本 — 挑一個並持續更新,因為瀏覽器更新時指紋會輪替。

搭配住宅代理一起用

指紋比對與 IP 輪換是互補的,不是二選一。兩者都用:一個瀏覽器等級的交握,透過一個乾淨的住宅 IP,才是真正能通過的組合:

from curl_cffi import requests

PROXY = "socks5h://USERNAME:[email protected]:10001"

r = requests.get(
    "https://example.com/protected",
    impersonate="chrome131",
    proxies={"http": PROXY, "https": PROXY},
    timeout=30,
)
print(r.status_code)

替代方案:tls-client

tls-client(一個包裝 Go uTLS 實作的 Python 封裝)是另一個紮實的選擇,附帶大量具名設定檔的函式庫:

# pip install tls-client
import tls_client

session = tls_client.Session(
    client_identifier="chrome_120",
    random_tls_extension_order=True,
)

session.proxies = {
    "http": "socks5h://USERNAME:[email protected]:10001",
    "https": "socks5h://USERNAME:[email protected]:10001",
}

r = session.get("https://example.com/protected")
print(r.status_code)

random_tls_extension_order=True 會打亂擴充功能的順序,以避免產生靜態、可重複利用的指紋 — 對那些長期追蹤 JA3 完全比對的系統很有幫助。

什麼時候你仍然需要真實瀏覽器

有些目標會檢查 JavaScript 執行訊號(canvas、WebGL、事件時序),那是任何 HTTP 用戶端都無法重現的。在那種情況下,改用驅動真實瀏覽器的方式 — 參見 搭配 Playwright 與 Puppeteer 使用代理並加上隱身。代價是成本與速度:像 curl_cffi 這類 HTTP 用戶端每個請求便宜得多,所以在它們夠用的地方就用它們,把完整瀏覽器留給最難的目標。

檢查清單

在多數「IP 乾淨卻仍被封鎖」的故事裡,TLS 指紋辨識是缺漏的那一層。修正交握、保留住宅 IP,成功率就會躍升。要對付最難纏的 WAF 並掌握完整堆疊,請閱讀 2026 Cloudflare 繞過配方

用乾淨 IP 擊敗指紋辨識

領取 500M免費流量與住宅 IP,搭配瀏覽器等級的 TLS 指紋使用。

開始免費試用

適用於所有 IP 產品 · 龐大的節點池隨時可用

立即註冊,儲值最高可享 100% 返現

新用戶註冊即送 500M免費流量,首次儲值另有贈金。優惠限時供應。