วิธีใช้ปลั๊กอิน Anti-Captcha ใน Puppeteer หรือ Selenium
Puppeteer และ Selenium เป็นเครื่องมือหลักสองอันสำหรับการทำงานอัตโนมัติของเบราว์เซอร์และปลั๊กอินของเราจะรวมเข้าด้วยกันอย่างราบรื่น ในบทความนี้ เราจะแสดงวิธีใช้งานใน Puppeteer และ Selenium สำหรับภาษาโปรแกรม NodeJS และ Python ตามลำดับ หากคุณเลือกต้องการเลือก เราขอแนะนำ NodeJS+Puppeteer สำหรับสภาพแวดล้อมดั้งเดิม
1. ติดตั้ง Dependencies สำหรับ NodeJS เพียงติดตั้งแพ็กเกจ npm ที่ระบุด้านล่าง สำหรับ Python ติดตั้งแพ็กเกจและดาวน์โหลด "chromedriver" ที่เรียกใช้งานได้จากหน้านี้ เวอร์ชันของไดรเวอร์ควรตรงกับเวอร์ชัน Chrome ที่ติดตั้งในระบบของคุณ
npm install adm-zip puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
pip install selenium
2. ดาวน์โหลดปลั๊กอินในเวอร์ชัน ZIP สำหรับ Chrome แล้วแตกไฟล์ลงในโฟลเดอร์โปรเจกต์ของคุณ เวอร์ชันจริงจะอยู่ที่นี่ คุณยังสามารถทำโดยทางโปรแกรม:
//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 () => {
// ดาวน์โหลดปลั๊กอิน
await new Promise((resolve) => {
https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
})
// แตกไฟล์
const zip = new AdmZip("./plugin.zip");
await zip.extractAllTo("./plugin/", true);
})();
import urllib.request
import zipfile
url = 'https://antcpt.com/anticaptcha-plugin.zip'
# ดาวน์โหลดปลั๊กอิน
filehandle, _ = urllib.request.urlretrieve(url)
# แตกไฟล์
with zipfile.ZipFile(filehandle, "r") as f:
f.extractall("plugin")
3. จากนั้น ให้กำหนดค่า API key ของคุณในไฟล์ ./plugin/js/config_ac_api_key.js คุณสามารถค้นหา API key ของคุณได้ในพื้นที่เฉพาะลูกค้า คุณจะต้องมียอดคงเหลือเป็นบวกจึงจะใช้งานได้
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
# ตั้งค่า 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)))
# บีบอัดไดเร็กทอรีปลั๊กอินกลับไปที่ 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. เริ่มต้นเบราว์เซอร์ด้วยปลั๊กอิน สำหรับ Puppeteer เราขอแนะนำปลั๊กอิน 'puppeteer-extra-plugin-stealth' สำหรับแพ็กเกจ 'puppeteer-extra' ซึ่งซ่อนสัญญาณทั้งหมดของเบราว์เซอร์ Chromium แบบอัตโนมัติทางเว็บ
//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. นำทางไปยังหน้าเป้าหมายและกรอกแบบฟอร์มหากต้องการ ปลั๊กอินจะรับและเริ่มแก้ Recaptcha โดยอัตโนมัติ
(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);
}
// ปิดการใช้งานข้อผิดพลาดการหมดเวลาของการนำทาง
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. ถัดไปเป็นส่วนที่ยุ่งยากเล็กน้อย แบบฟอร์มบนเว็บบางรายการต้องการให้ผู้ใช้กดปุ่มส่งหลังจาก Recaptcha ได้รับการแก้ไขแล้ว ส่วนอื่นๆ ใช้การเรียกกลับและส่งโดยอัตโนมัติ ในกรณีแรกเราต้องการกดปุ่มส่งทันทีหลังจากแก้ Recaptcha ได้ หากต้องการทำเช่นนั้นในเวลาที่เหมาะสม เพียงรอให้ตัวเลือก .antigate_solver.solved ปรากฏขึ้นแล้วกดปุ่มส่ง
// รอให้ตัวเลือก "solved" ปรากฏขึ้น
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('แก้ recaptcha แล้ว');
// กดปุ่มส่ง
await Promise.all([
page.click('#submitButton'),
page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('งานเสร็จสมบูรณ์ แบบฟอร์มที่มีการบายพาส recaptcha');
# รอให้ตัวเลือก "solved" ปรากฏขึ้น
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))
# กดปุ่มส่ง
browser.find_element_by_css_selector('#submitButton').click()
กรอกแบบฟอร์มแล้วและ Recaptcha ได้รับการแก้ไขและบายพาสแล้ว แค่นี้แหละ ตัวอย่างโค้ดแบบเต็ม:
// 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 () => {
// ดาวน์โหลดปลั๊กอิน
await new Promise((resolve) => {
https.get(pluginURL, resp => resp.pipe(fs.createWriteStream('./plugin.zip').on('close', resolve)));
})
// แตกไฟล์
const zip = new AdmZip("./plugin.zip");
await zip.extractAllTo("./plugin/", true);
// ตั้งค่า API key ในไฟล์กำหนดค่า
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();
}
});
// ตั้งค่าตัวเลือกการเปิดใช้เบราว์เซอร์
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 {
// เปิดเบราว์เซอร์ด้วยปลั๊กอิน
const browser = await puppeteer.launch();
page = await browser.newPage();
} catch (e) {
console.log('could not launch browser: '+e.toString())
return;
}
// นำทางไปยังหน้าเป้าหมาย
try {
await page.goto(url, {
waitUntil: "networkidle0"
});
} catch (e) {
console.error('err while loading the page: '+e);
}
// ปิดการใช้งานข้อผิดพลาดการหมดเวลาของการนำทาง
await page.setDefaultNavigationTimeout(0);
// กรอกแบบฟอร์ม
await page.$eval('#login', (element, login) => {
element.value = login;
}, login);
await page.$eval('#password', (element, password) => {
element.value = password;
}, password);
// รอให้ตัวเลือก "solved" ปรากฏขึ้น
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('แก้ recaptcha แล้ว');
// กดปุ่มส่ง
await Promise.all([
page.click('#submitButton'),
page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('แก้ recaptcha แล้ว');
})();
import urllib.request
import zipfile
import os
from pathlib import Path
from selenium import webdriver
# ดาวน์โหลดปลั๊กอิน
url = 'https://antcpt.com/anticaptcha-plugin.zip'
filehandle, _ = urllib.request.urlretrieve(url)
# แตกไฟล์
with zipfile.ZipFile(filehandle, "r") as f:
f.extractall("plugin")
# ตั้งค่า API key ในไฟล์กำหนดค่า
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)))
# บีบอัดไดเร็กทอรีปลั๊กอินกลับไปที่ 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()
# ตั้งค่าตัวเลือกการเปิดใช้เบราว์เซอร์
options = webdriver.ChromeOptions()
options.add_extension('./plugin.zip')
# ตั้งค่าตัวเลือกการเปิดใช้เบราว์เซอร์
browser = webdriver.Chrome('./chromedriver', options=options)
# นำทางไปยังหน้าเป้าหมาย
browser.get('https://anti-captcha.com/demo/?page=recaptcha_v2_textarea')
# กรอกแบบฟอร์ม
browser.find_element_by_css_selector('#login').send_keys('Test login')
browser.find_element_by_css_selector('#password').send_keys('Test password')
# รอให้ตัวเลือก "solved" ปรากฏขึ้น
webdriver.support.wait.WebDriverWait(browser, 120).until(lambda x: x.find_element_by_css_selector('.antigate_solver.solved'))
# กดปุ่มส่ง
browser.find_element_by_css_selector('#submitButton').click()
โบนัส: มีเคล็ดลับในการเรียกใช้ปลั๊กอินในโหมด Headless เนื่องจาก Chrome ไม่สนับสนุนการทำงานอัตโนมัติของเบราว์เซอร์ด้วยปลั๊กอิน ใช้ยูทิลิตีชื่อ Xvfb ซึ่งมีเดสก์ท็อปเสมือนสำหรับแอปพลิเคชันของคุณ
# ติดตั้งแพ็กเกจ
apt-get install -y xvfb
# ตั้งค่าตัวแปรการแสดงผล
export DISPLAY=:0
# เริ่ม Xvfb daemon ในเบื้องหลัง (เพียงครั้งเดียว)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &
# รอสักครู่ให้ปรากฏขึ้น (เพียงครั้งเดียว)
sleep 5
# เพิ่มคำนำหน้า "xvfb-run" ให้กับสคริปต์ "node" หรือ "python"
xvfb-run node myscript.js
# หรือ
xvfb-run python myscript.py