Mengotomatiskan Profil Browser dengan API Lokal

Jalankan profil dari skrip, dapatkan endpoint debugging, lalu sambungkan Playwright atau Puppeteer ke browser yang sudah memiliki identitas dan proxy-nya.
Mengotomatiskan browser antideteksi biasanya digambarkan sebagai masalah yang sulit. Padahal tidak, asalkan alatnya memberikan satu hal yang sudah dipahami pustaka otomasi Anda: endpoint debugging.
Gambaran umumnya
PowerOps menjalankan API HTTP yang terikat ke alamat loopback. Skrip Anda meminta API itu untuk memulai sebuah profil; ia meluncurkan browser dengan identitas, penyimpanan, dan proxy profil tersebut yang sudah terpasang, lalu mengembalikan endpoint WebSocket dari browser yang berjalan. Skrip Anda terhubung ke endpoint itu dengan Playwright, Puppeteer, atau apa pun yang memahami protokol DevTools.
Pustaka otomasi tidak perlu tahu apa itu fingerprint. Saat ia terhubung, lingkungannya sudah terbentuk.
Memulai profil
curl -s -H "Authorization: Bearer $POWEROPS_API_KEY" \
http://127.0.0.1:50326/status
Setiap rute kecuali pemeriksaan status memerlukan kunci bearer. Memulai browser mengembalikan endpoint untuk disambungi:
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
Menyambungkan pustaka Anda
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");
Baris yang penting adalah komentarnya. Tidak ada konfigurasi fingerprint di skrip Anda, karena mengonfigurasi lingkungan bukan tugas skrip Anda. Itu milik profil, dan tetap sama baik profil dibuka oleh orang yang mengeklik sebuah baris maupun oleh tugas terjadwal pada pukul tiga pagi.
Apa saja yang dicakup API
- Rute status adalah pemeriksaan kesehatan, dan satu-satunya yang tidak memerlukan kunci.
- Rute browser memulai, menghentikan, dan menanyakan browser yang sedang berjalan.
- Rute profil membuat, memperbarui, menanyakan, dan menghapus profil.
- Rute proxy mengelola pustaka proxy dan menetapkan rute.
- Rute grup mengatur profil secara massal.
- Rute ekstensi mengimpor dan menetapkan ekstensi.
Bagaimana API ini dijaga tetap lokal
API yang mengendalikan browser dengan akun yang sedang masuk layak mendapat penjelasan soal batas-batasnya.
- Ia terikat ke 127.0.0.1. Tidak ada pengaturan yang membuatnya mendengarkan di antarmuka lain.
- Kunci bearer diperlukan di setiap rute kecuali pemeriksaan status.
- Ia memvalidasi header Host dan tidak mengirim header CORS, sehingga halaman web yang terbuka di browser sehari-hari Anda tidak dapat menjangkaunya.
- Rahasia bersifat tulis-saja: kata sandi profil, rahasia dua faktor, dan kata sandi proxy tidak pernah dikembalikan oleh rute kueri mana pun.
Pola yang layak ditiru
Kueri profil dalam sebuah grup, mulai satu per satu, kerjakan tugasnya, hentikan. Jalankan beberapa sekaligus, bukan semuanya bersamaan. Kendalanya adalah memori di mesin Anda sendiri, karena setiap profil adalah proses browser sungguhan.
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 });
}
}));
}
Menghentikan profil dalam `finally` lebih penting daripada kelihatannya: penutupan yang bersih adalah yang menulis state browser ke luar, dan profil yang dimatikan paksa di tengah sesi bisa kehilangan sesi yang baru saja dibangunnya.
