Menu

Come usare il plugin di Anti-Captcha con Puppeteer o Selenium

Puppeteer e Selenium sono due motori importanti per l'automazione del browser e il nostro plugin si integra perfettamente con loro. In questo articolo ti mostriamo come usarlo con Puppeteer e Selenium rispettivamente per i linguaggi di programmazione NodeJS e Python. Se devi scegliere, ti consigliamo NodeJS+Puppeteer per il suo ambiente originario.

1. Installa dipendenze. Per NodeJS basta installare il pacchetto npm ricevuto che trovi sotto, per Python installa i pacchetti e scarica "chromedriver" eseguibile da questa pagina. La versione del driver deve essere compatibile con la versione di Chromeinstallata sul tuo sistema.

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

2. Scarica il plugin per Chrome in versione ZIP, estrailo nella cartella del tuo progetto. Le versioni effettive si trovano qui. Puoi anche farlo programmaticamente:

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

3. Successivamente, configura la chiave della tua API nel file ./plugin/js/config_ac_api_key.js. Puoi trovare la chiave della tua API nell'area clienti. Devi avere un saldo positivo affinché funzioni.

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. Avvia il browser col plugin. Per Puppeteer, consigliamo il plugin 'puppeteer-extra-plugin-stealth' per il pacchetto 'puppeteer-extra', che nasconde qualsiasi segno del browser automatizzato 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. Vai su una pagina bersaglio e, se richiesto, compila il modulo. Il plugin prenderà il Recaptcha automaticamente e comincerà a risolverlo.

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);
    }
    // disabilita errori timeout della navigazione
    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. Il passaggio successivo è un po' complicato. Alcuni moduli web richiedono che l'utente premi un bottone di invio dopo aver risolto il Recaptcha, altri utilizzano dei callback e lo inviano automaticamente. Nel primo caso vogliamo premere il bottone di invio subito dopo che il Recaptcha è stato risolto. Per farlo nel momento giusto, aspetta che compaia il selettore .antigate_solver.solved e poi premi il bottone di invio.

Javascript
Python
// aspetta che compaia il selettore "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') }}');

// premi il pulsante invia
await Promise.all([
    page.click('#submitButton'),
    page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('task completato, modulo con recaptcha bypassato');

Ci siamo, il modulo è compilato, il Recaptcha è risolto e bypassato. Esempi di codice completo:

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

    // imposta la chiave dell'API nel file di configurazione
    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();
        }
    });

    // imposta le opzioni di avvio del 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 {
        // avvia il browser col plugin
        const browser = await puppeteer.launch();
        page = await browser.newPage();
    } catch (e) {
        console.log('could not launch browser: '+e.toString())
        return;
    }

    // vai alla pagina bersaglio
    try {
        await page.goto(url, {
            waitUntil: "networkidle0"
        });
    } catch (e) {
        console.error('err while loading the page: '+e);
    }

    // disabilita errori timeout della navigazione
    await page.setDefaultNavigationTimeout(0);

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

    // aspetta che compaia il selettore "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') }}');

    // premi il pulsante invia
    await Promise.all([
        page.click('#submitButton'),
        page.waitForNavigation({ waitUntil: "networkidle0" })
    ]);
    console.log('recaptcha risolto');

})();

Bonus: c'è un trucco per eseguire il plugin in modalità headless, dato che Chrome non supporta l'automazione del browser automation coi plugin. Usa lo strumento chiamato Xvfb che fornisce un desktop virtuale per la tua applicazione.

# installa il pacchetto
apt-get install -y xvfb

# imposta la variabile display
export DISPLAY=:0

# esegui il demone Xvfb in background (una sola volta)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &

# aspetta un po' affinché possa comparire (una volta sola)
sleep 5

# aggiungi il prefisso "xvfb-run" allo script "node" o "python"
xvfb-run node myscript.js
# oppure
xvfb-run python myscript.py