Menu

كيفية استخدام إضافة Anti-Captcha بواسطة محرك Puppeteer أو Selenium

Puppeteer و Selenium هما المحركين الأساسيين لأتمتة المتصفح. وتعمل الإضافة الخاصة بنا معهم بشكل جيد. وفي هذا المقال سنستعرض كيفية استخدام Puppeteer و Selenium مع لغات NodeJS و بايثون على الترتيب. كما أننا ننصح بشدة باستخدام NodeJS + Puppeteer لأن البيئة الخاصة بها أكثر ملائمة.

1. تثبيت الحزم البرمجية المطلوبة لتشغيل الإضافة. لتشغيل NodeJs ينبغي تثبيت حزم npm المذكورة أدناه، ولتشغيل بايثون، يجب تثبيت وتحميل حزم "chromedriver" الموجودة في هذه الصفحة. يجب أن يوافق إصدار المُشغل إصدار متصفح الكروم المُثبت على نظامك.

Javascript
Python
npm install adm-zip puppeteer puppeteer-extra puppeteer-extra-plugin-stealth

2. تحميل الإضافة بصيغة مضغوطة من أجل متصفح كروم، ثم استخراج الملف المضغوط في مجلد المشروع. توجد الإصدارات الفعلية هنا. يمكنك القيام بذلك عن طريق السطور البرمجية التالية:

Javascript
Python
//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 () => {
    // download the plugin
    await new Promise((resolve) => {
        https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
    })
    // unzip it
    const zip = new AdmZip("./plugin.zip");
    await zip.extractAllTo("./plugin/", true);
})();

3. الخطوة التالية، إعداد مفتاح API الخاص بك في ملف ./plugin/js/config_ac_api_key.js . يمكنك إيجاد مفتاح API الخاص بك في منطقة العملاء. وستحتاج إلى وجود رصيد في حسابك من أجل تشغيله.

Javascript
Python
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' والتي تعمل على إخفاء كل علامات أتمتة الويب في متصفح كروم.

Javascript
Python
//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 تلقائيًا وتبدأ بحلها.

Javascript
Python
(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);
    }
    // disable navigation timeout errors
    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 ثم الضغط على زر الإرسال بعد ذلك.

Javascript
Python
// wait for "solved" selector to come up
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') }}');

// press submit button
await Promise.all([
    page.click('#submitButton'),
    page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('task completed, form with recaptcha bypassed');

:لقد تم الأمر، تم تحرير النموذج، وتم حل الـ recaptcha وتخطيها. أمثلة على كود برمجي كامل

Javascript
Python
// 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 () => {
    // download the plugin
    await new Promise((resolve) => {
        https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
    })
    // unzip it
    const zip = new AdmZip("./plugin.zip");
    await zip.extractAllTo("./plugin/", true);

    // set API key in configuration file
    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();
        }
    });

    // set browser launch options
    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 {
        // launch browser with the plugin
        const browser = await puppeteer.launch();
        page = await browser.newPage();
    } catch (e) {
        console.log('could not launch browser: '+e.toString())
        return;
    }

    // navigate to the target page
    try {
        await page.goto(url, {
            waitUntil: "networkidle0"
        });
    } catch (e) {
        console.error('err while loading the page: '+e);
    }

    // disable navigation timeout errors
    await page.setDefaultNavigationTimeout(0);

    // fill the form
    await page.$eval('#login', (element, login) => {
        element.value = login;
    }, login);
    await page.$eval('#password', (element, password) => {
        element.value = password;
    }, password);

    // wait for "solved" selector to come up
    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') }}');

    // press submit button
    await Promise.all([
        page.click('#submitButton'),
        page.waitForNavigation({ waitUntil: "networkidle0" })
    ]);
    console.log('recaptcha solved');

})();

مكافأة: يوجد خدعة سحرية لتشغيل الإضافة في وضع البرمجة الخلفية (وضع لا يشمل واجهة مستخدم) لأن متصفح كروم لا يدعم الأتمتة بواسطة الإضافة. ولفعل ذلك، ينبغي عليك استخدام خاصية تسمىXvfb تعمل على توفير بيئة سطح مكتب افتراضية من أجل تشغيل تطبيقك

# install the package
apt-get install -y xvfb

# set display variable
export DISPLAY=:0

# start Xvfb daemon in the background (only once)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &

# wait a bit to let it come up (only once)
sleep 5

# add prefix "xvfb-run" to "node" or "python" script
xvfb-run node myscript.js
# or
xvfb-run python myscript.py