Menu dokumentasi

Cara menggunakan plugin Anti-Captcha dalam Puppeteer atau Selenium

Puppeteer dan Selenium adalah dua mesin utama untuk otomatisasi browser dan plugin kami terintegrasi dengan lancar dalam keduanya. Dalam artikel ini, kami akan menunjukkan cara menggunakannya dalam Puppeteer dan Selenium untuk bahasa pemrograman NodeJS dan Python. Jika Anda memilih salah satu dari keduanya, kami sangat menyarankan NodeJS+Puppeteer untuk lingkungan natifnya.

1. Instal dependensi. Untuk NodeJS, instal saja npm package yang diberikan di bawah ini. Untuk Python, instal package dan unduh "chromedriver" yang bisa dieksekusi dari halaman ini. Versi driver harus sesuai dengan versi Chrome yang terinstal di sistem Anda.

NodeJS
          npm install adm-zip puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
        
Python
          pip install selenium
        

2. Unduh plugin dalam versi ZIP untuk Chrome dan unzip ke folder proyek Anda. Versi aktualnya terletak di sini. Anda juga dapat melakukannya secara terprogram:

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

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

3. Selanjutnya, konfigurasi kunci API Anda dalam berkas ./plugin/js/config_ac_api_key.js. Anda dapat menemukan kunci API Anda di area pelanggan. Saldo Anda harus positif agar dapat melakukannya.

NodeJS
          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!')
}
        
Python
          from pathlib import Path
import zipfile

# mengatur kunci API dalam berkas konfigurasi
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)))

# zip direktori plugin kembali ke 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()
        

4. Inisialisasi browser dengan plugin. Untuk Puppeteer, kami menyarankan plugin 'puppeteer-extra-plugin-stealth' untuk 'puppeteer-extra' package, yang menyembunyikan semua tanda dari browser Chromium terotomatisasi web.

NodeJS
          //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();
})();
        
Python
          from selenium import webdriver

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

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

5. Navigasi ke halaman target dan isilah form jika perlu. Plugin akan mengambil Recaptcha secara otomatis dan mulai menyelesaikannya.

NodeJS
          (async () => {
    const url = 'https://anti-captcha.com/tutorials/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);
    }
    // menonaktifkan kesalahan saat waktu navigasi habis
    await page.setDefaultNavigationTimeout(0);

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

})();
        
Python
          browser.get('https://anti-captcha.com/tutorials/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. Selanjutnya adalah bagian yang agak rumit. Beberapa web form mewajibkan pengguna untuk menekan tombol kirim setelah menyelesaikan Recaptcha, sementara lainnya memanfaatkan callback dan mengirimkannya secara otomatis. Dalam kasus pertama, kita ingin menekan tombol kirim tepat setelah Recaptcha diselesaikan. Untuk melakukannya di waktu yang tepat, tunggu saja selector .antigate_solver.solved untuk muncul, lalu tekan tombol kirim.

NodeJS
          // menunggu selector "solved" muncul
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('recaptcha diselesaikan');

// menekan tombol kirim
await Promise.all([
    page.click('#submitButton'),
    page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('tugas selesai, form dengan recaptcha terlewati');
        
Python
          # menunggu selector "solved" muncul
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))
# menekan tombol kirim
browser.find_element_by_css_selector('#submitButton').click()
        

Itu saja. Form sudah terisi, Recaptcha diselesaikan dan terlewati. Contoh kode lengkap:

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

    // mengatur kunci API dalam berkas konfigurasi
    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();
        }
    });

    // mengatur pilihan peluncuran 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 {
        // meluncurkan browser dengan plugin
        const browser = await puppeteer.launch();
        page = await browser.newPage();
    } catch (e) {
        console.log('could not launch browser: '+e.toString())
        return;
    }

    // navigasi ke halaman target
    try {
        await page.goto(url, {
            waitUntil: "networkidle0"
        });
    } catch (e) {
        console.error('err while loading the page: '+e);
    }

    // menonaktifkan kesalahan saat waktu navigasi habis
    await page.setDefaultNavigationTimeout(0);

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

    // menunggu selector "solved" muncul
    await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
    console.log('recaptcha diselesaikan');

    // menekan tombol kirim
    await Promise.all([
        page.click('#submitButton'),
        page.waitForNavigation({ waitUntil: "networkidle0" })
    ]);
    console.log('recaptcha diselesaikan');

})();
        
Python
          import urllib.request
import zipfile
import os
from pathlib import Path
from selenium import webdriver

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

# mengatur kunci API dalam berkas konfigurasi
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)))

# zip direktori plugin kembali ke 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()

# mengatur pilihan peluncuran browser
options = webdriver.ChromeOptions()
options.add_extension('./plugin.zip')

# mengatur pilihan peluncuran browser
browser = webdriver.Chrome('./chromedriver', options=options)

# navigasi ke halaman target
browser.get('https://anti-captcha.com/tutorials/v2-textarea')

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

# menunggu selector "solved" muncul
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))

# menekan tombol kirim
browser.find_element_by_css_selector('#submitButton').click()
        

Bonus: Ada trik untuk menjalankan plugin dalam mode headless karena Chrome tidak mendukung otomatisasi browser dengan plugin. Gunakan utilitas bernama Xvfb yang menyediakan desktop virtual untuk aplikasi Anda.

bash
          # menginstal package
apt-get install -y xvfb

# mengatur variabel tampilan
export DISPLAY=:0

# mulai Xvfb daemon di latar belakang (hanya sekali)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &

# menunggu sebentar untuk membiarkannya muncul (hanya sekali)
sleep 5

# menambahkan prefiks "xvfb-run" ke script "node" atau "python"
xvfb-run node myscript.js
# atau
xvfb-run python myscript.py