كيفية استخدام إضافة Anti-Captcha بواسطة محرك Puppeteer أو Selenium
Puppeteer و Selenium هما المحركان الأساسيان المسؤولان عن أتمتة المتصفح. وتعمل الإضافة الخاصة بنا معهم بشكل متناغم. وفي هذا المقال سنستعرض كيفية استخدام Puppeteer و Selenium مع لغات NodeJS و بايثون على الترتيب. كما أننا ننصح بشدة باستخدام NodeJS + Puppeteer لأن البيئة الخاصة بها أكثر ملائمة.
1. قم بتنزيل الملفات الإضافية. في حالة استخدام NodeJS قم بتثبيت حزم npm الموضحة أدناه، وفي حالة استخدام بايثون قم بتنزيل الحزم و "chromedriver" من هذه الصفحة. ينبغي أن يكون إصدار الملف التشغيلي مطابقًا لإصدار متصفح كروم المثبت لديك.
npm install adm-zip puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
2.قم بتنزيل الإضافة بصيغة مضغوطة لمتصفح كروم، ثم قم باستخراج محتويات الملف المضغوط في مجلد المشروع. ستجد الإصدارات الفعلية هنا. ويمكنك فعل ذلك بطريقة ديناميكية كما هو موضح تاليًا:
//npm install adm-zip
const https = require('https')
const fs = require('fs');
const AdmZip = require("adm-zip");
const pluginURL = 'https://antcpt.com/anticaptcha-plugin.zip';
(async () => {
// تنزيل الإضافة
await new Promise((resolve) => {
https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
})
// فك ضغط الملف
const zip = new AdmZip("./plugin.zip");
await zip.extractAllTo("./plugin/", true);
})();
3. ثم قم بإعداد مفتاح الـAPI الخاص بك الموجود في ملف ./plugin/js/config_ac_api_key.js. يمكنك إيجاد مفتاح API الخاص بك في قسم العملاء. ستحتاج إلى وجود رصيد كافٍ لكي تتمكن من القيام بهذه الخطوة.
const apiKey = 'API_KEY_32_BYTES';
if (fs.existsSync('./plugin/js/config_ac_api_key.js')) {
let confData = fs.readFileSync('./plugin/js/config_ac_api_key.js', 'utf8');
confData = confData.replace(/antiCapthaPredefinedApiKey = ''/g, `antiCapthaPredefinedApiKey = '${apiKey}'`);
fs.writeFileSync('./plugin/js/config_ac_api_key.js', confData, 'utf8');
} else {
console.error('plugin configuration not found!')
}
4. بدأ تشغيل المتصفح واستخدام الإضافة. في حالة استخدام محرك Puppeteer فإننا نوصي باستخدام إضافة 'puppeteer-extra-plugin-stealth' الخاصة بحزمة 'puppeteer-extra' والتي تعمل على إخفاء كل علامات أتمتة الويب في متصفح كروم.
//npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
(async () => {
const browser = await puppeteer.launch({
headless: false,
ignoreDefaultArgs: [
"--disable-extensions",
"--enable-automation"
],
args: [
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process',
'--allow-running-insecure-content',
'--disable-blink-features=AutomationControlled',
'--no-sandbox',
'--mute-audio',
'--no-zygote',
'--no-xshm',
'--window-size=1920,1080',
'--no-first-run',
'--no-default-browser-check',
'--disable-dev-shm-usage',
'--disable-gpu',
'--enable-webgl',
'--ignore-certificate-errors',
'--lang=en-US,en;q=0.9',
'--password-store=basic',
'--disable-gpu-sandbox',
'--disable-software-rasterizer',
'--disable-background-timer-throttling',
'--disable-backgrounding-occluded-windows',
'--disable-renderer-backgrounding',
'--disable-infobars',
'--disable-breakpad',
'--disable-canvas-aa',
'--disable-2d-canvas-clip-aa',
'--disable-gl-drawing-for-tests',
'--enable-low-end-device-mode',
'--disable-extensions-except=./plugin',
'--load-extension=./plugin'
]
});
const page = await browser.newPage();
})();
5. عليك التوجه إلى صفحة الويب المستهدفة لتحرير نموذج إذا كان مطلوبًا. وستلتقط الإضافة الـ recaptcha تلقائيًا وتبدأ بحلها.
(async () => {
const url = 'https://anti-captcha.com/demo/?page=recaptcha_v2_textarea';
const login = 'Test login';
const password = 'Test password';
try {
await page.goto(url, {
waitUntil: "networkidle0"
});
} catch (e) {
console.error('err while loading the page: '+e);
}
// تعطيل أخطاء زمن التنقل
await page.setDefaultNavigationTimeout(0);
await page.$eval('#login', (element, login) => {
element.value = login;
}, login);
await page.$eval('#password', (element, password) => {
element.value = password;
}, password);
})();
6. قد تكون الخطوة التالية أكثر تعقيدًا بعض الشيء. حيث تتطلب بعض نماذج الويب أن يضغط المستخدم على زر الإرسال بعد حل رموز تحقق Recaptcha، بينما يستخدم البعض الأخَر دوال معينة ويقوم بإرسالها بشكل تلقائي. في الحالة الأولي نحتاج إلى ضغط زر الإرسال مباشرة بعد حل رموز Recaptcha. ولفعل ذلك في التوقيت الصحيح، سنحتاج إلى انتظار ظهور مٌحدد .antigate_solver.solved ثم الضغط على زر الإرسال.
// انتظر ظهور مُحدِد "تم الحل"
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('{{ $t('articles.how-to-integrate.code-comments.recaptcha-solved') }}');
// اِضغط زر الإرسال
await Promise.all([
page.click('#submitButton'),
page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('تم حل المهمة، تم تجاوز النموذج الذي يحتوي على recaptcha');
:لقد تم الأمر، تم تحرير النموذج، وتم حل الـ recaptcha وتخطيها. أمثلة على كود برمجي كامل
// first run the following to install required npm packages:
//
// npm install adm-zip follow-redirects puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
//
//
const https = require('follow-redirects').https;
const fs = require('fs');
const AdmZip = require("adm-zip");
const apiKey = 'YOUR_API_KEY_HERE!';
const pluginURL = 'https://antcpt.com/anticaptcha-plugin.zip';
const url = 'https://anti-captcha.com/demo/?page=recaptcha_v2_textarea';
const login = 'Test login';
const password = 'Test password';
let page = null;
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
(async () => {
// تنزيل الإضافة
await new Promise((resolve) => {
https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
})
// فك ضغط الملف
const zip = new AdmZip("./plugin.zip");
await zip.extractAllTo("./plugin/", true);
// تعيين مفتاح الـ API في ملف الإعدادات
await new Promise((resolve, reject) => {
if (fs.existsSync('./plugin/js/config_ac_api_key.js')) {
let confData = fs.readFileSync('./plugin/js/config_ac_api_key.js', 'utf8');
confData = confData.replace(/antiCapthaPredefinedApiKey = ''/g, `antiCapthaPredefinedApiKey = '${apiKey}'`);
fs.writeFileSync('./plugin/js/config_ac_api_key.js', confData, 'utf8');
resolve();
} else {
console.error('plugin configuration not found!')
reject();
}
});
// تعيين خيارات تشغيل المتصفح
const options = {
headless: false,
ignoreDefaultArgs: [
"--disable-extensions",
"--enable-automation"
],
args: [
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process',
'--allow-running-insecure-content',
'--disable-blink-features=AutomationControlled',
'--no-sandbox',
'--mute-audio',
'--no-zygote',
'--no-xshm',
'--window-size=1920,1080',
'--no-first-run',
'--no-default-browser-check',
'--disable-dev-shm-usage',
'--disable-gpu',
'--enable-webgl',
'--ignore-certificate-errors',
'--lang=en-US,en;q=0.9',
'--password-store=basic',
'--disable-gpu-sandbox',
'--disable-software-rasterizer',
'--disable-background-timer-throttling',
'--disable-backgrounding-occluded-windows',
'--disable-renderer-backgrounding',
'--disable-infobars',
'--disable-breakpad',
'--disable-canvas-aa',
'--disable-2d-canvas-clip-aa',
'--disable-gl-drawing-for-tests',
'--enable-low-end-device-mode',
'--disable-extensions-except=./plugin',
'--load-extension=./plugin'
]
}
try {
// تشغيل المتصفح واستخدام الإضافة الجديدة
const browser = await puppeteer.launch();
page = await browser.newPage();
} catch (e) {
console.log('could not launch browser: '+e.toString())
return;
}
// الذهاب إلى الصفحة المطلوبة
try {
await page.goto(url, {
waitUntil: "networkidle0"
});
} catch (e) {
console.error('err while loading the page: '+e);
}
// تعطيل أخطاء زمن التنقل
await page.setDefaultNavigationTimeout(0);
// تعبئة النموذج
await page.$eval('#login', (element, login) => {
element.value = login;
}, login);
await page.$eval('#password', (element, password) => {
element.value = password;
}, password);
// انتظر ظهور مُحدِد "تم الحل"
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('{{ $t('articles.how-to-integrate.code-comments.recaptcha-solved') }}');
// اِضغط زر الإرسال
await Promise.all([
page.click('#submitButton'),
page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('حل recaptcha');
})();
معلومة إضافية: يوجد خدعة لتشغيل الإضافة في وضع Headless، ويرجع ذلك إلى أن متصفح كروم لا يدعم عمليات أتمتة المتصفح عن طريق الإضافات. يمكنك فعل ذلك عن طريق استخدام طريقة تعرف باسم Xvfb والتي تسمح لتطبيقك باستخدام حاسوب افتراضي.
# تثبيت الإضافة
apt-get install -y xvfb
# تعيين متغير العرض
export DISPLAY=:0
# استخدام برنامج Xvfb الخفي في الخلفية (مرة واحدة فقط)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &
# انتظر قليلًا لكي يظهر (مرة واحدة)
sleep 5
# أضف "xvfb-run" في بداية سكريبت "node" أو "بايثون"
xvfb-run node myscript.js
# أو
xvfb-run python myscript.py