Menu

Cómo utilizar el plugin AntiCaptcha en Puppeteer o Selenium

Puppeteer y Selenium son los dos motores principales para la automatización del navegador y nuestro plugin se integra perfectamente a ellos. En este artículo, mostraremos cómo usarlo en Puppeteer y Selenium para los lenguajes NodeJS and Python respectivamente. Si debe elegir entre los dos, le recomendamos NodeJS+Puppeteer como su entorno nativo.

1. Instale la dependencias. Para NodeJS simplemente instale los paquetes npm que se suministran a continuación; para Python instale los paquetes y descargue el ejecutable de "chromedriver" de esta página. La versión del driver debe coincidir con la versión de Chrome instalada en su sistema.

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

2. Descargue el plugin en ZIP versión para Chrome, descomprímala en la carpeta de su proyecto. Las versiones actuales están ubicadas aquí. También lo puede hacer a través de un programa:

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 () => {
    // descargue el plugin
    await new Promise((resolve) => {
        https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
    })
    // Descomprímalo
    const zip = new AdmZip("./plugin.zip");
    await zip.extractAllTo("./plugin/", true);
})();
import urllib.request
import zipfile

url = 'https://antcpt.com/anticaptcha-plugin.zip'
# descargue el plugin
filehandle, _ = urllib.request.urlretrieve(url)
# Descomprímalo
with zipfile.ZipFile(filehandle, "r") as f:
    f.extractall("plugin")

3. A continuación, configure la clave de su API en el archivo ./plugin/js/config_ac_api_key.js. Puede encontrar la clave de su API en el área de clientes. Necesita saldo positivo para que funcione.

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. Inicialice el navegador con el plugin. Para Puppeteer recomendamos el plugin 'puppeteer-extra-plugin-stealth' para el paquete 'puppeteer-extra', que oculta todos los recursos de la web automatizada del navegador Chromium.

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. Navegue a la página destino y llene un formulario si es requerido. El plugin reconocerá el Recaptcha automáticamente y comenzará a resolverlo.

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. La siguiente es una parte un poco complicada. Algunos formularios web requieren que el usuario pulse el botón enviar después de resolver el Recaptcha, otros utilizan callbacks y los envían de manera automática. En el primer caso, queremos pulsar el botón enviar justo después de que el Recaptcha se resuelve. Para hacerlo en el momento correcto, simplemente espere a que el selector .antigate_solver.solved aparezca y entonces pulse el botón enviar.

Node.js
Python
// espere a que aparezca el botón "solved" 
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('resuelva el recaptcha');

// presione el botón enviar
await Promise.all([
    page.click('#submitButton'),
    page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('tarea completada, formulario con recaptcha omitido ');
# espere a que aparezca el botón "solved" 
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()

Eso es todo, el formulario se llena, el Recaptcha es resuelto y omitido. Ejemplos de código completos:

Node.js
Python

Cómo integrar la extensión de navegador de Anti-Captcha en 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 () => {
    // descargue el plugin
    await new Promise((resolve) => {
        https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
    })
    // Descomprímalo
    const zip = new AdmZip("./plugin.zip");
    await zip.extractAllTo("./plugin/", true);

    // establezca la clave API en configuración
    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();
        }
    });

    // configure las opciones de inicio del navegador
    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 {
        // inicie el navegador con el plugin
        const browser = await puppeteer.launch();
        page = await browser.newPage();
    } catch (e) {
        console.log('could not launch browser: '+e.toString())
        return;
    }

    // Ingrese a la página de destino
    try {
        await page.goto(url, {
            waitUntil: "networkidle0"
        });
    } catch (e) {
        console.error('err while loading the page: '+e);
    }

    // desactive los errores de tiempo de espera
    await page.setDefaultNavigationTimeout(0);

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

    // espere a que aparezca el botón "solved" 
    await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
    console.log('resuelva el recaptcha');

    // presione el botón enviar
    await Promise.all([
        page.click('#submitButton'),
        page.waitForNavigation({ waitUntil: "networkidle0" })
    ]);
    console.log('resuelva el recaptcha');

})();

Cómo integrar la extensión de navegador de Anti-Captcha en Python

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

# descargue el plugin
url = 'https://antcpt.com/anticaptcha-plugin.zip'
filehandle, _ = urllib.request.urlretrieve(url)
# Descomprímalo
with zipfile.ZipFile(filehandle, "r") as f:
    f.extractall("plugin")

# establezca la clave API en configuración
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)))

# vuelva a comprimir el directorio zip al 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()

# configure las opciones de inicio del navegador
options = webdriver.ChromeOptions()
options.add_extension('./plugin.zip')

# configure las opciones de inicio del navegador
browser = webdriver.Chrome('./chromedriver', options=options)

# Ingrese a la página de destino
browser.get('https://anti-captcha.com/demo/?page=recaptcha_v2_textarea')

# llene el formulario
browser.find_element_by_css_selector('#login').send_keys('Test login')
browser.find_element_by_css_selector('#password').send_keys('Test password')

# espere a que aparezca el botón "solved" 
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))

# presione el botón enviar
browser.find_element_by_css_selector('#submitButton').click()

Bono de regalo: hay un truco para ejecutar el plugin en modo sin cabecera, dado que Chrome no acepta la automatización del navegador sin plugins. Use la herramienta llamada Xvfb que ofrece un escritorio virtual para su aplicación.

Node.js
Python
# instale el paquete
apt-get install -y xvfb

# establezca las variables de visualización
export DISPLAY=:0

# Inicie el Xvfb daemon en segundo plano (solo una vez)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &

# espere un poco a que aparezca (solo una vez)
sleep 5

# agregue el prefijo "xvfb-run" al script "node" o "python"
xvfb-run node myscript.js
# instale el paquete
apt-get install -y xvfb

# establezca las variables de visualización
export DISPLAY=:0

# Inicie el Xvfb daemon en segundo plano (solo una vez)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &

# espere un poco a que aparezca (solo una vez)
sleep 5

# agregue el prefijo "xvfb-run" al script "node" o "python"
xvfb-run python myscript.py