यदि आप Playwright पर पार्सिंग स्क्रिप्ट चला रहे हैं या मल्टी-एकाउंटिंग कर रहे हैं और प्रत्येक प्रॉक्सी के लिए अलग ब्राउज़र इंस्टेंस उठाते हैं - तो आप बेवजह मेमोरी और CPU बर्बाद कर रहे हैं। Playwright प्रॉक्सी को BrowserContext के स्तर पर असाइन करना जानता है, न कि पूरे ब्राउज़र पर, और यह स्क्रिप्ट की आर्किटेक्चर को पूरी तरह से बदल देता है: एक ब्राउज़र प्रक्रिया, विभिन्न IP, कुकीज़ और फिंगरप्रिंट के साथ दर्जनों अलग-अलग संदर्भ। इस लेख में - यह कैसे काम करता है, Python और Node.js में कोड, और यह रेजिडेंट और मोबाइल प्रॉक्सी के साथ काम करते समय विशेष रूप से क्यों महत्वपूर्ण है।
समस्या: browser.launch() पर प्रॉक्सी - महंगा और असुविधाजनक
Playwright पर कई स्क्रिप्ट का पारंपरिक दृष्टिकोण इस प्रकार है: प्रत्येक प्रॉक्सी के लिए chromium.launch({ proxy: {...} }) कॉल किया जाता है, एक अलग ब्राउज़र प्रक्रिया बनाई जाती है, वह काम करती है, फिर बंद हो जाती है, और नए प्रॉक्सी के साथ अगला शुरू होता है। यदि आपको Wildberries या Ozon के लिए 50 IP पते को समानांतर में संसाधित करना है, तो इसका मतलब है कि 50 पूर्ण Chromium प्रक्रियाएँ एक साथ चल रही हैं - प्रत्येक शुरू होने पर 150 से 300 MB RAM का उपयोग करती है, बिना टैब और रेंडरिंग के।
व्यावहारिक रूप से, यह सामान्य VPS पर 8 GB मेमोरी के साथ पहले से ही 15-20 समानांतर ब्राउज़रों पर रुक जाता है। सर्वर स्वैप करना शुरू कर देता है, स्क्रिप्ट टाइमआउट के साथ गिर जाती हैं, कुछ प्रॉक्सी काम नहीं कर पाती हैं। समस्या प्रॉक्सी में नहीं है और न ही Playwright में - समस्या आर्किटेक्चर में है: प्रत्येक ब्राउज़र लॉन्च पूरे रेंडरिंग इंजन, GPU प्रक्रिया, नेटवर्क और दर्जनों सहायक थ्रेड्स को खींचता है, जबकि वास्तव में आपको केवल नया IP और एक स्वच्छ सत्र चाहिए।
Playwright इस समस्या को कुशलता से हल करता है: प्रॉक्सी को ब्राउज़र लॉन्च करते समय नहीं, बल्कि BrowserContext बनाने के समय असाइन किया जा सकता है - एक ही ब्राउज़र प्रक्रिया के भीतर एक हल्की अलग-थलग "सैंडबॉक्स"। एक Chromium प्रक्रिया दर्जनों संदर्भों को बनाए रख सकती है, प्रत्येक अपने प्रॉक्सी, अपने कुकीज़ और localStorage के साथ, एक-दूसरे के साथ नहीं मिलते।
ब्राउज़र बनाम BrowserContext: क्या अंतर है
Browser - यह इंजन (Chromium, Firefox या WebKit) की प्रक्रिया है, जो एक बार शुरू होती है और लंबे समय तक चलती है। BrowserContext - यह इस प्रक्रिया के भीतर एक अलग वातावरण है, जो निजी विंडो (incognito) के समान है, जिसमें अपने कुकीज़, कैश, अनुमतियाँ और, हमारे लिए महत्वपूर्ण, अपने नेटवर्क सेटिंग्स, जिसमें प्रॉक्सी शामिल हैं।
यदि हम Dolphin Anty या AdsPower जैसे एंटी-डिटेक्ट ब्राउज़रों की तुलना करें - वहां प्रत्येक "प्रोफ़ाइल" भी मूल रूप से कुकीज़ और फिंगरप्रिंट के साथ अलग-अलग अलग-थलग कंटेनर है। Playwright प्रोग्रामेटिक रूप से समान तर्क बनाने की अनुमति देता है: एक ब्राउज़र - कई संदर्भ, प्रत्येक अपने IP के साथ एक अलग "प्रोफ़ाइल" के रूप में।
| पैरामीटर | ब्राउज़र पर प्रॉक्सी | BrowserContext पर प्रॉक्सी |
|---|---|---|
| एक IP पर मेमोरी | 150-300 MB (नया प्रक्रिया) | 15-40 MB (नया संदर्भ) |
| IP बदलने की गति | 2-5 सेकंड (ब्राउज़र को फिर से शुरू करना) | 0.1-0.3 सेकंड (नया संदर्भ) |
| कुकीज़ की अलगाव | पूर्ण (अलग प्रक्रियाएँ) | पूर्ण (संदर्भ कुकीज़ साझा नहीं करते) |
| 8 GB RAM पर अधिकतम समानांतर सत्र | ~20-25 | ~150-200 |
संदर्भ पर प्रॉक्सी: Python में कोड
नीचे एक बुनियादी पैटर्न है: एक ब्राउज़र एक बार शुरू होता है, और फिर प्रत्येक प्रॉक्सी के लिए एक अलग संदर्भ बनाया जाता है। यह Playwright का समन्वयित API है, लेकिन तर्क async संस्करण के लिए समान है।
from playwright.sync_api import sync_playwright
proxies = [
{"server": "http://proxy1.example.com:8000", "username": "user1", "password": "pass1"},
{"server": "http://proxy2.example.com:8000", "username": "user2", "password": "pass2"},
{"server": "http://proxy3.example.com:8000", "username": "user3", "password": "pass3"},
]
with sync_playwright() as p:
# ब्राउज़र एक बार शुरू होता है, बिना प्रॉक्सी के
browser = p.chromium.launch(headless=True)
for proxy in proxies:
# प्रॉक्सी वास्तव में संदर्भ को असाइन की जाती है, न कि ब्राउज़र को
context = browser.new_context(
proxy={
"server": proxy["server"],
"username": proxy["username"],
"password": proxy["password"],
},
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
)
page = context.new_page()
page.goto("https://httpbin.org/ip", timeout=30000)
print(page.content())
page.close()
context.close() # केवल संदर्भ को बंद करें, ब्राउज़र जीवित रहता है
browser.close()
मुख्य बिंदु - browser.launch()browser.new_context()
संदर्भ पर प्रॉक्सी: Node.js में कोड
JavaScript में वही तर्क async/await का उपयोग करके - अक्सर Node.js पर पार्सिंग फ्रेमवर्क के साथ जोड़ा जाता है:
const { chromium } = require('playwright');
const proxies = [
{ server: 'http://proxy1.example.com:8000', username: 'user1', password: 'pass1' },
{ server: 'http://proxy2.example.com:8000', username: 'user2', password: 'pass2' },
];
(async () => {
const browser = await chromium.launch({ headless: true });
for (const proxy of proxies) {
const context = await browser.newContext({
proxy: {
server: proxy.server,
username: proxy.username,
password: proxy.password,
},
});
const page = await context.newPage();
await page.goto('https://httpbin.org/ip', { timeout: 30000 });
console.log(await page.content());
await page.close();
await context.close();
}
await browser.close();
})();
दर्जनों प्रॉक्सी को समानांतर में संसाधित करने के लिए संदर्भों को Promise.all
ब्राउज़र को फिर से शुरू किए बिना प्रॉक्सी का स्वच्छ रोटेशन
"स्वच्छ रोटेशन" का अर्थ है कि IP बदलने पर पिछले सत्र के कोई अवशेष नहीं रहते - न कुकीज़, न कैश, न सेवा कार्यकर्ता। पूरे ब्राउज़र को फिर से शुरू करने पर यह स्वचालित रूप से सुनिश्चित किया जाता है, लेकिन संसाधनों के लिए महंगा है। संदर्भों के साथ काम करते समय, वही पुराने संदर्भ को बंद करने और नए को बनाने के द्वारा प्राप्त किया जाता है - यह प्रक्रिया सेकंड के अंश लेती है।
async function rotateProxy(browser, proxyList, index) {
const proxy = proxyList[index % proxyList.length];
const context = await browser.newContext({ proxy });
const page = await context.newPage();
return { context, page };
}
// इस तरह उपयोग करें: हर N-वीं पुनरावृत्ति पर IP बदलें
for (let i = 0; i < 100; i++) {
if (i % 10 === 0) {
const { context, page } = await rotateProxy(browser, proxies, i);
// नई सत्र के साथ 10 अनुरोधों के लिए काम करें
}
}
यह पैटर्न विशेष रूप से मार्केटप्लेस के पार्सिंग के लिए उपयोगी है: उदाहरण के लिए, Wildberries या Ozon से कीमतें इकट्ठा करते समय, जहां बॉट्स के खिलाफ सुरक्षा एक समय में एक IP से अनुरोधों की संख्या को ट्रैक करती है। संदर्भ स्तर पर रोटेशन आपको हर 5-10 अनुरोधों में IP बदलने की अनुमति देता है, जबकि ब्राउज़र को फिर से शुरू करने पर प्रदर्शन को खोए बिना।
ऐसे परिदृश्यों के लिए रेसिडेंशियल प्रॉक्सी अच्छी तरह से काम करते हैं - वे वास्तविक उपयोगकर्ताओं के IP प्रदान करते हैं, जिन्हें मार्केटप्लेस कम संदिग्ध के रूप में चिह्नित करते हैं, स्पष्ट रूप से सर्वर रेंज के विपरीत।
मेमोरी और गति की तुलना
8 GB RAM और 4 vCPU के साथ परीक्षण VPS पर विभिन्न IP के साथ 100 पृष्ठों को पार करने के कार्य पर दो दृष्टिकोणों का परीक्षण किया गया। पहले मामले में, प्रत्येक IP के लिए एक अलग chromium.launch() शुरू किया गया, जबकि दूसरे में - एक ब्राउज़र के साथ 100 संदर्भों को क्रमिक रूप से बनाया गया।
| मेट्रिक | 100 बार browser.launch() शुरू करना | 1 ब्राउज़र में 100 संदर्भ |
|---|---|---|
| पीक मेमोरी | ~6.8 GB | ~1.9 GB |
| कुल निष्पादन समय | 182 सेकंड | 97 सेकंड |
| टाइमआउट के कारण गिरने वाले सत्रों की संख्या | 7 | 0 |
इस परीक्षण में मेमोरी की बचत लगभग 70% थी, और कुल निष्पादन समय लगभग आधा हो गया क्योंकि हर बार Chromium प्रक्रिया को शुरू करने और समाप्त करने पर कोई ओवरहेड नहीं था। बड़े वॉल्यूम में - हजारों IP प्रति दिन - अंतर और भी स्पष्ट हो जाता है, और यह सीधे इस पर प्रभाव डालता है कि आप एक ही सर्वर पर बिना हार्डवेयर अपग्रेड के कितने प्रॉक्सी का उपयोग कर सकते हैं।
व्यावहारिक मामले: पार्सिंग और मल्टी-एकाउंटिंग
मार्केटप्लेस की पार्सिंग। Wildberries, Ozon या Avito से कीमतें इकट्ठा करते समय, एक ही ब्राउज़र दर्जनों संदर्भों को खोले रखता है, प्रत्येक एक अद्वितीय IP और अपने कुकी स्टोरेज के साथ। यह अनुरोधों के पैटर्न के कारण ब्लॉक होने के जोखिम को कम करता है और डेटा को तेजी से इकट्ठा करने की अनुमति देता है, IP के बीच प्रक्रिया को फिर से शुरू करने की प्रतीक्षा किए बिना।
मल्टी-एकाउंटिंग और अकाउंट्स की खेती। Facebook Ads या TikTok Ads में विज्ञापन अभियानों का परीक्षण करने के लिए Playwright स्क्रिप्ट के माध्यम से, प्रत्येक खाते को अपने प्रॉक्सी और उपयोगकर्ता-एजेंट के साथ अलग संदर्भ में रखना तार्किक है - यह Multilogin या GoLogin जैसे एंटी-डिटेक्ट ब्राउज़रों के व्यवहार की नकल करता है, केवल बिना एंटी-डिटेक्ट के लाइसेंस के, पूरी तरह से प्रोग्रामेटिक।
विज्ञापन का भौगोलिक परीक्षण। मार्केटर्स को यह जांचने की आवश्यकता होती है कि विभिन्न देशों में क्रिएटिव कैसे प्रदर्शित होता है, विभिन्न प्रॉक्सी के साथ संदर्भ एक ब्राउज़र सत्र में क्रमिक रूप से "जरूरी क्षेत्रों" में जाने की अनुमति देते हैं, बिना मैन्युअल रूप से दर्जनों अलग-अलग विंडो खोले।
ऐसे परिदृश्यों के लिए जहां मोबाइल ट्रैफ़िक की नकल करना महत्वपूर्ण है - जैसे कि वेबसाइट या TikTok Ads में विज्ञापन के मोबाइल संस्करण की जांच - मोबाइल प्रॉक्सी पर विचार करना चाहिए, जो वास्तविक मोबाइल ऑपरेटरों से IP प्रदान करते हैं और एंटी-फ्रॉड सिस्टम के लिए कम संदिग्ध होते हैं।
यदि कार्य - उच्च गुमनामी की आवश्यकता के बिना तेज और स्थिर पार्सिंग है (जैसे कि बिना सख्त एंटी-बॉट सुरक्षा के वेबसाइटों से सार्वजनिक डेटा इकट्ठा करना), डेटा सेंटर प्रॉक्सी बड़े अनुरोधों के वॉल्यूम पर गति और लागत का सबसे अच्छा अनुपात प्रदान करते हैं।
आम गलतियाँ और उनसे कैसे बचें
1. प्रॉक्सी को launch() में सेट करना, new_context() में नहीं। यह शुरुआती लोगों की सबसे सामान्य गलती है - ब्राउज़र लॉन्च करते समय निर्दिष्ट प्रॉक्सी सभी संदर्भों पर तुरंत लागू होती है और इसे व्यक्तिगत रूप से ओवरराइड नहीं किया जा सकता। यदि IP के लिए लचीलापन चाहिए, तो हमेशा प्रॉक्सी को new_context() में पास करें।
2. पुराने संदर्भ बंद नहीं होते। यदि सैकड़ों संदर्भ बनाए जाते हैं और context.close()
3. सभी संदर्भों के लिए एक ही उपयोगकर्ता-एजेंट। यदि प्रॉक्सी बदलता है, जबकि ब्राउज़र का फिंगरप्रिंट समान रहता है (उपयोगकर्ता-एजेंट, भाषा, समय क्षेत्र), तो मार्केटप्लेस और सोशल मीडिया के एंटी-बॉट सिस्टम फिर भी सत्रों को आपस में जोड़ सकते हैं। प्रत्येक संदर्भ के लिए प्रॉक्सी के साथ उपयोगकर्ता-एजेंट और व्यू पोर्ट को बदलें।
4. प्रॉक्सी के टाइमआउट की अनदेखी। रेजिडेंशियल और मोबाइल प्रॉक्सी कभी-कभी डेटा सेंटर प्रॉक्सी की तुलना में धीमी प्रतिक्रिया देते हैं, वास्तविक नेटवर्क अवसंरचना के कारण। page.goto()
5. एक ही ब्राउज़र में एक साथ बहुत सारे संदर्भ। मेमोरी की बचत के बावजूद, 500+ सक्रिय संदर्भों का अनियंत्रित निर्माण भी प्रक्रिया की सीमाओं में रुक जाएगा। एक उचित संतुलन - एक ब्राउज़र प्रक्रिया पर 30-80 सक्रिय संदर्भ, सर्वर की RAM की मात्रा के आधार पर।
निष्कर्ष
BrowserContext के स्तर पर प्रॉक्सी को असाइन करना, न कि पूरे ब्राउज़र पर - यह एक आर्किटेक्चरल समाधान है जो 70% तक मेमोरी की बचत करता है, IP के रोटेशन को कई गुना तेज करता है और सत्रों के बीच कुकीज़ का स्वच्छ अलगाव प्रदान करता है, बिना लगातार Chromium को फिर से शुरू किए। मार्केटप्लेस की पार्सिंग, विभिन्न क्षेत्रों में विज्ञापन का परीक्षण और मल्टी-एकाउंटिंग के लिए यह एक सीधा तरीका है कि आप बिना हार्डवेयर अपग्रेड के उसी सर्वर पर समानांतर सत्रों की संख्या बढ़ा सकें।
यदि आप Wildberries, Ozon से डेटा इकट्ठा करने के लिए या Facebook Ads और TikTok Ads के विज्ञापन खातों के साथ काम करने के लिए Playwright पर स्क्रिप्ट बना रहे हैं, तो प्रॉक्सी पूल की गुणवत्ता कोड की आर्किटेक्चर के रूप में उतनी ही महत्वपूर्ण है। उन कार्यों के लिए जहां IP की विश्वसनीयता और एंटी-बॉट सिस्टम के प्रति स्थिरता महत्वपूर्ण है, रेसिडेंशियल प्रॉक्सी से शुरू करना उचित है - वे ऊपर वर्णित "एक ब्राउज़र, कई संदर्भ" दृष्टिकोण के साथ अच्छी तरह से मेल खाते हैं।