Come usare il plugin Anti-Captcha su Puppeteer o Selenium
Puppeteer e Selenium sono due motori principali per l'automazione del browser e il nostro plugin s'integra senza problemi in essi. In questo articolo ti mostriamo come usarlo in Puppeteer e Selenium per i linguaggi di programmazione NodeJS e Python rispettivamente. Se devi scegliere tra i due, consigliamo vivamente NodeJS+Puppeteer per il suo ambiente nativo.
1. Installa le dipendenze. Per NodeJS installa gli specifici pacchetti npm i basso, per Python installa i pacchetti e scarica il file eseguibile "chromedriver" da questa pagina. La versione driver dovrebbe combaciare con la versione di Chrome installata sul tuo sistema.
npm install adm-zip puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
2. Scarica il plugin nella versione ZIP per Chrome, estrai il file nella tua cartella del progetto. Le versioni attuali si trovano qui. Puoi anche farlo con un programma:
//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. Il prossimo passaggio consiste nel configurare la tua chiave API nel file ./plugin/js/config_ac_api_key.js. Puoi trovare la tua chiave API nell' area clienti. Avrai bisogno di un saldo in positivo affinchè funzioni.
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 con il plugin. Per Puppeteer consigliamo il plugin 'puppeteer-extra-plugin-stealth' per il pacchetto 'puppeteer-extra' che nasconde qualsiasi traccia di un browser Chromium automatizzato.
//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 target e compila un modulo se richiesto. Il plugin rileverà il Recaptcha automaticamente comincerà a risolverlo.
(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);
}
// disattiva errori di timeout
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 prossimo step è un pò complesso. Alcuni moduli web richiedono che l'utente prema su Invia dopo aver risolto il Recaptcha, altri utilizzano dei callback per inviarli automaticamente. Nel primo caso vogliamo premere su Invia subito dopo che il Recaptcha è stato risolto. Per farlo nel momento giusto, ti basta attendere che appaia il selettore .antigate_solver.solved e poi premere Invia.
// attendi che il selettore "risolto" appaia
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 Invia
await Promise.all([
page.click('#submitButton'),
page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('attività completata, modulo con recaptcha superato');
E questo è tutto, il modulo è stato compilato, il Recaptcha risolto e bypassato. Campioni di codice completo:
// 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 chiave 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 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 con il plugin
const browser = await puppeteer.launch();
page = await browser.newPage();
} catch (e) {
console.log('could not launch browser: '+e.toString())
return;
}
// vai alla pagina target
try {
await page.goto(url, {
waitUntil: "networkidle0"
});
} catch (e) {
console.error('err while loading the page: '+e);
}
// disattiva errori di timeout
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);
// attendi che il selettore "risolto" appaia
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 Invia
await Promise.all([
page.click('#submitButton'),
page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('recaptcha risolto');
})();
Bonus: c'è un modo per usare il plugin in modalità headless, poichè Chrome non supporta l'automazione del browser con i plugin. Usa l'utilità chiamata 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
# avvia Xvfb daemon in background (solo una volta)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &
# attendi un pò per farlo apparire (solo una volta)
sleep 5
# aggiungi il prefisso "xvfb-run" allo script "node" o "python"
xvfb-run node myscript.js
# o
xvfb-run python myscript.py