Menu

Paano gamitin ang plugin ng Anti-Captcha sa Puppeteer o Selenium

Ang Puppeteer at Selenium ang dalawang pangunahing makina para sa awtomasyon ng browser at ang aming plugin ay madaling naisasama sa mga ito. Sa artikulong ito ay ipakikita namin kung paano ito gamitin sa Puppeteer at Selenium para sa mga lenggwaheng pang-program na NodeJS at Python. Kung pipili ka sa dalawang ito, inirerekomenda namin ang NodeJS+Puppeteer dahil sa katutubong environment nito.

1. I-install ang mga dependency. Para sa NodeJS i-install lamang ang mga npm package sa ibaba, para sa Python i-install ang mga package at i-download ang executable na "chromedriver" sa pahinang ito. Ang bersiyon ng driver ay dapat tugma sa bersiyon ng Chrome na naka-install sa iyong sistema.

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

2. I-download ang plugin sa berisyong ZIP na para sa Chrome, i-unzip ito sa folder ng iyong proyekto. Ang mga aktwal na bersiyon ay nakalagay rito. Maaari mo rin itong gawin nang naka-program:

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

3. Sunod, i-configure ang iyong susi ng API sa ./plugin/js/config_ac_api_key.js file. Maaari mo ring makita ang iyong susi ng API sa lugar ng mga kostumer. Kailangang may positibo kang balanse para mapagana mo ito.

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. I-initialize ang browser gamit ang plugin. Para sa Puppeteer inirerekomenda namin ang plugin na 'puppeteer-extra-plugin-stealth' para sa 'puppeteer-extra' na package, na itinatago ang lahat ng mga palatandaan ng web-automated na browser na Chromium.

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. Pumunta sa puntiryang pahina at punan ang form kung kinakailangan. Ang plugin ay makukuha ang Recaptcha nang awtomatiko at sisimulang resolbahin ito.

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);
    }
    // huwag paganahin ang mga timeout error sa pag-navigate
    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. Ang sunod medyo nakalilitong parte. Ang ilang mga web form ay inataasan ang mga gumagamit na pindutin ang submit na boton pagkatapos malutas ang Recaptcha, ang iba ay gumagamit ng mga callback at sinusumite ito nang awtomatiko. Sa unang kaso gusto nating pindutin ang submit na boton pagkatapos na malutas ang Recaptcha. Para magawa ito sa tamang pagkakataon, hintayin lamang ang selector na .antigate_solver.solved na lumabas at saka pindutin ang submit na boton.

Javascript
Python
// hintayin ang selector na "solved" na lumabas
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') }}');

// pindutin ang submit na boton
await Promise.all([
    page.click('#submitButton'),
    page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('nakumpleto ang gawain, ang form na may recaptcha ay na-bypass');

Ayun na nga, ang form ay napunan, ang Recapatcha ay nalutas at na-bypass. Mga buong code na halimbawa:

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

    // i-set ang susi ng API sa file ng configuration
    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();
        }
    });

    // i-set ang mga opsiyon sa pag-launch ng browser
    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 {
        // i-launch ang browser gamit ang plugin
        const browser = await puppeteer.launch();
        page = await browser.newPage();
    } catch (e) {
        console.log('could not launch browser: '+e.toString())
        return;
    }

    // pumunta sa puntiryang pahina
    try {
        await page.goto(url, {
            waitUntil: "networkidle0"
        });
    } catch (e) {
        console.error('err while loading the page: '+e);
    }

    // huwag paganahin ang mga timeout error sa pag-navigate
    await page.setDefaultNavigationTimeout(0);

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

    // hintayin ang selector na "solved" na lumabas
    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') }}');

    // pindutin ang submit na boton
    await Promise.all([
        page.click('#submitButton'),
        page.waitForNavigation({ waitUntil: "networkidle0" })
    ]);
    console.log('nalutas ang recaptcha');

})();

Bonus: mayroong paraan para mapagana ang plugin sa headless na mode, sa kadahilanang ang Chrome ay hindi sinusuportahan ang awtomasyon ng browser gamit ang mga plugin. Gamitin ang utility na Xvfb na nagbibigay ng virtual na desktop para sa iyong aplikasyon.

# i-install ang package
apt-get install -y xvfb

# i-set ang variable ng display
export DISPLAY=:0

# umpisahan ang Xvfb daemon sa background (isang beses lamang)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &

# maghintay ng sandali para lumabas ito (isang beses lamang)
sleep 5

# idagdag ang prefix na "xvfb-run" sa "node" o "python" script
xvfb-run node myscript.js
# o
xvfb-run python myscript.py