دليل كامل لإخفاء Selenium و Puppeteer عن الكشف
أنظمة حماية البوت الحديثة تتعرف بسهولة على المتصفحات الآلية من خلال عشرات العلامات: من متغيرات JavaScript إلى ميزات سلوك WebDriver. تستخدم المواقع Cloudflare و DataDome و PerimeterX وحلولها الخاصة التي تمنع حتى 90% من الطلبات من Selenium و Puppeteer في التكوين القياسي.
في هذا الدليل، سنستعرض جميع طرق إخفاء الأتمتة: من الإعدادات الأساسية إلى تقنيات متقدمة لتجاوز الكشف. ستحصل على حلول جاهزة مع أمثلة على الشيفرة لـ Python و Node.js، والتي تعمل ضد معظم أنظمة الحماية.
كيف تكتشف المواقع الأتمتة
تقوم أنظمة حماية البوت بتحليل المتصفح بناءً على مجموعة من المعايير في آن واحد. حتى إذا قمت بإخفاء علامة واحدة، فإن البقية ستكشف الأتمتة. فهم جميع طرق الكشف هو المفتاح لإخفاء فعال.
مؤشرات WebDriver
أبسط طريقة للكشف هي التحقق من متغيرات JavaScript التي توجد فقط في المتصفحات الآلية:
// هذه المتغيرات تكشف Selenium/Puppeteer
navigator.webdriver === true
window.navigator.webdriver === true
document.$cdc_ // متغير محدد لـ ChromeDriver
window.document.documentElement.getAttribute("webdriver")
navigator.plugins.length === 0 // المتصفحات الآلية لا تحتوي على إضافات
navigator.languages === "" // قائمة اللغات فارغة
تتحقق Cloudflare والأنظمة المماثلة من هذه الخصائص في المقام الأول. إذا كانت واحدة على الأقل تعود بنتيجة إيجابية - يتم حظر الطلب.
بصمة المتصفح
تقوم الأنظمة المتقدمة بإنشاء بصمة فريدة للمتصفح بناءً على عشرات المعايير:
- بصمة Canvas - رسم صور مخفية وتحليل بيانات البكسل
- بصمة WebGL - معلمات وحدة معالجة الرسوميات وبطاقة الفيديو
- سياق الصوت - خصائص فريدة لمعالجة الصوت
- بصمة الخطوط - قائمة الخطوط المثبتة في النظام
- دقة الشاشة - دقة الشاشة، عمق اللون، المنطقة المتاحة
- المنطقة الزمنية واللغة - المنطقة الزمنية، لغات المتصفح، إعدادات النظام
غالبًا ما تحتوي المتصفحات الآلية على تركيبات غير نمطية من هذه المعايير. على سبيل المثال، لا تحتوي Chrome Headless على إضافات، لكنها تدعم WebGL - مثل هذه التركيبة نادرة جدًا بين المستخدمين الحقيقيين.
التحليل السلوكي
تتبع الأنظمة الحديثة أنماط السلوك:
- حركات الماوس - تتحرك الروبوتات المؤشر في خطوط مستقيمة أو لا تتحرك على الإطلاق
- سرعة الإجراءات - ملء النماذج بشكل فوري، سرعة نقر غير بشرية
- أنماط التمرير - قفزات حادة بدلاً من التمرير السلس
- أحداث لوحة المفاتيح - عدم وجود تأخيرات طبيعية بين النقرات
- تكرار الطلبات - فترات منتظمة جدًا بين الإجراءات
مهم: تستخدم DataDome و PerimeterX التعلم الآلي لتحليل السلوك. تم تدريبها على ملايين الجلسات ويمكنها التعرف على الروبوت حتى عند إخفاء المعلمات التقنية بشكل صحيح، إذا بدا السلوك غير طبيعي.
إخفاء Selenium الأساسي
يترك Selenium WebDriver في التكوين القياسي العديد من الآثار. دعونا نستعرض إعدادًا خطوة بخطوة لتقليل الكشف باستخدام Python و ChromeDriver.
تعطيل علامة webdriver
الخطوة الأولى هي إخفاء المتغير navigator.webdriver. يتم ذلك من خلال بروتوكول أدوات مطوري Chrome:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
# إعداد خيارات Chrome
chrome_options = Options()
# تعطيل علامة الأتمتة
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# إنشاء السائق
driver = webdriver.Chrome(options=chrome_options)
# إزالة webdriver عبر CDP
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
'''
})
driver.get('https://example.com')
إعداد User-Agent وغيرها من الرؤوس
غالبًا ما تستخدم المتصفحات الخفية سلاسل User-Agent قديمة أو محددة. من الضروري تعيين User-Agent حديث لمتصفح حقيقي:
# User-Agent حديث لـ Chrome على Windows
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
chrome_options.add_argument(f'user-agent={user_agent}')
# إضافات أخرى لإخفاء
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-gpu')
# حجم النافذة مثل المستخدم الحقيقي
chrome_options.add_argument('--window-size=1920,1080')
chrome_options.add_argument('--start-maximized')
إضافة إضافات ولغات
لا تحتوي المتصفحات الآلية على إضافات وغالبًا ما تظهر قائمة اللغات فارغة. نقوم بإصلاح ذلك عبر CDP:
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en', 'ru']
});
Object.defineProperty(navigator, 'plugins', {
get: () => [
{
0: {type: "application/x-google-chrome-pdf", suffixes: "pdf", description: "Portable Document Format"},
description: "Portable Document Format",
filename: "internal-pdf-viewer",
length: 1,
name: "Chrome PDF Plugin"
},
{
0: {type: "application/pdf", suffixes: "pdf", description: ""},
description: "",
filename: "mhjfbmdgcfjbbpaeojofohoefgiehjai",
length: 1,
name: "Chrome PDF Viewer"
}
]
});
Object.defineProperty(navigator, 'platform', {
get: () => 'Win32'
});
'''
})
مثال كامل لإعداد Selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import random
def create_stealth_driver():
chrome_options = Options()
# إعدادات أساسية للإخفاء
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
# User-Agent
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
chrome_options.add_argument(f'user-agent={user_agent}')
# حجم النافذة
chrome_options.add_argument('--window-size=1920,1080')
chrome_options.add_argument('--start-maximized')
driver = webdriver.Chrome(options=chrome_options)
# سكربت الإخفاء عبر CDP
stealth_script = '''
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});
Object.defineProperty(navigator, 'platform', {get: () => 'Win32'});
window.chrome = {
runtime: {}
};
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5]
});
'''
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': stealth_script
})
return driver
# الاستخدام
driver = create_stealth_driver()
driver.get('https://bot.sannysoft.com/') # موقع لاختبار الكشف
إعداد Puppeteer لتجاوز الكشف
تواجه Puppeteer نفس مشاكل الكشف مثل Selenium. ومع ذلك، توجد مكتبة جاهزة لـ Node.js تُدعى puppeteer-extra-plugin-stealth، والتي تقوم بأتمتة معظم إعدادات الإخفاء.
تثبيت puppeteer-extra
npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
التكوين الأساسي مع الإضافة stealth
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
// إضافة إضافة الإخفاء
puppeteer.use(StealthPlugin());
(async () => {
const browser = await puppeteer.launch({
headless: 'new', // وضع headless الجديد لـ Chrome
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu',
'--window-size=1920,1080',
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process'
]
});
const page = await browser.newPage();
// تعيين viewport
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1
});
// تعيين User-Agent
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
// رؤوس إضافية
await page.setExtraHTTPHeaders({
'Accept-Language': 'en-US,en;q=0.9',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
});
await page.goto('https://bot.sannysoft.com/');
// لقطة للتحقق
await page.screenshot({ path: 'test.png' });
await browser.close();
})();
الإعداد اليدوي بدون إضافات
إذا كنت ترغب في السيطرة الكاملة أو لا يمكنك استخدام مكتبات خارجية، قم بإعداد الإخفاء يدويًا:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
// إعادة تعريف webdriver وخصائص أخرى
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en']
});
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5]
});
// إخفاء Chrome headless
Object.defineProperty(navigator, 'platform', {
get: () => 'Win32'
});
window.chrome = {
runtime: {}
};
// إعادة تعريف الأذونات
const originalQuery = window.navigator.permissions.query;
window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
});
await page.goto('https://example.com');
await browser.close();
})();
إعداد لتجاوز Cloudflare
تستخدم Cloudflare طرق الكشف المتقدمة. لتجاوزها، من الضروري إضافة تأخيرات عشوائية ومحاكاة الإجراءات:
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
async function bypassCloudflare(url) {
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-web-security'
]
});
const page = await browser.newPage();
// User-Agent عشوائي
const userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
];
await page.setUserAgent(userAgents[Math.floor(Math.random() * userAgents.length)]);
// الانتقال إلى الصفحة
await page.goto(url, { waitUntil: 'networkidle2' });
// الانتظار للتحقق من Cloudflare (عادة 5-10 ثواني)
await page.waitForTimeout(8000);
// حركة ماوس عشوائية
await page.mouse.move(100, 100);
await page.mouse.move(200, 200);
const content = await page.content();
await browser.close();
return content;
}
مكافحة بصمة JavaScript
بصمة JavaScript هي إنشاء بصمة فريدة للمتصفح بناءً على العديد من المعايير. حتى إذا قمت بإخفاء webdriver، تقوم الأنظمة بتحليل المئات من الخصائص الأخرى لكشف الأتمتة.
الاتجاهات الرئيسية للبصمة
تتحقق أنظمة حماية البوت من المعايير التالية:
| المعيار | ما يتم التحقق منه | خطر الكشف |
|---|---|---|
| navigator.webdriver | وجود علامة الأتمتة | حرج |
| navigator.plugins | عدد وأنواع الإضافات | مرتفع |
| window.chrome | وجود واجهة برمجة تطبيقات Chrome | متوسط |
| navigator.permissions | واجهة برمجة تطبيقات أذونات المتصفح | متوسط |
| screen.colorDepth | عمق لون الشاشة | منخفض |
| navigator.hardwareConcurrency | عدد أنوية المعالج | منخفض |
سكربت إخفاء شامل
السكربت أدناه يعيد تعريف معظم الخصائص المسببة للمشاكل. قم بإدراجه عبر CDP (Selenium) أو evaluateOnNewDocument (Puppeteer):
const stealthScript = `
// إزالة webdriver
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
// إضافة كائن chrome
window.chrome = {
runtime: {},
loadTimes: function() {},
csi: function() {},
app: {}
};
// إعادة تعريف الأذونات
const originalQuery = window.navigator.permissions.query;
window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
// إخفاء الإضافات
Object.defineProperty(navigator, 'plugins', {
get: () => {
return [
{
0: {type: "application/x-google-chrome-pdf", suffixes: "pdf"},
description: "Portable Document Format",
filename: "internal-pdf-viewer",
length: 1,
name: "Chrome PDF Plugin"
},
{
0: {type: "application/pdf", suffixes: "pdf"},
description: "Portable Document Format",
filename: "internal-pdf-viewer",
length: 1,
name: "Chrome PDF Viewer"
},
{
0: {type: "application/x-nacl"},
description: "Native Client Executable",
filename: "internal-nacl-plugin",
length: 2,
name: "Native Client"
}
];
}
});
// اللغات
Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en']
});
// النظام
Object.defineProperty(navigator, 'platform', {
get: () => 'Win32'
});
// البائع
Object.defineProperty(navigator, 'vendor', {
get: () => 'Google Inc.'
});
// إزالة آثار Selenium
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;
// واجهة برمجة تطبيقات البطارية (غير موجودة في headless)
if (!navigator.getBattery) {
navigator.getBattery = () => Promise.resolve({
charging: true,
chargingTime: 0,
dischargingTime: Infinity,
level: 1
});
}
`;
إزالة خصائص WebDriver
يضيف ChromeDriver وغيرها من تطبيقات WebDriver متغيرات محددة إلى النطاق العالمي. تبدأ هذه المتغيرات بالبادئة cdc_ ويسهل اكتشافها من قبل أنظمة الحماية.
اكتشاف متغيرات cdc
يمكن التحقق من وجود هذه المتغيرات باستخدام سكربت بسيط:
// البحث عن جميع متغيرات cdc
for (let key in window) {
if (key.includes('cdc_')) {
console.log('تم اكتشاف متغير WebDriver:', key);
}
}
// المتغيرات النموذجية لـ ChromeDriver:
// cdc_adoQpoasnfa76pfcZLmcfl_Array
// cdc_adoQpoasnfa76pfcZLmcfl_Promise
// cdc_adoQpoasnfa76pfcZLmcfl_Symbol
// $cdc_asdjflasutopfhvcZLmcfl_
الطريقة 1: الإزالة عبر CDP
الطريقة الأكثر موثوقية هي إزالة المتغيرات قبل تحميل الصفحة عبر بروتوكول أدوات مطوري Chrome:
from selenium import webdriver
driver = webdriver.Chrome()
# إزالة جميع متغيرات cdc
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
// إزالة متغيرات cdc المعروفة
const cdcProps = [
'cdc_adoQpoasnfa76pfcZLmcfl_Array',
'cdc_adoQpoasnfa76pfcZLmcfl_Promise',
'cdc_adoQpoasnfa76pfcZLmcfl_Symbol',
'$cdc_asdjflasutopfhvcZLmcfl_'
];
cdcProps.forEach(prop => {
delete window[prop];
});
// إزالة جميع المتغيرات التي تحتوي على 'cdc_'
Object.keys(window).forEach(key => {
if (key.includes('cdc_') || key.includes('$cdc_')) {
delete window[key];
}
});
'''
})
الطريقة 2: تعديل ChromeDriver
نهج أكثر جذرية هو تعديل الملف الثنائي لـ ChromeDriver، واستبدال السلسلة cdc_ بسلسلة رموز أخرى. يمنع هذا إنشاء هذه المتغيرات:
import re
def patch_chromedriver(driver_path):
"""
يقوم بتعديل ChromeDriver، مستبدلاً 'cdc_' بسلسلة عشوائية
"""
with open(driver_path, 'rb') as f:
content = f.read()
# استبدال جميع ظهورات 'cdc_' بـ 'dog_' (أو أي سلسلة أخرى بنفس الطول)
patched = content.replace(b'cdc_', b'dog_')
with open(driver_path, 'wb') as f:
f.write(patched)
print(f'تم تعديل ChromeDriver: {driver_path}')
# الاستخدام
patch_chromedriver('/path/to/chromedriver')
تحذير: قد يؤدي تعديل الملف الثنائي لـ ChromeDriver إلى تعطيل عمله. تأكد دائمًا من عمل نسخة احتياطية قبل التعديل. لا تعمل هذه الطريقة مع جميع إصدارات ChromeDriver.
الطريقة 3: استخدام undetected-chromedriver
تقوم مكتبة undetected-chromedriver بتعديل ChromeDriver تلقائيًا عند التشغيل:
pip install undetected-chromedriver
import undetected_chromedriver as uc
# إنشاء سائق مع تعديل تلقائي
driver = uc.Chrome()
driver.get('https://nowsecure.nl/') # موقع لاختبار الكشف
input('اضغط Enter للإغلاق...')
driver.quit()
إخفاء Canvas و WebGL و Audio API
تعتبر بصمة Canvas و WebGL و Audio طرقًا لإنشاء بصمة فريدة بناءً على ميزات رسم الرسوميات ومعالجة الصوت. تعطي كل تركيبة من المتصفح ونظام التشغيل والأجهزة نتيجة فريدة.
بصمة Canvas
تقوم الأنظمة برسم صورة مخفية على Canvas وتحليل البكسلات الناتجة. غالبًا ما تعطي المتصفحات الخفية نتائج غير نمطية بسبب عدم وجود تسريع GPU.
// كود نموذجي لبصمة Canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = '14px Arial';
ctx.fillText('بصمة المتصفح', 2, 2);
const fingerprint = canvas.toDataURL();
لحماية نفسك، يمكنك إضافة ضوضاء عشوائية إلى واجهة برمجة تطبيقات Canvas:
const canvasNoiseScript = `
// إضافة ضوضاء عشوائية إلى Canvas
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
const originalToBlob = HTMLCanvasElement.prototype.toBlob;
const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
// وظيفة إضافة الضوضاء
const addNoise = (canvas, context) => {
const imageData = originalGetImageData.call(context, 0, 0, canvas.width, canvas.height);
for (let i = 0; i < imageData.data.length; i += 4) {
// إضافة ضوضاء بسيطة إلى RGB (غير ملحوظة للعين)
imageData.data[i] += Math.floor(Math.random() * 3) - 1;
imageData.data[i + 1] += Math.floor(Math.random() * 3) - 1;
imageData.data[i + 2] += Math.floor(Math.random() * 3) - 1;
}
context.putImageData(imageData, 0, 0);
};
// إعادة تعريف toDataURL
HTMLCanvasElement.prototype.toDataURL = function() {
if (this.width > 0 && this.height > 0) {
const context = this.getContext('2d');
addNoise(this, context);
}
return originalToDataURL.apply(this, arguments);
};
`;
بصمة WebGL
يوفر WebGL معلومات حول بطاقة الفيديو وبرامج التشغيل. غالبًا ما تظهر المتصفحات الخفية SwiftShader (مُعالج رسومي برمجي) بدلاً من GPU الحقيقي:
const webglMaskScript = `
// إخفاء معلمات WebGL
const getParameter = WebGLRenderingContext.prototype.getParameter;
WebGLRenderingContext.prototype.getParameter = function(parameter) {
// UNMASKED_VENDOR_WEBGL
if (parameter === 37445) {
return 'Intel Inc.';
}
// UNMASKED_RENDERER_WEBGL
if (parameter === 37446) {
return 'محرك Intel Iris OpenGL';
}
return getParameter.call(this, parameter);
};
// أيضًا لـ WebGL2
if (typeof WebGL2RenderingContext !== 'undefined') {
const getParameter2 = WebGL2RenderingContext.prototype.getParameter;
WebGL2RenderingContext.prototype.getParameter = function(parameter) {
if (parameter === 37445) {
return 'Intel Inc.';
}
if (parameter === 37446) {
return 'محرك Intel Iris OpenGL';
}
return getParameter2.call(this, parameter);
};
}
`;
بصمة سياق الصوت
توفر واجهة برمجة تطبيقات الصوت أيضًا بصمة فريدة. نضيف ضوضاء إلى معالجة الصوت:
const audioMaskScript = `
// إضافة ضوضاء إلى سياق الصوت
const AudioContext = window.AudioContext || window.webkitAudioContext;
if (AudioContext) {
const originalCreateAnalyser = AudioContext.prototype.createAnalyser;
AudioContext.prototype.createAnalyser = function() {
const analyser = originalCreateAnalyser.call(this);
const originalGetFloatFrequencyData = analyser.getFloatFrequencyData;
analyser.getFloatFrequencyData = function(array) {
originalGetFloatFrequencyData.call(this, array);
// إضافة ضوضاء بسيطة
for (let i = 0; i < array.length; i++) {
array[i] += Math.random() * 0.0001;
}
};
return analyser;
};
}
`;
محاكاة سلوك الإنسان
حتى مع إخفاء تقني مثالي، تكشف الروبوتات نفسها من خلال سلوكها. تقوم أنظمة التعلم الآلي بتحليل أنماط حركات الماوس، سرعة الإجراءات وتسلسل الأحداث.
تأخيرات عشوائية بين الإجراءات
لا تستخدم أبدًا تأخيرات ثابتة. يقوم المستخدمون الحقيقيون بأخذ فترات راحة لمدة مختلفة:
import random
import time
def human_delay(min_seconds=1, max_seconds=3):
"""تأخير عشوائي يحاكي الإنسان"""
delay = random.uniform(min_seconds, max_seconds)
time.sleep(delay)
# الاستخدام
driver.get('https://example.com')
human_delay(2, 4) # فترة راحة من 2 إلى 4 ثواني
element = driver.find_element(By.ID, 'search')
human_delay(0.5, 1.5) # فترة راحة قصيرة قبل الإدخال
element.send_keys('search query')
human_delay(1, 2)
حركة ماوس سلسة
تتحرك الروبوتات الماوس في خطوط مستقيمة أو تنقل المؤشر. يقوم المستخدمون الحقيقيون بإنشاء مسارات منحنية مع تسارع وتباطؤ:
// Puppeteer: حركة ماوس سلسة
async function humanMouseMove(page, targetX, targetY) {
const steps = 25; // عدد النقاط الوسيطة
const currentPos = await page.evaluate(() => ({
x: window.mouseX || 0,
y: window.mouseY || 0
}));
for (let i = 0; i <= steps; i++) {
const t = i / steps;
// استخدام easing للنعومة
const ease = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
const x = currentPos.x + (targetX - currentPos.x) * ease;
const y = currentPos.y + (targetY - currentPos.y) * ease;
await page.mouse.move(x, y);
await page.waitForTimeout(Math.random() * 10 + 5);
}
// حفظ الموضع
await page.evaluate((x, y) => {
window.mouseX = x;
window.mouseY = y;
}, targetX, targetY);
}
// الاستخدام
await humanMouseMove(page, 500, 300);
await page.mouse.click(500, 300);
تمرير طبيعي
يقوم المستخدمون الحقيقيون بالتمرير بسلاسة، مع توقفات لقراءة المحتوى:
async function humanScroll(page) {
const scrollHeight = await page.evaluate(() => document.body.scrollHeight);
const viewportHeight = await page.evaluate(() => window.innerHeight);
let currentPosition = 0;
while (currentPosition < scrollHeight - viewportHeight) {
// خطوة تمرير عشوائية (200-500px)
const scrollStep = Math.floor(Math.random() * 300) + 200;
currentPosition += scrollStep;
// تمرير سلس
await page.evaluate((pos) => {
window.scrollTo({
top: pos,
behavior: 'smooth'
});
}, currentPosition);
// فترة راحة لـ "قراءة" المحتوى (1-3 ثواني)
await page.waitForTimeout(Math.random() * 2000 + 1000);
}
}
// الاستخدام
await page.goto('https://example.com');
await humanScroll(page);
إدخال نص طبيعي
يكتب الناس بسرعات مختلفة، ويقومون بالأخطاء ويصححونها:
async function humanTypeText(page, selector, text) {
await page.click(selector);
for (let char of text) {
// تأخير عشوائي بين النقرات (50-200ms)
const delay = Math.random() * 150 + 50;
await page.waitForTimeout(delay);
// 5% فرصة لخطأ مطبعي
if (Math.random() < 0.05) {
// كتابة حرف عشوائي
const wrongChar = String.fromCharCode(97 + Math.floor(Math.random() * 26));
await page.keyboard.type(wrongChar);
await page.waitForTimeout(100 + Math.random() * 100);
// حذف (Backspace)
await page.keyboard.press('Backspace');
await page.waitForTimeout(50 + Math.random() * 50);
}
await page.keyboard.type(char);
}
}
// الاستخدام
await humanTypeText(page, '#search-input', 'example search query');
دمج البروكسي لتحقيق الخصوصية الكاملة
إن إخفاء المتصفح غير مجدي إذا كانت جميع الطلبات تأتي من عنوان IP واحد. تقوم أنظمة حماية البوت بتتبع عدد الطلبات من كل IP وتمنع النشاط المشبوه. البروكسي هو عنصر أساسي في أي أتمتة جدية.
اختيار نوع البروكسي
تتطلب المهام المختلفة أنواعًا مختلفة من البروكسي:
| نوع البروكسي | المزايا | الاستخدام |
|---|---|---|
| بروكسي عادي | سهل الاستخدام، مناسب للعديد من المهام | تصفح عادي، أتمتة بسيطة |
| بروكسي سكني | يبدو كأنه مستخدم حقيقي، أقل عرضة للحظر | أتمتة معقدة، تجميع البيانات |
| بروكسي مخصص | تحكم كامل، سرعة عالية | مشاريع كبيرة، أتمتة متقدمة |
مكتبات وأدوات جاهزة
هناك العديد من المكتبات والأدوات التي يمكن أن تساعدك في إخفاء الأتمتة:
- puppeteer-extra - مكتبة لـ Puppeteer مع إضافات للإخفاء
- undetected-chromedriver - مكتبة لتجاوز الكشف عن ChromeDriver
- selenium-stealth - مكتبة لإخفاء Selenium
- proxy-rotation - مكتبة لإدارة البروكسيات
اختبار مستوى الكشف
من المهم اختبار مستوى الكشف بعد إعداد الإخفاء. يمكنك استخدام أدوات مثل:
- bot.sannysoft.com - موقع لاختبار الكشف عن الروبوتات
- browserleaks.com - أداة لتحليل بصمة المتصفح
- whoer.net - اختبار IP والبروكسي
الخاتمة
إخفاء استخدام Selenium و Puppeteer يتطلب فهمًا عميقًا لأساليب الكشف. باستخدام التقنيات والأدوات الصحيحة، يمكنك تقليل فرص اكتشاف الأتمتة بشكل كبير.