Menu tài liệu

Cách sử dụng Anti-Captcha plugin trong Puppeteer hoặc Selenium

Puppeteer và Selenium là hai công cụ chính để tự động hóa trình duyệt và plugin của chúng tôi tích hợp liền mạch vào hai công cụ này. Trong bài viết này, chúng tôi sẽ hướng dẫn cách sử dụng plugin của chúng tôi trong Puppeteer và Selenium đối với các ngôn ngữ lập trình NodeJS và Python tương ứng. Nếu chọn một trong hai, chúng tôi đặc biệt khuyến nghị sử dụng NodeJS+Puppeteer cho môi trường gốc của nó.

1. Cài đặt các phần phụ thuộc. Đối với NodeJS, chỉ cần cài đặt các gói npm nhất định bên dưới, đối với Python, cài đặt các gói và tải xuống tập tin thực thi "chromedriver" từ trang này. Phiên bản hệ điều hành phải phù hợp với phiên bản Chrome được cài đặt trên hệ thống của bạn.

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

2. Tải xuống plugin phiên bản ZIP dành cho Chrome, giải nén tệp zip này vào thư mục dự án của bạn. Các phiên bản thực tế nằm tại tại đây. Bạn cũng có thể thực hiện việc này theo chương trình:

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 () => {
    // tải xuống plugin
    await new Promise((resolve) => {
        https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
    })
    // giải nén tệp zip đó
    const zip = new AdmZip("./plugin.zip");
    await zip.extractAllTo("./plugin/", true);
})();
        
Python
          import urllib.request
import zipfile

url = 'https://antcpt.com/anticaptcha-plugin.zip'
# tải xuống plugin
filehandle, _ = urllib.request.urlretrieve(url)
# giải nén tệp zip đó
with zipfile.ZipFile(filehandle, "r") as f:
    f.extractall("plugin")
        

3. Tiếp theo, cấu hình khóa API của bạn trong tệp ./plugin/js/config_ac_api_key.js. Bạn có thể thấy khóa API của mình trong khu vực khách hàng. Bạn sẽ cần có số dư tài khoản dương để khóa này hoạt động.

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

# thiết đặt khóa API trong tệp cấu hình
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)))

# nén thư mục plugin lại vào 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. Khởi tạo trình duyệt với plugin. Đối với Puppeteer, chúng tôi khuyến nghị sử dụng plugin 'puppeteer-extra-plugin-stealth' dành cho gói 'puppeteer-extra’. Plugin này giúp ẩn tất cả các dấu hiệu của trình duyệt Chromium tự động trên 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. Điều hướng đến trang đích và điền biểu mẫu nếu cần. Plugin sẽ tự động nhận Recaptcha và bắt đầu giải.

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);
    }
    // tắt lỗi hết thời gian chờ điều hướng
    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. Phần tiếp theo sẽ hơi phức tạp một chút. Biểu mẫu web Một số yêu cầu người dùng nhấn nút gửi sau khi giải xong Recaptcha, .antigate_solver.solved sử dụng callback (gọi lại) và tự động gửi các biểu mẫu. Trong trường hợp thứ nhất, chúng tôi muốn nhấn nút gửi ngay sau khi Recaptcha được giải xong. Để làm được vậy đúng lúc, chỉ cần đợi bộ chọn .antigate_solver.solved xuất hiện rồi nhấn nút gửi.

NodeJS
          // chờ bộ chọn "đã giải" xuất hiện
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('mã recaptcha đã được giải');

// nhấn nút gửi
await Promise.all([
    page.click('#submitButton'),
    page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('tác vụ hoàn tất, biểu mẫu có mã recaptcha đã được vượt qua');
        
Python
          # chờ bộ chọn "đã giải" xuất hiện
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))
# nhấn nút gửi
browser.find_element_by_css_selector('#submitButton').click()
        

Vậy là xong, biểu mẫu được điền, Recaptcha được giải và bị vượt qua. Mẫu về mã đầy đủ:

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 () => {
    // tải xuống plugin
    await new Promise((resolve) => {
        https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
    })
    // giải nén tệp zip đó
    const zip = new AdmZip("./plugin.zip");
    await zip.extractAllTo("./plugin/", true);

    // thiết đặt khóa API trong tệp cấu hình
    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();
        }
    });

    // thiết đặt các tùy chọn khởi chạy trình duyệt
    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 {
        // khởi chạy trình duyệt với plugin
        const browser = await puppeteer.launch();
        page = await browser.newPage();
    } catch (e) {
        console.log('could not launch browser: '+e.toString())
        return;
    }

    // điều hướng đến trang đích
    try {
        await page.goto(url, {
            waitUntil: "networkidle0"
        });
    } catch (e) {
        console.error('err while loading the page: '+e);
    }

    // tắt lỗi hết thời gian chờ điều hướng
    await page.setDefaultNavigationTimeout(0);

    // điền vào biểu mẫu
    await page.$eval('#login', (element, login) => {
        element.value = login;
    }, login);
    await page.$eval('#password', (element, password) => {
        element.value = password;
    }, password);

    // chờ bộ chọn "đã giải" xuất hiện
    await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
    console.log('mã recaptcha đã được giải');

    // nhấn nút gửi
    await Promise.all([
        page.click('#submitButton'),
        page.waitForNavigation({ waitUntil: "networkidle0" })
    ]);
    console.log('mã recaptcha đã được giải');

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

# tải xuống plugin
url = 'https://antcpt.com/anticaptcha-plugin.zip'
filehandle, _ = urllib.request.urlretrieve(url)
# giải nén tệp zip đó
with zipfile.ZipFile(filehandle, "r") as f:
    f.extractall("plugin")

# thiết đặt khóa API trong tệp cấu hình
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)))

# nén thư mục plugin lại vào 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()

# thiết đặt các tùy chọn khởi chạy trình duyệt
options = webdriver.ChromeOptions()
options.add_extension('./plugin.zip')

# thiết đặt các tùy chọn khởi chạy trình duyệt
browser = webdriver.Chrome('./chromedriver', options=options)

# điều hướng đến trang đích
browser.get('https://anti-captcha.com/tutorials/v2-textarea')

# điền vào biểu mẫu
browser.find_element_by_css_selector('#login').send_keys('Test login')
browser.find_element_by_css_selector('#password').send_keys('Test password')

# chờ bộ chọn "đã giải" xuất hiện
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))

# nhấn nút gửi
browser.find_element_by_css_selector('#submitButton').click()
        

Bonus: có một mẹo để chạy plugin ở chế độ headless, vì Chrome không hỗ trợ tự động hóa trình duyệt với plugin. Sử dụng tiện ích Xvfb có chức năng cung cấp màn hình ảo cho ứng dụng của bạn.

bash
          # cài đặt gói
apt-get install -y xvfb

# thiết đặt các biến hiển thị
export DISPLAY=:0

# khởi động Xvfb daemon trong nền (chỉ một lần)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &

# chờ một chút để bộ chọn đó xuất hiện (chỉ một lần)
sleep 5

# thêm prefix "xvfb-run" vào "node” hoặc "python" script
xvfb-run node myscript.js
# hoặc
xvfb-run python myscript.py