Playwright & Puppeteer
Về bản chất Clearcote chỉ là Chromium, nên nó dùng được như một trình duyệt thay thế trực tiếp (drop-in) cho các công cụ tự động hóa bạn đang dùng.
Dùng SDK (khuyến nghị)
Gói clearcote (npm, PyPI và NuGet) biến các tùy chọn danh tính thành tham số có tên và trả về các đối tượng Playwright bình thường. Ở lần dùng đầu tiên, nó tải trình duyệt về và xác minh SHA-256 — bản build mở nếu không có khóa giấy phép, bản build có giấy phép mới nhất nếu có (xem Cài đặt) — rồi áp dụng các giá trị mặc định được mô tả ở phần dưới.
# pip install clearcote
from clearcote import launch
browser = launch(fingerprint="seed-123", platform="windows", brand="Chrome")
page = browser.new_page()
page.goto("https://example.com")
browser.close()SDK hiện tại: 0.31.1. Từ 0.23, launch() trong Python và Node chạy trên một thư mục profile thật, dùng một lần (bị xóa khi đóng) thay vì chế độ incognito, nhờ vậy những gì phụ thuộc vào profile khớp với một Chrome thật và widevine: true có thể nạp module DRM. Hàm trả về một handle hoạt động như browser: newPage() vẫn dùng như thường, nhưng newContext() trả về chính context của profile đó chứ không tạo context tách biệt. Nếu cần các cookie jar riêng, hãy khởi chạy các browser riêng; truyền ephemeralProfile: false / ephemeral_profile=False để dùng Browser incognito như trước, hoặc userDataDir / user_data_dir để giữ lại profile.
API async (clearcote.async_api) nhận cùng các tùy chọn persona và proxy bên trong một vòng lặp asyncio và trả về các đối tượng async của Playwright; launch() của nó chạy incognito, nên hãy dùng launch_persistent_context() khi cần profile (và khi cần widevine=True). SDK .NET hỗ trợ LaunchEphemeralProfileAsync (khuyến nghị — LaunchAsync của .NET chạy incognito và không căn được cửa sổ khi chạy headless), LaunchPersistentContextAsync, ServeAsync, tải xuống có xác minh, cấp phép, Geoip và thao tác nhập liệu giống người (gọi tường minh HumanClickAsync / HumanTypeAsync / HumanSelectOptionAsync thay vì bật bằng flag khi khởi chạy). Profile đã lưu, profile: "auto", kiểm tra render-coherence, Widevine và các helper cho agent hiện chỉ có trên Python & Node. Các quy trình đầy đủ để copy-paste có ở Ví dụ.
Puppeteer và các client CDP khác (serve)
SDK không có launcher cho Puppeteer. Thay vào đó, serve() khởi động Clearcote với các thiết lập khởi chạy của SDK (persona, proxy, giá trị mặc định) cùng một endpoint CDP trên loopback, và bất kỳ client CDP nào cũng kết nối vào được — Puppeteer, connectOverCDP của Playwright, browser-use, Crawl4AI, Stagehand. Cách này dùng được với bản build có giấy phép, và không có gì thêm --enable-automation vào. humanize nằm ở phía Playwright, nên không áp dụng cho client kết nối theo cách này.
import { serve } from "clearcote";
import puppeteer from "puppeteer-core";
const srv = await serve({ fingerprint: "seed-123", platform: "windows" });
const browser = await puppeteer.connect({ browserURL: srv.cdpUrl, defaultViewport: null });
const page = await browser.newPage();
await page.goto("https://example.com");
await browser.disconnect();
await srv.close();Khi chạy headless, serve() cấp cho trình duyệt một màn hình có kích thước thật và căn cửa sổ vừa với vùng làm việc trước khi bất kỳ client nào kết nối (0.31+); truyền windowSize / window_size nếu muốn cửa sổ nhỏ hơn. Từ shell, clearcote serve làm điều tương tự dưới dạng một dịch vụ chạy thường trực — và có thể cấp cho mỗi kết nối một trình duyệt riêng, với danh tính, proxy, múi giờ và ngôn ngữ lấy từ URL kết nối. Xem Triển khai.
Điều khiển binary trực tiếp (bản build mở)
Bạn cũng có thể trỏ launcher của mình vào bản build mở bằng executablePath (Node) hoặc executable_path (Python) và truyền các tùy chọn danh tính qua args. Bản build có giấy phép không khởi động theo cách này — nó cần token giấy phép mà SDK lấy về, vì vậy hãy dùng launch() hoặc serve() ở trên. Hãy bỏ --enable-automation như SDK vẫn làm (Puppeteer và các phiên bản Playwright cũ thêm flag này; nó chuyển Chromium sang chế độ automation). Theo cách này, không giá trị mặc định nào của SDK (ngôn ngữ, chính sách WebRTC, kích thước và vị trí cửa sổ) được áp dụng.
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
executable_path=r"C:\clearcote\chrome.exe",
headless=False,
ignore_default_args=["--enable-automation"],
args=[
"--fingerprint=seed-123",
"--fingerprint-platform=windows",
"--timezone=America/New_York",
],
)
page = browser.new_page()
page.goto("https://abrahamjuliot.github.io/creepjs/")
browser.close()Xác định hoặc tải trước binary đã xác minh
SDK xác định trình duyệt theo thứ tự sau: executablePath / executable_path được chỉ định tường minh, sau đó là CLEARCOTE_BINARY, rồi đến version bạn yêu cầu (hoặc CLEARCOTE_BROWSER_VERSION), tiếp theo là bản build có giấy phép nếu tìm thấy khóa giấy phép (tùy chọn licenseKey, CLEARCOTE_LICENSE_KEY, hoặc ~/.clearcote/license.key), và cuối cùng là bản build mở được cố định trong phiên bản SDK này. Đường dẫn do bạn cung cấp sẽ được kiểm tra xem có tệp nào bị thiếu hoặc bị cắt cụt không trước khi khởi chạy. Hãy gọi download / executable_path khi bạn muốn làm nóng cache mà không khởi chạy, dùng thư mục cache tùy chỉnh, hoặc chủ động chọn bản build mở mới nhất trên GitHub lúc runtime.
from clearcote import download, launch
chrome = download(cache_dir=r"C:\clearcote-cache", auto_update=True)
browser = launch(executable_path=chrome, fingerprint="seed-123")Chế độ cố định (pinned) xác minh theo các giá trị SHA-256 được nhúng sẵn trong SDK. autoUpdate / auto_update phải bật chủ động (opt-in) và sẽ xác minh manifest checksum của bản phát hành; khi có gpg, nó còn đối chiếu manifest đã ký với fingerprint của khóa ký Clearcote đã được cố định. Tùy chọn này chỉ áp dụng cho bản build mở: khi có khóa giấy phép, download() sẽ tải bản build có giấy phép hiện hành (chọn bản cụ thể bằng version hoặc releaseChannel — xem chọn bản build). Trong .NET, DownloadAsync chỉ tải bản build mở; để tải trước bản build có giấy phép, hãy dùng ExecutablePathAsync(new LaunchOptions { LicenseKey = … }).
Import profile từ Chrome thật
Thay vì persona tổng hợp suy ra từ seed, bạn có thể để Clearcote báo cáo các giá trị thu được từ một máy thật. Thu thập một profile từ một Chrome nguồn bằng công cụ thu thập tại tools/fingerprint-collect (mở collect.html, bấm Capture, và công cụ sẽ tải về một profile JSON), hoặc khởi đầu từ chrome-fingerprints — bộ dữ liệu mã nguồn mở gồm 10k bản ghi — bằng công cụ chuyển đổi đi kèm convert_dataset.py. Dữ liệu thu thập bao gồm navigator, kích thước màn hình, vendor/renderer WebGL + các giới hạn getParameter, Web Audio, giọng đọc speech-synthesis, font, codec và các đặc tính CSS @media.
Truyền profile cho SDK dưới dạng đường dẫn tệp, object hoặc chuỗi JSON — SDK sẽ lo phần đóng gói gzip + base64 cho bạn. Các trường có trong profile sẽ ghi đè những gì trình duyệt lẽ ra báo cáo; các trường không có sẽ dùng giá trị mặc định của trình duyệt. SDK cũng suy ra Accept-Language từ navigator.languages của profile khi bạn không tự đặt giá trị này. Cả hai bản build đều đọc được profile import; trên bản build có giấy phép, profile được áp dụng đầy đủ từ 151 r19.
Đừng truyền seed fingerprint cùng với profile. Seed sẽ kích hoạt lớp farbling, thứ mà các cơ chế chấm điểm khắt khe coi là can thiệp canvas (canvas tampering), và nó không mang lại gì mà profile chưa cung cấp. Chỉ dùng một trong hai. Profile chỉ thay thế các giá trị được báo cáo — nó không bao giờ thay đổi thứ render ra pixel của bạn, nên hai tài khoản dùng hai profile khác nhau trên cùng một máy vẫn tạo ra canvas giống hệt nhau. Nếu cần tách biệt kết quả render theo từng tài khoản, hãy dùng seed riêng cho mỗi tài khoản và không dùng profile.
from clearcote import launch
browser = launch(fingerprint_profile="profile.json", disable_gpu_fingerprint=True, fingerprint_noise=False)
page = browser.new_page()
page.goto("https://example.com")
browser.close()Nhất quán theo mặc định (không cần flag bổ sung)
Dù bạn khởi chạy với tùy chọn nào, engine vẫn giữ các bề mặt thứ cấp khớp với persona bạn chọn — với persona Windows là khớp với những gì một máy desktop chạy Chrome trên Windows thật báo cáo. Nền tảng của persona mặc định theo hệ điều hành máy host, nên trên host Linux, các bề mặt này sẽ theo persona Linux trừ khi bạn truyền platform. Các giới hạn WebGL getParameter (WebGL1 + WebGL2) báo cáo giá trị của persona, nhưng bị giới hạn ở mức GPU của máy này thực sự đáp ứng được, còn UNMASKED_RENDERER / UNMASKED_VENDOR cố định trong suốt phiên (cùng một GPU trên mọi trang, theo persona). Với persona Windows, navigator.getBattery() báo cáo một máy desktop cắm điện lưới, navigator.connection báo cáo một kết nối mạng dân dụng, và AudioContext báo cáo sample rate và độ trễ Windows-WASAPI tương ứng. getScreenDetails() báo cáo một màn hình duy nhất, còn @media (pointer: fine) / (hover: hover) khớp với một máy desktop dùng chuột.
Đã kiểm tra trên 153 r26, chạy headed trên Windows (tháng 9/2026): BrowserScan báo không có bot và CreepJS hiển thị 0% stealth. Khi dùng proxy, hãy thêm geoip để múi giờ và WebRTC khớp với điểm thoát (exit).
Sự kiện console và page-error
Engine không chuyển tiếp các sự kiện console hay page-error tới client tự động hóa, nên page.on("console") và page.on("pageerror") sẽ không nhận được gì. Đây là thiết kế có chủ đích — việc chuyển tiếp chúng chính là thứ mà một probe phát hiện automation đo lường. Các handler window.onerror và unhandledrejection trong trang vẫn chạy bình thường, nên để lấy output của console, hãy thu thập nó ngay trong trang rồi đọc lại bằng page.evaluate(). SDK Python và Node sẽ in một thông báo về điều này một lần khi khởi chạy.
Tự khớp theo khu vực của proxy (geoip)
Truyền geoip cùng với proxy, SDK sẽ xác định IP thoát của proxy — tra trong cơ sở dữ liệu offline geoip-all-in-one — rồi đặt múi giờ + ngôn ngữ chính của navigator + Accept-Language + IP WebRTC nhất quán cho khu vực đó. Không còn phải tự chọn múi giờ khớp với từng proxy nữa:
from clearcote import launch
browser = launch(
fingerprint="user-7423",
proxy={"server": "http://host:8080", "username": "u", "password": "p"},
geoip=True, # timezone + language auto-matched to the proxy's region
)Nó cũng đặt vị trí địa lý (geolocation) và toàn bộ danh sách navigator.languages cho khu vực đó, hoạt động qua proxy HTTP và SOCKS5 (kể cả proxy có thông tin xác thực), và có trong cả ba SDK (Geoip = true trong .NET). Lần chạy đầu tiên sẽ tải cơ sở dữ liệu về (khoảng 50 MB). Nếu không xác định được khu vực, quá trình khởi chạy dừng lại với GeoipError thay vì lặng lẽ khởi động với đồng hồ và ngôn ngữ của máy này; hãy đặt cả timezone lẫn acceptLanguage nếu vẫn muốn khởi chạy. Việc tra cứu có tối đa 20 giây (CLEARCOTE_GEOIP_TIMEOUT_SECONDS); trong .NET, lỗi là GeoipException. Nếu không có geoip hoặc timezone được đặt tường minh, múi giờ sẽ theo ngôn ngữ — en-US nghĩa là New York, kể cả khi đi qua một proxy ở Đức.
Muốn tự đặt? Dùng acceptLanguage (Node) / accept_language (Python), ví dụ "en-US,en" — tùy chọn này đặt header Accept-Language, toàn bộ mảng navigator.languages và navigator.language — và Intl / toLocaleString cũng theo giá trị đó.
Nhập liệu giống người (humanize & showCursor)
Truyền humanize và mọi thao tác nhập liệu — di chuyển chuột, click, kéo, cuộn và gõ phím — đều chạy theo cùng một chuẩn mô phỏng người thật, ở cả cấp page (page.click / hover / type / fill / mouse.* / keyboard.type) lẫn cấp locator (locator.click / type / fill / pressSequentially / dragTo / …). Chuột di chuyển theo một đường cubic-bézier hơi cong, xuất phát từ vị trí con trỏ cuối cùng, và được đi theo mô hình min-jerk sum-of-sub-movements (một chuyển động chính dạng ballistic + một chuyển động hiệu chỉnh — vận tốc nhiều đỉnh như khi người thật với tay tới mục tiêu, chứ không phải một hình chuông đối xứng duy nhất), và mọi thứ được phát đi dưới dạng sự kiện thật, trusted (isTrusted === true, và navigator.webdriver vẫn là false). Trên Pro, các cú click theo tọa độ (mouse.click(x, y)) đi theo chuyển động được ghi lại từ người thật; mọi thao tác khác, cùng mọi cú click trên bản build mở và gói Miễn phí với GitHub, đều dùng quỹ đạo được sinh ra. Thêm showCursor để vẽ một chấm chạy theo chuyển động, giúp bạn quan sát.
Vì chuyển động dùng input native, một nút được nhấn bằng mouse.down() sẽ được giữ nguyên trong suốt quá trình di chuyển — nên down → move → up là một thao tác kéo có giữ nút thật sự (các control kéo để chọn vị trí như slider sẽ nhận được một thao tác kéo có nhấn giữ thật), và locator.dragTo cũng được humanize. Gõ phím diễn ra từng phím một, với khoảng cách giữa các phím ngẫu nhiên + các khoảng dừng ở ranh giới từ và thỉnh thoảng gõ nhầm rồi sửa lại; cuộn trang dùng quán tính ease-out và thỉnh thoảng dừng lại như đang đọc. fill focus vào trường nhập rồi gõ nội dung ra (giá trị dài hơn ~200 ký tự vẫn được điền một lần để việc điền dữ liệu lớn không bị chậm như rùa).
from clearcote import launch
browser = launch(fingerprint="seed-123", humanize=True, show_cursor=True)
page = browser.new_page()
page.goto("https://example.com")
page.click("text=Sign in") # eased curve, then a trusted click
page.fill("#email", "you@example.com") # focus + key-by-key human typing
page.locator("#password").type("s3cr3t") # locators are humanized too
# held-button drag (e.g. a slider): the press stays held across the move
x0, y0, x1 = 100, 300, 400 # the handle's start, and where to release it
page.mouse.move(x0, y0); page.mouse.down()
page.mouse.move(x1, y0); page.mouse.up()
browser.close()Kiểm tra tính nhất quán của backend render (checkRenderCoherence)
Persona có thể khai báo một GPU, nhưng nếu trang thực ra được vẽ bằng một software rasterizer (SwiftShader / llvmpipe — thường gặp khi chạy headless không có GPU) thì một detector khắt khe có thể nhận ra. Hãy kiểm tra trên một trang đang chạy: hàm này đọc vendor/renderer WebGL (unmasked) mà trang thực sự thấy, gắn cờ trường hợp fallback sang software rasterizer (một dấu hiệu lộ headless chí mạng — hãy bật canvas bridge hoặc chạy headed trên GPU thật) hoặc một cặp vendor/renderer không nhất quán, rồi trả về một kết luận có cấu trúc. Truyền vào GPU mà persona khai báo để kiểm tra thêm cả dòng GPU thực sự render trang. Dùng được ở API sync, async và trong Node.
from clearcote import launch, check_render_coherence
browser = launch(fingerprint="seed-123")
page = browser.new_page(); page.goto("about:blank")
verdict = check_render_coherence(page) # {'renderer', 'software_suspected', 'coherent', 'warnings'}
if not verdict["coherent"]:
print(verdict["warnings"]) # e.g. software rasterizer / incoherent GPU family
browser.close()Profile & lưu trữ lâu dài
Giữ danh tính ổn định qua các lần chạy bằng cách dùng lại cùng một seed fingerprint, và lưu lại cookie/storage bằng một thư mục user-data:
from clearcote import launch_persistent_context
ctx = launch_persistent_context(r"C:\clearcote\profiles\acme", fingerprint="acme-tenant-7", headless=False)
page = ctx.pages[0] if ctx.pages else ctx.new_page()Cookie trong một thư mục profile được mã hóa bằng một khóa gắn với máy đã tạo ra thư mục đó. Để sao chép profile sang máy khác mà cookie vẫn nguyên vẹn, hãy truyền portableProfile: true / portable_profile=True (khóa đi kèm theo profile) hoặc encryptionKey / encryption_key (khóa được suy ra từ secret của bạn, và không có gì nhạy cảm được ghi xuống đĩa). Dành cho bản build có giấy phép, Python & Node.
SDK cũng có các persona đã lưu: một Profile lưu các tùy chọn fingerprint, thiết lập proxy, thiết lập canvas-bridge và các tùy chọn khởi chạy khác dưới dạng JSON trong ~/.clearcote/profiles (ghi đè bằng CLEARCOTE_PROFILE_DIR).
from clearcote import Profile, launch, launch_persistent_context
Profile("acct-1", {
"fingerprint": "acct-1",
"gpu_vendor": "Google Inc. (Intel)",
"gpu_renderer": "ANGLE (Intel, Intel(R) UHD Graphics ... D3D11)",
"canvas_bridge": {"url": "ws://127.0.0.1:8443", "auth": "user:secret"},
}).save()
ctx = launch_persistent_context(r"C:\clearcote\profiles\acct-1", profile="acct-1")
browser = launch(profile="acct-1", headless=False)Profile đã lưu ở dạng văn bản thuần (plaintext) và có thể chứa thông tin xác thực như canvasBridge.auth. Hãy coi tệp profile là đầu vào đáng tin cậy, và đừng commit hay chia sẻ chúng.Các tùy chọn khởi chạy khác
extensions— danh sách đường dẫn tới thư mục của các extension dạng unpacked (sinh ra--load-extension+--disable-extensions-except).disablePrivacySandbox/disable_privacy_sandbox— đặttrueđể tắt các API Privacy Sandbox (Topics, FLEDGE / Protected Audience, Shared Storage, Private Aggregation, Fenced Frames). Tùy chọn này mặc định tắt từ 0.23: persona mặc định thể hiện là Google Chrome, vốn có sẵn tất cả các API đó. Chỉ bật khi persona là Chromium đã loại bỏ Google. WebUSB không bị ảnh hưởng.agentTyping/agent_typing— nhịp gõ phím của agent (humanlà mặc định /fast/instant). Xem Agent.tlsProfile— giữ TLS ClientHello nhất quán với phiên bản Chrome mà persona khai báo, để lớp mạng khớp với UA (chứ không dùng TLS gốc của bản build). Mặc định,"match-persona"đi theobrandVersion;"native"giữ nguyên không đổi;"chrome-<major>"cố định một major. Xem Các flag fingerprint.platform: "android"— một persona di động ở mức best-effort (cảm ứng, con trỏ coarse, màn hình/DPR di động, WebGL Mali/Adreno, viewport điện thoại). Trên engine desktop, phần render GPU vẫn là của desktop — hãy kết hợp với canvas bridge để render nhất quán.storageQuota,fingerprintProfile,canvasBridge,webrtcIp,acceptLanguage,disableGpuFingerprint,fingerprintNoise— xem Các flag fingerprint.
Tùy chọn mới hơn (bản build có giấy phép)
Các tùy chọn này cần bản build có giấy phép (Miễn phí với GitHub hoặc Pro). Revision engine mà mỗi tùy chọn yêu cầu được ghi trong ngoặc vuông; trên engine cũ hơn, SDK bỏ qua các tùy chọn 152 r22 kèm cảnh báo, còn engine thì bỏ qua những tùy chọn còn lại.
allowThirdPartyCookies/allow_third_party_cookies— cho phép cookie bên thứ ba như Chrome gốc. Bản nền đã loại bỏ Google chặn chúng theo mặc định, làm hỏng các frame đăng nhập nhúng, thanh toán và challenge vốn dựa vào chúng. [152 r22]transparentProxy/transparent_proxy— ẩn proxy khỏi header của request và thời gian kết nối (request HTTP thường không mang header proxy nào; kết nối qua proxy báo thời gian như một kết nối được tái sử dụng). Cần có proxy. [152 r22]fingerprintVoices: false/fingerprint_voices=False— giữ các giọng đọc (speech voice) của chính máy này thay vì danh sách của persona. [152 r22]fingerprint: "off"— khởi chạy hoàn toàn không có persona, để khắc phục sự cố. [152 r22]socks5Udp/socks5_udp— truyền UDP của WebRTC qua một proxysocks5://, để voice, video và kết nối peer hoạt động mà vẫn đi ra từ địa chỉ của proxy. Proxy phải cho phép điều này; nhiều pool proxy dân cư không cho phép. [151 r17]portableProfile/encryptionKey— profile có thể sao chép giữa các máy (xem ở trên). [151 r14; Python & Node]personaSchema: 2/persona_schema=2— một mô hình danh tính tùy chọn, trong đó màn hình và chip đồ họa phù hợp với bộ xử lý và bộ nhớ mà persona khai báo. Mặc định tắt, nên mọi seed hiện có vẫn giữ nguyên danh tính. Chỉ thêmrealGpuHost/real_gpu_hosttrên máy có card đồ họa thật. [151 r19; Python & Node]shaderDialect: "hlsl"— xem Shader dialect. [151 r15]profile: "auto"— khởi chạy bằng một fingerprint thật đã thu thập, được chọn cho máy này, thay vì dùng seed; tinh chỉnh bằngprofileSelect/profile_select. Python & Node. Trong Node, tùy chọn này hoạt động vớilaunch()mặc định,launchPersistentContext()vàserve()từ SDK 0.31.1; bản 0.31.0 trở về trước cầnephemeralProfile: falsevà lỗi vớiserve().
Không phụ thuộc vào bản build engine:
version/releaseChannel— chọn bản build; xem chọn bản build.licenseKey/license_key/LicenseKey— khóa giấy phép, nếu khóa không nằm trongCLEARCOTE_LICENSE_KEYhoặc~/.clearcote/license.key.licenseThroughProxy/license_through_proxy(hoặcCLEARCOTE_LICENSE_THROUGH_PROXY=1) — gửi các lệnh gọi cấp phép qua proxy của lần khởi chạy thay vì gửi từ máy này.ephemeralProfile/userDataDirtrênlaunch()— xem ghi chú trong phần Dùng SDK ở trên.widevine: true— phát nội dung có DRM (cả hai bản build); xem Widevine & DRM.quiet— tắt các cảnh báo và thông tin tiến trình của SDK khi khởi chạy.
Giá trị mặc định nhất quán (có thể ghi đè)
SDK áp dụng sẵn một vài giá trị mặc định chuẩn stealth để những dấu hiệu lộ dễ thấy không bị lọt ra:
- Khởi chạy headed mặc định không giả lập viewport (
viewport: null/no_viewport=True) đểwindow.innerWidthbám theo cửa sổ thật của hệ điều hành — một viewport giả lập 1280×720 nằm trên một cửa sổ thật là dấu hiệu lộ kiểu “cửa sổ bất khả thi”. Truyềnviewporttường minh để ghi đè. - WebRTC mặc định dùng
disable_non_proxied_udp, nên không có UDP nào đi ra ngoài proxy và địa chỉ thật của máy bạn được giữ kín. Chỉ có--webrtc-ip-handling-policydo chính bạn đặt trongargsmới ghi đè được — và, trên bản build mở, cảwebrtcIp/geoip, vốn cho phép UDP của WebRTC lại đi ra qua kết nối của chính bạn (bản build có giấy phép luôn chặn UDP của WebRTC bất kể thế nào). Với chính sách đó và không cówebrtcIp, trang sẽ không nhận được ICE candidate nào — khi dùng proxy, hãy truyềngeoip(hoặcwebrtcIp) để WebRTC báo cáo địa chỉ của proxy, hoặcsocks5Udpđể truyền UDP thật qua proxy SOCKS5. - Khi dùng proxy, QUIC / HTTP-3 bị tắt, giống như một Chrome thật đứng sau proxy — nên không có kết nối UDP nào được thử đi vòng ngoài proxy.
- Persona có nền tảng mặc định theo hệ điều hành máy host và brand mặc định là Google Chrome. Nếu không có
timezonevà không cógeoip, múi giờ sẽ theo ngôn ngữ (en-US→ New York). - Thông tin xác thực proxy được giao cho trình duyệt, không phải cho Playwright, ở những chỗ engine hỗ trợ: SOCKS5 thì luôn luôn (Playwright hoàn toàn không xác thực được SOCKS5), HTTP(S) từ 151 r19+ để cache của trang vẫn được bật (Python & Node). Xem bên dưới.
humanizechạy một bước kiểm tra trước khả năng thao tác (actionability pre-flight) trước mỗi cú click trusted (hiển thị / được bật / ổn định + kiểm tra phần tử có bị che hay không bằngelementFromPoint) và chuyển về click native nếu không đạt, nên một cú click trusted không bao giờ được phát ra khi đang bị lớp phủ che hoặc giữa lúc animation đang chạy.
SOCKS5 có thông tin xác thực
Chromium gốc hoàn toàn không xác thực được với proxy SOCKS5 — nó không triển khai bước thương lượng con username/password (sub-negotiation) — nên cách xoay xở thường thấy là dùng một relay cục bộ giữ thông tin xác thực. Bản build có giấy phép triển khai việc này ngay trong engine (RFC 1929), nên không cần relay. Truyền username và password dưới dạng các trường riêng hoặc ngay trong địa chỉ (socks5://user:pass@host:port); cách nào thì SDK cũng chuyển chúng cho engine. Thông tin xác thực nằm trong địa chỉ cần SDK 0.31.1 trở lên: các SDK cũ hơn để Playwright làm rơi mất chúng, và proxy không nhận được thông tin đăng nhập nào.
from clearcote import launch_persistent_context
ctx = launch_persistent_context(
"./profile",
proxy={"server": "socks5://proxy.example.net:1080", "username": "user", "password": "pass"},
)
page = ctx.pages[0] if ctx.pages else ctx.new_page()
page.goto("https://api.ipify.org?format=json") # confirm the exit IP is the proxy'sCần bản build có giấy phép (Miễn phí với GitHub hoặc Pro, engine 151 r14 trở lên); bản build mở không xác thực được với proxy SOCKS5, nên hãy dùng relay cục bộ hoặc proxy HTTP với bản build này.
Luôn kiểm tra địa chỉ thoát trước khi tin tưởng một phiên. Một proxy âm thầm fail open (khi lỗi thì để traffic đi thẳng) sẽ gửi traffic từ chính IP của bạn, và mọi biện pháp phòng ngừa khác trở nên vô nghĩa. Hãy kiểm tra một lần lúc khởi chạy bằng một dịch vụ trả về địa chỉ IP của bạn, thay vì cứ mặc định là ổn.
Mẹo: suy ra seed từ id tài khoản/tenant của chính bạn để mỗi danh tính đều tái lập được — cùng seed, cùng fingerprint trình duyệt, lần nào cũng vậy. Xem danh sách switch đầy đủ ở Các flag fingerprint.