أتمتة الملفات الشخصية للمتصفح عبر واجهة برمجية محلية

شغّل ملفاً شخصياً من سكربت، واحصل على نقطة تنقيح، وأرفق Playwright أو Puppeteer بمتصفح يحمل هويته وبروكسيه جاهزين.
يُقدَّم عادةً أتمتة المتصفح المضاد للكشف على أنها مشكلة صعبة. وليست كذلك، شرط أن تسلّمك الأداة الشيء الوحيد الذي تعرف مكتبة الأتمتة لديك كيف تستخدمه: نقطة تنقيح.
الصورة العامة
يشغّل PowerOps واجهة HTTP برمجية مرتبطة بعنوان loopback. يطلب سكربتك منها تشغيل ملف شخصي، فتطلق المتصفح بهوية ذلك الملف وتخزينه وبروكسيه مرفقة بالفعل، وتعيد نقطة WebSocket الخاصة بالمتصفح العامل. يتصل سكربتك بتلك النقطة عبر Playwright أو Puppeteer أو أي شيء يتحدث بروتوكول DevTools.
لا تحتاج مكتبة الأتمتة أن تعرف ما هي البصمة أصلاً. فحين تتصل تكون البيئة قد أُقيمت.
تشغيل ملف شخصي
curl -s -H "Authorization: Bearer $POWEROPS_API_KEY" \
http://127.0.0.1:50326/status
كل مسار عدا فحص الحالة يتطلب مفتاح bearer. وتشغيل متصفح يعيد النقطة التي ترفق بها:
curl -s -X POST \
-H "Authorization: Bearer $POWEROPS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profileId": "..."}' \
http://127.0.0.1:50326/browser/start
إرفاق مكتبتك
import { chromium } from "playwright";
const res = await fetch("http://127.0.0.1:50326/browser/start", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.POWEROPS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ profileId }),
});
const { ws } = await res.json();
// The profile's identity, storage and proxy are already in place.
const browser = await chromium.connectOverCDP(ws);
const [context] = browser.contexts();
const page = context.pages()[0] ?? await context.newPage();
await page.goto("https://example.com");
السطر المهم هو التعليق. لا يوجد في سكربتك ضبط للبصمة، لأن ضبط البيئة ليس مهمة سكربتك. إنه من شأن الملف الشخصي، ويبقى كما هو سواء فتح الملفَّ شخصٌ نقر على صف أو مهمة مجدولة في الثالثة فجراً.
ما الذي تغطيه الواجهة
- مسار الحالة فحص سلامة، وهو الوحيد الذي لا يحتاج مفتاحاً.
- مسارات المتصفح تشغّل المتصفحات العاملة حالياً وتوقفها وتستعلم عنها.
- مسارات الملفات الشخصية تنشئ الملفات وتحدّثها وتستعلم عنها وتحذفها.
- مسارات البروكسي تدير مكتبة البروكسيات وتسند المسارات.
- مسارات المجموعات تنظّم الملفات الشخصية بالجملة.
- مسارات الإضافات تستورد الإضافات وتسندها.
كيف تبقى محلية
واجهة برمجية تقود متصفحات تحمل حسابات مسجَّلة الدخول تستحق كلمة عن حدودها.
- ترتبط بـ 127.0.0.1. لا يوجد إعداد يجعلها تستمع على أي واجهة أخرى.
- يُشترط مفتاح bearer في كل مسار عدا فحص الحالة.
- تتحقق من ترويسة Host ولا ترسل أي ترويسات CORS، فلا تستطيع صفحة ويب مفتوحة في متصفحك اليومي الوصول إليها.
- الأسرار للكتابة فقط: كلمات مرور الملفات الشخصية وأسرار المصادقة الثنائية وكلمات مرور البروكسي لا يعيدها أي مسار استعلام أبداً.
نمط يستحق النسخ
استعلم عن الملفات الشخصية في مجموعة، وشغّل كل واحد، وأنجز العمل، ثم أوقفه. شغّلها بضعة ملفات في كل مرة لا جميعها دفعة واحدة. القيد هو الذاكرة على جهازك أنت، فكل ملف شخصي عملية متصفح حقيقية.
const { profiles } = await api("/profiles?groupId=" + groupId);
for (const batch of chunk(profiles, 5)) {
await Promise.all(batch.map(async (profile) => {
const { ws } = await api("/browser/start", { profileId: profile.id });
try {
await doTheWork(ws);
} finally {
await api("/browser/stop", { profileId: profile.id });
}
}));
}
إيقاف الملف الشخصي في `finally` أهم مما يبدو: الإغلاق النظيف هو ما يكتب حالة المتصفح، وقد يفقد الملف الذي يُنهى في منتصف الجلسة الجلسة التي أسسها للتو.
