إعداد بروكسي Puppeteer، التوصيل باستخدام --proxy-server و page.authenticate
يشرح هذا الدليل كيفية توصيل بروكسي HTTP من Socks5Proxy في Puppeteer باستخدام وسيطة --proxy-server ومصادقة page.authenticate، واتصال SOCKS5، وكود لتشغيل متصفحات متعددة بعناوين IP مختلفة.
كيف يعمل البروكسي في Puppeteer؟
يحدد Puppeteer البروكسي باستخدام وسيطات يتم تمريرها عند تشغيل Chrome. إضافة العنوان إلى --proxy-server يجعل جميع الصفحات في ذلك المتصفح تستخدم نفس البروكسي. لا يمكن إضافة اسم المستخدم وكلمة المرور لبروكسي HTTP كوسيطات تشغيل، لذا يتم تمريرهما عبر page.authenticate بعد فتح الصفحة، مما يجعل Puppeteer يرد تلقائيًا عند طلب المصادقة من البروكسي.
يستخدم المثال عنوان IP 198.51.100.23 ومنفذ HTTP 8000 ومنفذ SOCKS5 1080 واسم المستخدم spx_user وكلمة المرور spx_pass.
npm install puppeteerكيفية الاتصال بـ HTTP بروكسي مع المصادقة؟
أضف --proxy-server=198.51.100.23:8000 إلى args في launch، وبعد إنشاء الصفحة باستخدام newPage، قم بتمرير اسم المستخدم وكلمة المرور إلى page.authenticate. يجب تكرار المصادقة لكل صفحة جديدة.
يتم فتح مواقع HTTPS بشكل طبيعي. يقوم المتصفح بإنشاء نفق CONNECT ويتواصل بشكل مشفر داخل النفق.
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
headless: true,
args: ["--proxy-server=http://198.51.100.23:8000"],
});
const page = await browser.newPage();
await page.authenticate({ username: "spx_user", password: "spx_pass" });
await page.goto("https://api.ipify.org", { waitUntil: "domcontentloaded" });
console.log(await page.evaluate(() => document.body.innerText)); // proxy IP
await browser.close();كيف يتم استخدام بروكسي SOCKS5؟
ضع عنوان socks5:// في --proxy-server. ومع ذلك، لا يدعم Chrome مصادقة اسم المستخدم وكلمة المرور لبروتوكول SOCKS، لذا لا يتم تطبيق page.authenticate على SOCKS5. للاتصال عبر SOCKS5، استخدم مصادقة IP عن طريق تسجيل IPv4 للخادم الذي يتم تشغيل الكود عليه في لوحة التحكم.
إذا كنت بحاجة إلى الاتصال باستخدام اسم المستخدم وكلمة المرور، فإن استخدام منفذ HTTP لنفس IP هو الأبسط. سيظهر الموقع نفسه لأنك تستخدم نفس IP.
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
args: ["--proxy-server=socks5://198.51.100.23:1080"], // server IP is authorized in the dashboard
});
const page = await browser.newPage();
await page.goto("https://api.ipify.org");
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();كيفية تشغيل متصفحات متعددة باستخدام IPs مختلفة؟
Chrome يخصص بروكسي واحد لكل متصفح يعمل، لذا إذا كنت بحاجة إلى عناوين IP مختلفة، يجب تشغيل المتصفحات بشكل منفصل. يقوم الكود التالي باستقبال قائمة ip:port:user:pass من API ويفتح متصفحًا لكل من العناصر الثلاثة الأولى، ثم يعرض IP الذي يظهر في كل صفحة.
فتح العديد من المتصفحات يستهلك ذاكرة كبيرة. نوصي بإنشاء طابور مهام وتحديد عدد المتصفحات التي تعمل في نفس الوقت.
import puppeteer from "puppeteer";
const KEY = "YOUR_API_KEY";
const res = await fetch("https://socks5proxy.io/api/v1/proxies/download?format=ip:port:user:pass&protocol=http", {
headers: { Authorization: "Bearer " + KEY },
});
const lines = (await res.text()).trim().split("\n").slice(0, 3);
await Promise.all(lines.map(async (line) => {
const [ip, port, user, pass] = line.trim().split(":");
const browser = await puppeteer.launch({ args: ["--proxy-server=http://" + ip + ":" + port] });
try {
const page = await browser.newPage();
await page.authenticate({ username: user, password: pass });
await page.goto("https://api.ipify.org", { timeout: 30000 });
console.log(ip, await page.evaluate(() => document.body.innerText));
} finally {
await browser.close();
}
}));كيف يمكن فتح الصفحات بشكل أسرع؟
المرور عبر البروكسي يعني أن الصور والخطوط ومقاطع الفيديو يتم استقبالها جميعًا عبر البروكسي، مما يستهلك المزيد من النطاق الترددي والوقت. إذا كنت بحاجة إلى النصوص والبيانات فقط، يمكنك منع طلبات الصور والخطوط باستخدام page.setRequestInterception لزيادة السرعة وتوفير النطاق الترددي الشهري للخطة المشتركة.
تعد قيمة waitUntil مهمة أيضًا. networkidle0 ينتظر انتهاء جميع الطلبات مما قد يكون بطيئًا، لذا يُفضل استخدام page.waitForSelector للمتابعة فور ظهور العناصر المطلوبة.
await page.setRequestInterception(true);
page.on("request", (req) => {
const type = req.resourceType();
if (type === "image" || type === "font" || type === "media") req.abort();
else req.continue();
});هل يمكن استخدام عناوين IP مختلفة لكل صفحة في متصفح واحد؟
خيار --proxy-server في Chrome يطبق على المتصفح بأكمله، مما يجعل من الصعب إعطاء IP مختلف لكل صفحة. بدءًا من Puppeteer 22، يمكنك استخدام خيار proxyServer في browser.createBrowserContext لتخصيص بروكسي مختلف لكل سياق. السياقات منفصلة في الكوكيز والتخزين، مما يجعلها مناسبة للعمل على حسابات مختلفة.
يمكنك تمرير اسم المستخدم وكلمة المرور إلى الصفحات التي تم إنشاؤها في السياق باستخدام page.authenticate. هذا يستخدم ذاكرة أقل من فتح متصفحات متعددة.
import puppeteer from "puppeteer";
const browser = await puppeteer.launch();
const context = await browser.createBrowserContext({ proxyServer: "http://198.51.100.23:8000" });
const page = await context.newPage();
await page.authenticate({ username: "spx_user", password: "spx_pass" });
await page.goto("https://api.ipify.org");
console.log(await page.evaluate(() => document.body.innerText));
await context.close();
await browser.close();ما الذي يجب ضبطه لتظهر كمستخدم من ذلك البلد؟
قم بتعيين Accept-Language باستخدام page.setExtraHTTPHeaders والمنطقة الزمنية باستخدام page.emulateTimezone لتتناسب مع دولة IP. إذا كانت اللغة أو المنطقة الزمنية مختلفة عن دولة IP، قد تظهر الصفحة بلغة خاطئة أو بتنسيق تاريخ مختلف.
يمكنك ضبط حجم الشاشة باستخدام page.setViewport، ولشاشات الهواتف المحمولة، يمكنك تمرير إعدادات الجهاز من KnownDevices في puppeteer إلى page.emulate.
await page.setExtraHTTPHeaders({ "Accept-Language": "ja-JP,ja;q=0.9" });
await page.emulateTimezone("Asia/Tokyo");
await page.setViewport({ width: 1366, height: 900 });كيف يمكن الحفاظ على استقرار المتصفح في المهام طويلة الأمد؟
للعمليات التي تعمل طوال اليوم، من الأكثر استقرارًا إغلاق المتصفح وإعادة فتحه بعد معالجة عدد معين من الصفحات بدلاً من إبقائه مفتوحًا لفترة طويلة. المتصفحات المفتوحة لفترة طويلة تستهلك ذاكرة أكثر تدريجيًا، وقد تتوقف جميع المهام التالية عند حدوث خطأ.
استخدم دائمًا page.close مع try و finally، وأضف timeout إلى goto لتجنب التوقف عند الصفحات التي لا تستجيب. يمكن إعادة المحاولة في المهام الفاشلة بفتح متصفح جديد ببروكسي آخر.
تسجيل وقت استجابة البروكسي والأخطاء لكل بروكسي يساعد في العثور على الخطوط البطيئة ومراجعة دعم العملاء في لوحة التحكم أو تغيير مجموعة المهام.
كيف يتم حل الأخطاء الشائعة؟
net::ERR_INVALID_AUTH_CREDENTIALS أو 407 تشير إلى قيم غير صحيحة في page.authenticate أو عدم استدعائها بعد newPage. تأكد من استدعائها قبل goto لكل صفحة.
net::ERR_PROXY_CONNECTION_FAILED تشير إلى عنوان أو منفذ غير صحيح. تأكد من استخدام منفذ HTTP مع عنوان HTTP ومنفذ SOCKS5 مع عنوان SOCKS5. إذا تم رفض الاتصال عبر SOCKS5، تحقق من تسجيل IP الخادم الخارجي في تفويض IP.