लोकल API से ब्राउज़र प्रोफ़ाइल को ऑटोमेट करना

स्क्रिप्ट से प्रोफ़ाइल शुरू करें, डीबगिंग एंडपॉइंट पाएँ, और Playwright या Puppeteer को ऐसे ब्राउज़र से जोड़ें जिसमें आइडेंटिटी और प्रॉक्सी पहले से लगी हो।
एंटीडिटेक्ट ब्राउज़र को ऑटोमेट करना आम तौर पर कठिन समस्या की तरह पेश किया जाता है। ऐसा नहीं है, बशर्ते टूल आपको वही एक चीज़ दे जिसे आपकी ऑटोमेशन लाइब्रेरी पहले से इस्तेमाल करना जानती है: एक डीबगिंग एंडपॉइंट।
इसका ढाँचा
PowerOps लूपबैक पते से बँधा एक HTTP API चलाता है। आपकी स्क्रिप्ट उससे प्रोफ़ाइल शुरू करने को कहती है; वह ब्राउज़र को उस प्रोफ़ाइल की आइडेंटिटी, स्टोरेज और प्रॉक्सी पहले से लगाकर लॉन्च करता है, और चल रहे ब्राउज़र का 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");
सबसे अहम पंक्ति कमेंट है। आपकी स्क्रिप्ट में कोई फ़िंगरप्रिंट कॉन्फ़िगरेशन नहीं है, क्योंकि माहौल को कॉन्फ़िगर करना आपकी स्क्रिप्ट का काम नहीं है। वह प्रोफ़ाइल का है, और वह वैसा ही रहता है चाहे प्रोफ़ाइल को कोई व्यक्ति पंक्ति पर क्लिक करके खोले या रात तीन बजे कोई शेड्यूल्ड जॉब।
API क्या-क्या कवर करता है
- स्टेटस रूट एक हेल्थ चेक है, और अकेला जिसे कुंजी की ज़रूरत नहीं।
- ब्राउज़र रूट मौजूदा चल रहे ब्राउज़रों को शुरू, बंद और क्वेरी करते हैं।
- प्रोफ़ाइल रूट प्रोफ़ाइल बनाते, अपडेट करते, क्वेरी करते और हटाते हैं।
- प्रॉक्सी रूट प्रॉक्सी लाइब्रेरी सँभालते और रूट असाइन करते हैं।
- ग्रुप रूट प्रोफ़ाइलों को थोक में व्यवस्थित करते हैं।
- एक्सटेंशन रूट एक्सटेंशन इम्पोर्ट और असाइन करते हैं।
इसे लोकल कैसे रखा जाता है
जो API साइन-इन अकाउंट वाले ब्राउज़र चलाता है, उसकी सीमाओं के बारे में एक शब्द कहना बनता है।
- यह 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` में रोकना दिखने से ज़्यादा मायने रखता है: साफ़ तरीक़े से बंद करना ही ब्राउज़र की स्थिति को लिखता है, और सत्र के बीच में मारा गया प्रोफ़ाइल वह सत्र गँवा सकता है जो उसने अभी-अभी स्थापित किया था।
