نحوه استفاده از پلاگین آنتی کپچا در Puppeteer یا Selenium
Puppeteer و Selenium دو موتور اصلی برای خودکار کردن مرورگر هستند و پلاگین ما به شیوهای بینقص با آنها یکپارچه میشود. در این مقاله نشان خواهیم داد که چگونه از پلاگین ما در Puppeteer و Selenium به ترتیب برای زبانهای برنامهنویسی NodeJS و پایتون استفاده کنید. اگر باید بین این دو گزینه انتخاب کنید، ما شدیداً NodeJS+Puppeteer را برای محیط بومی آن توصیه میکنیم.
1. وابستگیها را نصب کنید. برای NodeJS فقط بستههای npm مشخص شده در زیر را نصب کنید، برای Python، بستهها را نصب کنید و شکل قابلاجرای "chromedriver" را از صفحه این دانلود کنید. نسخه درایور باید با نسخه کروم نصب شده روی سیستمتان تطابق داشته باشد.
npm install adm-zip puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
pip install selenium
2. پلاگین را در نسخه ZIP برای کروم دانلود کنید، آن را در فولدر your project آنزیپ کنید. نسخههای واقعی در اینجا قرار دارند. ضمناً میتوانید این کار را به صورت برنامهریزیشده انجام دهید:
//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 خودتان را در فایل ./plugin/js/config_ac_api_key.js پیکربندی کنید. میتوانید کلید API خودتان را در بخش مشتریان پیدا کنید. موجودیتان باید مثبت باشد تا API کار کند.
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 را در فایل پیکربندی تنظیم کنید
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' توصیه میکنیم، که همه نشانههای مرورگر کرومیوم خودکار-وب را پنهان میکند.
//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. به صفحه هدف بروید و در صورت نیاز فرم را پر کنید. پلاگین به صورت خودکار ریکپچا را انتخاب خواهد کرد و حل کردن آن را شروع میکند.
(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);
}
// خطاهای navigation 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);
})();
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. مرحله بعد کمی فنی و ظریف است. در برخی فرمهای وب لازم است که که کاربر بعد از حل ریکپچا، دکمه ارسال را بزند. سایرین از کالبکها استفاده میکنند و آنها را به صورت خودکار ارسال میکنند. در مورد اول میخواهیم درست بعدازاین که ریکپچا حل شد دکمه ارسال را بزنیم. برای انجام این کار در زمان مناسب، بهسادگی منتظر سلکتور .antigate_solver.solved بمانید تا بالا بیاید و بعد دکمه ارسال را بزنید.
// منتظر بمانید تا سلکتور "solved" بالا بیاید
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('ریکپچا حل شد');
// دکمه ارسال را بزنید
await Promise.all([
page.click('#submitButton'),
page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('وظیفه انجام شد، فرم دارای ریکپچا دور زده شد');
# منتظر بمانید تا سلکتور "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()
کل کار همین بود، فرم پر میشود، ریکپچا حل میشود و سپس دور زده میشود. نمونههای کد کامل:
// 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 را در فایل پیکربندی تنظیم کنید
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);
}
// خطاهای navigation 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);
// منتظر بمانید تا سلکتور "solved" بالا بیاید
await page.waitForSelector('.antigate_solver.solved').catch(error => console.log('failed to wait for the selector'));
console.log('ریکپچا حل شد');
// دکمه ارسال را بزنید
await Promise.all([
page.click('#submitButton'),
page.waitForNavigation({ waitUntil: "networkidle0" })
]);
console.log('ریکپچا حل شد');
})();
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 را در فایل پیکربندی تنظیم کنید
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()
پاداش: یک ترفند برای اجرای پلاگین در حالت بدون سر(هدلس) وجود دارد، زیرا کروم از خودکارسازی مرورگر با پلاگینها پشتیبانی نمیکند. از یوتیلیتی به نام Xvfb استفاده کنید که دسکتاپ مجازی را برای برنامه شما ارائه میکند.
# بسته را نصب کنید
apt-get install -y xvfb
# متغیر نمایش را تنظیم کنید
export DISPLAY=:0
# دامون Xvfb را در پسزمینه آغاز کنید (فقط یکبار)
/usr/bin/Xvfb :0 -screen 0 1024x768x24 &
# کمی منتظر بمانید تا بالا بیاید (فقط یکبار)
sleep 5
# پیشوند "xvfb-run" را به اسکریپت "node" یا "python" اضافه کنید
xvfb-run node myscript.js
# یا
xvfb-run python myscript.py