
invisible_playwright v0.7.0
متصفح تخفٍّ مجاني مضاد للاكتشاف مع Playwright: بصمة Firefox غير مكتشفة في وضع headless. استخراج بيانات عبر Python وتجاوز reCAPTCHA وكشف الروبوتات. مفتوح المصدر.
يتم كشف Playwright بواسطة أنظمة مكافحة البوتات والكابتشا.
هذا الإصدار يعمل على Firefox مضاد للكشف ببصمة غير قابلة للاكتشاف، ومتوافق مع كود Playwright الحالي لديك.

كيف يعمل
تطرح أنظمة مكافحة البوتات سؤالين، ويقيّم reCAPTCHA وhCaptcha وCloudflare Turnstile الإجابات. يجيب invisible_playwright بـ"نعم" على كليهما.
1. هل هذا متصفح حقيقي؟ نعم. إنه Firefox، مُعدَّل على مستوى الكود المصدري بلغة C++.
- تُضبط بصمة المتصفح داخل المحرك، لا تُحقن في الصفحة: navigator، والشاشة، وGPU/WebGL، والكانفاس، والخطوط، والصوت، وWebRTC، والمنطقة الزمنية، والشبكة. سواء في الوضع بلا واجهة أو بواجهة، القيم نفسها في الحالتين.
- لا طبقة JS وسيطة، ولا تجاوز، ولا أثر يمكن قراءته.
2. هل يستخدمه شخص حقيقي؟ نعم. الإجراءات مُحوَّلة إلى سلوك بشري في المشغّل.
- كل نقرة وتمرير وسحب يتبع مسار فأرة طبيعيًا بتوقيت بشري، دون مؤشر يقفز.
- كل إدخال مطابق بايتًا ببايت لفأرة حقيقية: مصدر إدخال حقيقي، وضغط، وأحداث موثوقة.
التثبيت
Windows، في PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
$env:Path = "$env:USERPROFILE\.local\bin;$env:Path"
uv init --python ">=3.11" my-project
cd my-project
uv add invisible-playwright
uv run invisible-playwright fetch # one-time download, sha256-verified: 240 MB, about 550 MB unpacked
Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
uv init --python ">=3.11" my-project
cd my-project
uv add invisible-playwright
uv run invisible-playwright fetch # one-time download, sha256-verified: 262 MB (x86_64) / 253 MB (arm64), about 550 MB unpacked
المنصات المدعومة: Windows x86_64، Linux x86_64 / arm64.
ثم احفظ أحد الأمثلة أدناه باسم main.py في my-project وشغّله باستخدام uv run main.py.
الاستخدام
بصمة عشوائية لكل جلسة
واجهة Playwright البرمجية، المتزامنة وغير المتزامنة، دون أي تغييرات في الكود. نفس الكائنات، نفس الاستدعاءات، نفس القيم المُعادة. بعض الأسطح خارج النطاق - التتبع (tracing)، وHAR، وCDP، وسياق طلبات API - وكل واحد منها يرفض بجملة توضح السبب بدلاً من أن يسيء التصرف بصمت. إذا كنت تستخدم Playwright بالفعل، فإن التبديل يتم بسطرين:
- from playwright.sync_api import sync_playwright
- with sync_playwright() as p:
- browser = p.firefox.launch()
+ from invisible_playwright import InvisiblePlaywright
+ with InvisiblePlaywright() as browser:
كل جلسة تحصل على بصمة مميزة (GPU، الصوت، الخطوط، الشاشة، ~200 حقل) وحركة فأرة بمنحنيات بيزييه.
المزامنة
from invisible_playwright import InvisiblePlaywright
with InvisiblePlaywright(proxy={"server": "socks5://...", "username": "u", "password": "p"}) as browser:
page = browser.new_page()
page.goto("https://example.com")
page.click("#submit") # mouse arcs to the button on a Bezier curve
غير متزامن
from invisible_playwright.async_api import InvisiblePlaywright
async with InvisiblePlaywright(proxy={"server": "socks5://...", "username": "u", "password": "p"}) as browser:
page = await browser.new_page()
await page.goto("https://example.com")
await page.click("#submit")
كائن browser هو playwright.sync_api.Browser / playwright.async_api.Browser - كل طريقة من طرق Playwright تعمل كما هي.
سجّل البذرة (seed) لإعادة تشغيل الجولة:
sf = InvisiblePlaywright()
with sf as browser:
print("seed =", sf.seed)
# ...
بصمة قابلة لإعادة الإنتاج
with InvisiblePlaywright(seed=42) as browser:
... # same GPU, same canvas hash, same audio context, every run
الوكلاء
proxy = {
"server": "socks5://gate.example.com:1080",
"username": "user",
"password": "pass",
}
with InvisiblePlaywright(proxy=proxy) as browser:
...
المخططات المدعومة: socks5، socks4، http، https. يتم توجيه DNS عبر البروكسي افتراضيًا، دون تسريب محلي.
المنطقة الزمنية
تتبع المنطقة الزمنية للمتصفح المعامل timezone=:
# default: timezone is auto-derived from the egress IP (proxy egress if a
# proxy is set, otherwise the host's own public IP)
with InvisiblePlaywright(proxy=proxy) as browser:
...
# explicit IANA zone always wins, the only way to force a specific zone
with InvisiblePlaywright(proxy=proxy, timezone="America/New_York") as browser:
...
تثبيت حقول بصمة محددة
افتراضيًا يأتي كل شيء من seed. لفرض قيم محددة بينما يبقى الباقي مشتقًا من البذرة:
with InvisiblePlaywright(
seed=42,
pin={
"gpu.renderer": "ANGLE (AMD, Radeon R9 200 Series Direct3D11 vs_5_0 ps_5_0, D3D11)",
"gpu.vendor": "Google Inc. (AMD)",
"screen.width": 2560,
"screen.height": 1440,
"hardware.concurrency": 16,
},
) as browser:
...
اختيار GPU pin لواحد من الـ personas المُتحقَّق منها بدلاً من تعيين سلسلة نصية حرة،
لأن قيم getParameter البالغ عددها ~81 وقائمة الإضافات تنتقل مع
اسم الـ renderer ويتحقق منها كاشف مقابل الاسم. أي اسم لا يحمله التجمع
يُثير خطأً، ويُدرج الخطأ الأسماء التي يحملها.
القائمة الكاملة للمفاتيح القابلة للتثبيت، وكيفية تفاعل التثبيت مع عيّنة Bayesian، والأنماط الشائعة موجودة في docs/pinning.md.
CLI
الأمر المثبَّت هو invisible-playwright، بشرطة. ويعمل python -m invisible_playwright بالطريقة نفسها تماماً ولا يحتاج إلى شيء على PATH.
invisible-playwright fetch # download the engine if missing, check every cached
# one against the seal, print the path
invisible-playwright version # wrapper, core and engine versions, and where the
# engine is cached
الوثائق والأدلة والمقارنات
إذا كنت تفضّل التوجيه النصي على كتابة السكربت. هذه الصفحة هي المحرك، على هيئة مكتبة
Python. طريقتان لاستخدامه دون كتابة شيفرة، كلتاهما بسطر واحد: من عميل MCP
لديك بالفعل (Claude Code، Claude Desktop، Cursor)،
claude mcp add stealth -- uvx aihawk، انظر
صفحة خادم MCP؛ أو بواجهة
ونموذج مضمّنين، لا يحتاجان سوى مفتاح OpenRouter،
uvx aihawk ui --openrouter-key sk-or-...، انظر
AIHawk. المحرك نفسه في الأسفل، والثاني
عميل للأول.
كل ذلك يُقرأ بشكل أفضل، وقابل للبحث، في الويكي، منظَّمًا في أربعة أقسام بدلًا من قائمة مسطّحة واحدة: