Menu

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

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

1. قم بتنزيل الملفات الإضافية. في حالة استخدام NodeJS قم بتثبيت حزم npm الموضحة أدناه، وفي حالة استخدام بايثون قم بتنزيل الحزم و "chromedriver" من هذه الصفحة. ينبغي أن يكون إصدار الملف التشغيلي مطابقًا لإصدار متصفح كروم المثبت لديك.

Node.js
Python
npm install adm-zip puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
pip3 install selenium

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

Node.js
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 () => {
    // تنزيل الإضافة
    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);
})();
import urllib.request
import zipfile

url = 'https://antcpt.com/anticaptcha-plugin.zip'
# تنزيل الإضافة
filehandle, _ = urllib.request.urlretrieve(url)
# فك ضغط الملف
with zipfile.ZipFile(filehandle, "r") as f:
    f.extractall("plugin")

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

Node.js
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!')
}
from pathlib import Path
import zipfile

# `+t('articles.how-to-integrate.code-comments.set-api-key')+`
api_key = "API_KEY_32_BYTES"
file = Path('./plugin/js/config_ac_api_key.js')
file.write_text(file.read_text().replace("antiCapthaPredefinedApiKey = ''", "antiCapthaPredefinedApiKey = '{}'".format(api_key)))

# `+t('articles.how-to-integrate.code-comments.zip-back')+`
zip_file = zipfile.ZipFile('./plugin.zip', 'w', zipfile.ZIP_DEFLATED)
for root, dirs, files in os.walk("./plugin"):
        for file in files:
            path = os.path.join(root, file)
            zip_file.write(path, arcname=path.replace("./plugin/", ""))
zip_file.close()

4. بدأ تشغيل المتصفح واستخدام الإضافة. في حالة استخدام محرك Puppeteer فإننا نوصي باستخدام إضافة 'puppeteer-extra-plugin-stealth' الخاصة بحزمة 'puppeteer-extra' والتي تعمل على إخفاء كل علامات أتمتة الويب في متصفح كروم.

Node.js
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();
})();
from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_extension('./plugin.zip')

browser = webdriver.Chrome('./chromedriver', options=options)

5. عليك التوجه إلى صفحة الويب المستهدفة لتحرير نموذج إذا كان مطلوبًا. وستلتقط الإضافة الـ recaptcha تلقائيًا وتبدأ بحلها.

Node.js
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);
    }
    // `+t('articles.how-to-integrate.code-comments.disable-timeouts')+`
    await page.setDefaultNavigationTimeout(0);

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

})();
browser.get('https://anti-captcha.com/demo/?page=recaptcha_v2_textarea')

# filling form
browser.find_element_by_css_selector('#login').send_keys('Test login')
browser.find_element_by_css_selector('#password').send_keys('Test password')

6. قد تكون الخطوة التالية أكثر تعقيدًا بعض الشيء. حيث تتطلب بعض نماذج الويب أن يضغط المستخدم على زر الإرسال بعد حل رموز تحقق Recaptcha، بينما يستخدم البعض الأخَر دوال معينة ويقوم بإرسالها بشكل تلقائي. في الحالة الأولي نحتاج إلى ضغط زر الإرسال مباشرة بعد حل رموز Recaptcha. ولفعل ذلك في التوقيت الصحيح، سنحتاج إلى انتظار ظهور مٌحدد .antigate_solver.solved ثم الضغط على زر الإرسال.

Node.js
Python
// انتظر ظهور مُحدِد "تم الحل"
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('حل recaptcha');

// اِضغط زر الإرسال
await Promise.all([
    page.click('#submitButton'),
    page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('تم حل المهمة، تم تجاوز النموذج الذي يحتوي على recaptcha ');
# انتظر ظهور مُحدِد "تم الحل"
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))
# articles.how-to-integrate.code-comments.press-submit
browser.find_element_by_css_selector('#submitButton').click()

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

Node.js
Python

كيفية دمج إضافة المتصفح Anti-Captcha في Node.js

// 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('حل recaptcha');

    // اِضغط زر الإرسال
    await Promise.all([
        page.click('#submitButton'),
        page.waitForNavigation({ waitUntil: "networkidle0" })
    ]);
    console.log('حل recaptcha');

})();

كيفية دمج إضافة المتصفح Anti-Captcha في Python

import urllib.request
import zipfile
import os
from pathlib import Path
from selenium import webdriver

# تنزيل الإضافة
url = 'https://antcpt.com/anticaptcha-plugin.zip'
filehandle, _ = urllib.request.urlretrieve(url)
# فك ضغط الملف
with zipfile.ZipFile(filehandle, "r") as f:
    f.extractall("plugin")

# تعيين مفتاح الـ API في ملف الإعدادات
api_key = "YOUR_API_KEY_HERE!"
file = Path('./plugin/js/config_ac_api_key.js')
file.write_text(file.read_text().replace("antiCapthaPredefinedApiKey = ''", "antiCapthaPredefinedApiKey = '{}'".format(api_key)))

# اضغط مجلد إضافة المتصفح وقم بتسمية الملف المضغوط plugin.zip
zip_file = zipfile.ZipFile('./plugin.zip', 'w', zipfile.ZIP_DEFLATED)
for root, dirs, files in os.walk("./plugin"):
        for file in files:
            path = os.path.join(root, file)
            zip_file.write(path, arcname=path.replace("./plugin/", ""))
zip_file.close()

# تعيين خيارات تشغيل المتصفح
options = webdriver.ChromeOptions()
options.add_extension('./plugin.zip')

# تعيين خيارات تشغيل المتصفح
browser = webdriver.Chrome('./chromedriver', options=options)

# الذهاب إلى الصفحة المطلوبة
browser.get('https://anti-captcha.com/demo/?page=recaptcha_v2_textarea')

# تعبئة النموذج
browser.find_element_by_css_selector('#login').send_keys('Test login')
browser.find_element_by_css_selector('#password').send_keys('Test password')

# انتظر ظهور مُحدِد "تم الحل"
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))

# اِضغط زر الإرسال
browser.find_element_by_css_selector('#submitButton').click()

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

Node.js
Python
# تثبيت الإضافة
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
# تثبيت الإضافة
apt-get install -y xvfb

# تعيين متغير العرض
export DISPLAY=:0

# استخدام برنامج Xvfb الخفي في الخلفية (مرة واحدة فقط)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &

# انتظر قليلًا لكي يظهر (مرة واحدة)
sleep 5

# أضف "xvfb-run" في بداية سكريبت "node" أو "بايثون"
xvfb-run python myscript.py