"אנטי־דטקציה" זה לא feature אחת. זה ערימה של 20+ שכבות הגנה שכל אחת מהן עוצרת sector ספציפי של זיהוי, וביחד הן מאפשרות לבוט פייסבוק לרוץ חודשים בלי שייתפס. במאמר הזה אני אפרק את הערימה השלמה שאנחנו ב־BuzzPost בנינו לאורך 4 שנים, עם דוגמאות קוד וערכים מספריים שניתן ליישם.
זה לא "טיפים כלליים". זה הספציפיקציה ההנדסית שמאחורי מערכת שמטפלת ב־150+ חשבונות במקביל בלי שאף אחד יישבר.
שכבה 1: User-Agent consistency
ה־UA הוא ה־first impression של הבוט שלך. ב־BuzzPost אנחנו משתמשים ב־UA אמיתי של Chrome האחרון על Windows:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36
שלוש הוראות עיקריות:
- אותו UA תמיד. החלפה בין sessions = checkpoint.
- UA אמיתי, לא מומצא. Facebook משווה ל־database של UAs ידועים.
- UA שמתאים ל־OS אמיתי של ה־VDS. אם אתה רץ על Windows VDS — UA של Windows. לא של macOS.
כש־Chrome מתעדכן (פעם בחודש בערך), ה־UA קצת משתנה. אנחנו מעקבים את ה־update הזה ולא מנסים להישאר על UA ישן — כי גם UA ישן מדי מעלה דגל. שמאל זהב: לעולם UA לא יותר ישן מ־3 חודשים מהגרסה הנוכחית של Chrome.
שכבה 2: viewport ו־window size
ה־default שלנו: 1366×768. למה? כי זה הרזולוציה הכי נפוצה של מסך Windows. ~22% ממסכי Windows ב־2026 הם 1366×768. אם הבוט שלך רץ ב־1920×1080, אתה במיעוט, וזה ספאם signal.
הגדרת window size:
chrome.exe --window-size=1366,768 --window-position=0,0
חשוב: window.outerWidth/outerHeight צריכים להיות 1366/768, אבל window.innerWidth/innerHeight מעט קטנים יותר (כי יש toolbar). זה ה־ratio הטבעי שפייסבוק מצפה.
רנדומיזציה מלצדית: לא רנדמיזציה של ה־window size עצמו (זה fingerprint signal), אלא של ה־scroll position — לפעמים גלילה למטה לפני פעולה.
שכבה 3: locale ו־timezone
קריטי לישראל: lang=he-IL ב־Chrome ו־timezone Asia/Jerusalem ב־OS. ערכים אלה נחשפים בכמה דרכים:
navigator.language— מקבל את ה־lang flag.navigator.languages— array, default["he-IL", "he", "en-US", "en"].Intl.DateTimeFormat().resolvedOptions().timeZone—"Asia/Jerusalem".- HTTP header
Accept-Language: he-IL,he;q=0.9,en-US;q=0.8,en;q=0.7.
חשבון פייסבוק ישראלי שמתחבר עם Accept-Language: ru-RU = signal חזק שמשהו לא בסדר. אצלנו ב־BuzzPost ה־locale נקבע פעם אחת בעת הקמת ה־VDS וקבוע לכל החיים.
שכבה 4: WebGL ו־Canvas fingerprint
כפי שפירטתי במאמר headless vs visible, fingerprint של WebGL הוא נקודת זיהוי קריטית. ב־VDS visible:
- אנחנו לא מעבירים
--disable-gpu. - אנחנו לא משתמשים בכל "anti-fingerprinting" extension שמשנה את ה־renderer (זה פוגע).
- אנחנו תומכים ב־GPU של Hyper-V/KVM שמספק WebGL אורגני.
Canvas fingerprint: גם הוא אורגני. נגזר מ־GPU וה־OS, ולא מוסטה.
שכבה 5: רנדומיזציה של delays
זה אחד התקפים החשובים ב־anti-detection. בין כל שתי פעולות של הבוט, יש delay רנדומי של 8-22 שניות. למה הטווח הזה?
- פחות מ־5 שניות = bot מובהק. אדם לא יכול לעבד מסך + לקרוא + ללחוץ במהירות הזו.
- יותר מ־30 שניות = idle session, נראה חשוד (למה משתמש פתח קבוצה ולא עשה כלום 30 שניות?).
- 8-22 שניות = הטווח הטבעי של אדם שגולל קבוצה, קורא כותרת, מחליט לפרסם.
הקוד אצלנו:
import random, time
def human_pause():
seconds = random.uniform(8, 22)
time.sleep(seconds)שיפור נוסף: התפלגות לא־אחידה. רוב הפעמים 10-14 שניות, אבל לפעמים 20+. זה מקרב את ה־distribution לאמת אנושית.
שכבה 6: timing של key-press
כשהבוט "מקליד" טקסט, הוא לא מדביק את כל הטקסט בבת אחת (send_keys ב־selenium מדביק "מיידי", וזה bot signal). במקום זה: קלידה תו אחר תו, 50-150ms בין מקשים.
def human_type(element, text):
for ch in text:
element.send_keys(ch)
time.sleep(random.uniform(0.05, 0.15))למה 50-150ms? זה הטווח של מהירות הקלדה רגילה (60-100 WPM). פחות מ־50ms = bot. יותר מ־200ms = הקלדה בעיניים סגורות.
שיפור: מדי פעם backspace + תיקון, או pause של 0.5-1s באמצע משפט. נראה אנושי באמת.
שכבה 7: mouse paths (Bezier curves, לא lines)
זה שכבה שרוב הבוטים מתעלמים ממנה. כשהבוט "מזיז את העכבר" ל־button, האם הוא עובר ב־קו ישר? אדם לא עושה את זה.
אדם מזיז את העכבר ב־Bezier curve: מתחיל לאט, מאיץ באמצע, מאט בסוף. הקוד שלנו מחשב נקודות שליטה (control points) רנדומיות ומבצע את התנועה ב־~30 frames של 16ms כל אחד (60fps).
def move_mouse_bezier(driver, target_x, target_y):
# Compute Bezier path with random control points
ActionChains(driver).move_to_element_with_offset(...)
# ... 30 micro-movements over 500ms
passאם פייסבוק מקשיבה לאירועי mousemove (היא כן), היא רואה את ההבדל. בוטים נאיביים שעוברים בקו ישר מסומנים תוך 5 פעולות.
שכבה 8: scroll patterns
אדם שגולל פיד פייסבוק לא גולל ב־קצב קבוע. הוא גולל קצת, עוצר, קורא, גולל עוד, גולל למעלה (כי משהו תפס את עינו), גולל למטה שוב. הבוט שלנו מבצע scroll patterns של 4-8 תזוזות עם pauses ביניהם.
def human_scroll(driver, total_y=2000):
chunks = random.randint(4, 8)
for _ in range(chunks):
delta = total_y // chunks + random.randint(-50, 50)
driver.execute_script(f"window.scrollBy(0, {delta});")
time.sleep(random.uniform(0.4, 1.2))
# Sometimes scroll back up
if random.random() < 0.2:
driver.execute_script("window.scrollBy(0, -300);")
time.sleep(random.uniform(0.5, 1.5))שכבה 9: cookie persistence (כפי שדנו במאמר נפרד)
ראה session persistence ו־cookies. תקציר: שמירה של user-data dir, רענון פעיל כל 13 ימים, השמטה של כל delete.
שכבה 10: IP isolation
כל VDS עם static IP נפרד. אין proxy chains, אין shared IPs. למה? כי:
- Proxy chains מוסיפים latency שמשנה ב־performance timing fingerprint.
- Shared IPs (גם residential) מנוצלים ע"י עוד אנשים שעלולים להיחסם בעצמם.
- Static IP מ־דאטה־סנטר ישראלי הוא הכי "נורמלי" עבור חשבון פייסבוק ישראלי.
כל ה־VDS שלנו על תשתית של דאטה־סנטרים אירופאים ו־ישראלים, עם IPs נקיים שעברו בדיקה.
שכבה 11: בית הספר של חימום
חשבון חדש לא יכול להתחיל לפרסם מיידית. אצלנו ה־protocol:
- שבוע 1: כניסה לפייסבוק יום־יום, גלילת פיד 5-10 דקות, לייקים על 3-5 פוסטים, אפס פוסטים אישיים.
- שבוע 2: בנוסף, הוספת 5-10 חברים אמיתיים, הצטרפות ל־3-5 קבוצות, תגובות על 2-3 פוסטים.
- שבוע 3: 1-2 פוסטים אישיים (לא קבוצתיים), שיתוף פוסט אחד.
- שבוע 4 ואילך: בוט מתחיל לפרסם — מתחיל מ־3-5 פוסטים ביום וגדל בהדרגה.
חשבון שמתחיל לפרסם 50 פוסטים ביום ביום הראשון — נחסם תוך 24 שעות. הפרוטוקול הזה הוא לא־אופציונלי.
שכבה 12: זיהוי מבני (לא טקסטואלי)
פירטתי במאמר rate-limit engineering. בקצרה: זיהוי outcome של פוסט באמצעות מבנה ARIA, לא טקסט. נשמע מוזר לקרוא ל"זיהוי outcome" שכבה של anti-detection, אבל זה כן: מערכת שטועה ב־70% מהזמן מהדפוס תיכשל מהר. דיוק = הישרדות.
שכבה 13: watchdog ו־recovery
אם הבוט תקוע (state mtime > 90 דקות), watchdog process מאתחל אותו. זה לא רק תיקון bug — זה אנטי־דטקציה כי "בוט שתקוע" הופך ל"בוט שנראה שכוח" שעלול לעורר חשד.
סיכום
אנטי־דטקציה ב־2026 היא הנדסה רצינית. BuzzPost מטפל בכל 20+ השכבות אוטומטית — אתה לא צריך לדעת מה זה Bezier curve או timezone leak; אתה רק פותח את הפאנל ורואה שהמערכת רצה. כל לקוח מקבל VDS ייעודי עם כל ההגנות מוכנות. אם אתה רוצה להתחיל לפרסם בלי לאבד את החשבון — קנה את התוכנית הראשונה ב־249₪ לחודש. שרת אחד, כל הערימה.
למידע נוסף: תכונות, headless vs visible, ניהול חשבונות מרובים.
שכבות 14-20: עיון מעמיק בשכבות הנוספות
שכבה 14: רנדומיזציה של פוסט (תוכן + תמונה)
אסור שיהיו שני פוסטים זהים. הבוט משתמש ב־AI (GPT-4 או מודל מקומי) לכתיבת וריאציות של אותו תוכן. למשל, "דירה להשכרה קריית מוצקין" יכול להיות:
- "להשכרה בקריית מוצקין: דירת 3 חדרים נעימה ומוארת"
- "מציעים להשכרה בקריית מוצקין — 3 חדרים, מצויינת!"
- "דירת 3 חדרים להשכרה בקריית מוצקין, מיידי"
תמונות: pool של 20-30 תמונות לכל דירה, ובכל פוסט תמונה אחרת. אם אין מספיק תמונות אמיתיות, עיבוד קל (crop, color shift, מטה־דאטה חדש) על אותה תמונה מייצר וריאציה.
שכבה 15: ניהול hashtags
hashtags עוברים רוטציה. לא להשתמש בכל פוסט באותם 5 hashtags. בנוסף, וריאציה בסדר ה־hashtags — לפעמים בסוף הפוסט, לפעמים באמצע.
שכבה 16: phone number consistency
מספר הטלפון שמופיע בפוסטים נדל"ן הוא ה־contact של הלקוח. גם הוא עובר רנדומיזציה קלה בפורמט:
050-123-4567050 123 4567050.123.45670501234567+972-50-123-4567
פייסבוק לא מסמנת מספרי טלפון, אבל פוסטים זהים עם פורמט זהה של מספר נחשבים יותר ספאם.
שכבה 17: time-of-day distribution
פוסטים מתפזרים על פני 4-5 חלונות זמן ב־24 שעות, רובם בלילה (00:00-07:00). לא לרכז את כל ה־24 פוסטים ב־2 שעות.
שכבה 18: group rotation
בוט לא מפרסם באותה קבוצה פעמיים ביום. אם יש 50 קבוצות יעד, היום הראשון 25 קבוצות, היום השני 25 הקבוצות האחרות. אחרי 7 ימים — חזרה לסבב.
שכבה 19: ניהול hash של תמונות
פייסבוק מחשבת hash perceptual לכל תמונה. אם אותה תמונה עולה ל־3 קבוצות שונות, פייסבוק רואה את הקשר. אצלנו אנחנו מבצעים image aging: כל תמונה לא חוזרת אותה קבוצה במשך 7 ימים, ואחרי 7 ימים — variant של התמונה (crop שונה, חיתוך אחר).
שכבה 20: monitor + alerting
המערכת המלאה כוללת dashboards, alerts, ו־health checks. אם פוסט אחד נכשל — alert. אם 3 פוסטים נכשלים ברצף — alert חמור. אם רמת השגיאה כללית עולה מ־5% ל־15% — alert קריטי.
שאלות שלקוחות שואלים
"מה אם פייסבוק תוסיף שכבת זיהוי חדשה?"
אנחנו מעקבים את הבעיה. כשמשהו משתנה — כל הצי שלנו (150+ חשבונות) רואים את אותה תופעה בו זמנית, וזה signal ברור. אנחנו מעדכנים את ה־detector תוך 48 שעות בממוצע.
"איך אדע שהבוט פועל נכון?"
בפאנל יש לוח dashboards מלא: כמה פוסטים היום, אחוז הצלחה, התראות אדומות אם משהו לא בסדר.
נספח: דגלי Chrome שאסור להעביר
לא כל דגל הוא טוב. הנה רשימה שחורה של דגלים שמסכימים את ה־anti-detection:
--headless— מובן מאליו--disable-gpu— מטה את WebGL fingerprint--no-sandbox— לא חוצה רף זיהוי, אבל ב־production לא מומלץ--disable-web-security— שובר CORS שפייסבוק מסתמכת עליו--disable-features=VizDisplayCompositor— אופטימיזציית רינדור שמשפיעה fingerprint--use-fake-ui-for-media-stream— מסמן כ־automated--enable-automation— שם זה אומר הכל
אם אתה בונה משלך, התחל מ־minimal flag set ותוסיף רק מה שנדרש. כל דגל הוא potential signal.
הקשר בין השכבות
חשוב להבין שהשכבות לא עצמאיות. הן עובדות יחד. אם יש לך UA אמיתי אבל timezone שגוי, ה־signal נשבר. אם יש לך mouse paths מעולים אבל אתה רץ ב־scroll constant — נחשד. כל השכבות חייבות להיות עקביות.
זה מה שמייצר את ה־"deep faking" של אנושיות: 20+ פרטים קטנים שמסכימים זה עם זה ויוצרים תמונה אמינה. כשפייסבוק מנסה לזהות bot, היא בודקת לא רק אם השכבה הראשונה נכשלת — היא מחפשת inconsistencies בין השכבות.
דוגמה: UA אומר "Windows 10 + Chrome 121", אבל timezone אומר "America/New_York", אבל IP מ־ישראל, אבל locale מ־"en-US". זה לא משתמש — זה מישהו שטעה במספר פרמטרים. גם אם הוא משתמש אמיתי שגר באמריקה ועולה לישראל — שילוב זה לא מצוי.
בגלל זה ה־VDS הייעודי הוא לא רק "פתרון פשוט" אלא פתרון נכון: כל פרמטר מותאם ל־persona אחד וקבוע. אין החלפה, אין סתירה. כל ה־20+ שכבות מסכמות ל"משתמש ישראלי מבוגר על Windows 10 בקריות שגלל פיד נדל"ן ב־04:30 לפני שהילדים התעוררו". זה נראה אמין, כי זה מתאים לאלפי משתמשים אמיתיים.