爬蟲的精準識別:基于 User-Agent 的正則實現

🧑 博主簡介:CSDN博客專家歷代文學網(PC端可以訪問:https://literature.sinhy.com/#/?__c=1000,移動端可微信小程序搜索“歷代文學”)總架構師,15年工作經驗,精通Java編程高并發設計Springboot和微服務,熟悉LinuxESXI虛擬化以及云原生Docker和K8s,熱衷于探索科技的邊界,并將理論知識轉化為實際應用。保持對新技術的好奇心,樂于分享所學,希望通過我的實踐經歷和見解,啟發他人的創新思維。在這里,我希望能與志同道合的朋友交流探討,共同進步,一起在技術的世界里不斷學習成長。
技術合作請加本人wx(注明來自csdn):foreast_sea

在這里插入圖片描述
------在這里插入圖片描述

爬蟲的精準識別:基于 User-Agent 的正則實現


引言

在當今實時交互場景中,WebSocket 技術已成為在線客服、即時通訊、實時數據推送等服務的核心支柱。然而,一個看似簡單的技術細節卻可能讓企業付出高昂的代價:當爬蟲機器人偽裝成“用戶”接入 WebSocket 時,客服系統可能誤將其識別為真實客戶,導致客服資源被無意義消耗,甚至因“無響應對話”而影響用戶體驗

場景痛點:當技術便利遭遇“無效流量”

想象一個典型的在線客服場景:用戶訪問網站后,通過 WebSocket 與客服實時溝通。然而,大量爬蟲(如搜索引擎索引、SEO 工具、惡意掃描程序)的請求也會觸發 WebSocket 連接。這些爬蟲不會主動發送消息,卻會長期占用連接資源。客服人員看到“在線用戶”列表中的爬蟲會話,嘗試對話卻得不到任何回應,最終導致:

  1. 資源浪費:服務器帶寬、連接數被無效占用。
  2. 效率下降:客服需要手動排查“沉默用戶”,增加工作負擔。
  3. 數據污染:統計報表中的“用戶活躍數”被虛假流量污染。

更糟糕的是,部分攻擊者會利用 WebSocket 的長連接特性,發起高頻請求或注入攻擊,進一步威脅系統安全。

傳統方案的局限性

許多開發者試圖通過簡單的 IP 封禁請求頻率限制 解決問題,但爬蟲的 IP 池和訪問策略日益動態化,傳統方案往往力不從心。而直接依賴 User-Agent 字符串過濾 看似直接,卻常因正則表達式設計不當(如漏判新爬蟲、誤傷正常用戶)導致效果大打折扣。

本文目標

本文將聚焦 “如何在 WebSocket 握手階段精準識別爬蟲”,通過以下實踐方案實現高效攔截:

  1. 多維度 User-Agent 檢測:基于正則表達式覆蓋 95% 的已知爬蟲標識,確保關鍵詞精準匹配。
  2. 輕量化瀏覽器端攔截:提供 JavaScript 正則方案,避免爬蟲觸發前端資源加載。
  3. 服務端兜底邏輯:結合 IP 黑名單與行為分析,應對偽造 User-Agent 的高級爬蟲。

文章將深入解析正則表達式設計技巧、跨語言(Java/JavaScript)實現方案,并探討如何在開源數據集(如 crawler-user-agents)基礎上動態更新策略。無論您是構建客服系統的開發者,還是需優化實時服務性能的架構師,均可通過本文獲得可直接復用的代碼與實踐經驗。


以下是基于常見爬蟲和機器人的 User-Agent 關鍵詞整理的正則表達式實現方案:


1. 常見爬蟲 User-Agent 關鍵詞

以下關鍵詞覆蓋了主流搜索引擎、SEO 工具、社交媒體、監控服務等類型的爬蟲機器人:

關鍵詞(不區分大小寫)示例爬蟲名稱
botGooglebot, Bingbot
spiderYandexSpider, Baiduspider
crawlerAhrefsBot, SemrushBot
slurpYahoo! Slurp
facebookexternalhitFacebook 鏈接預覽機器人
duckduckbotDuckDuckGo 爬蟲
facebotFacebook 爬蟲
alexaAmazon 的 Alexa 爬蟲
applebotApple 的搜索引擎爬蟲
pinterestPinterest 爬蟲
twitterbotTwitter 爬蟲
linkedinbotLinkedIn 爬蟲
telegrambotTelegram 爬蟲
uptimerobotUptimeRobot 監控服務
exabotExalead 搜索引擎
msnbotMSN 搜索引擎爬蟲
yahooYahoo 爬蟲

2. 正則表達式實現

以下正則表達式會匹配包含上述關鍵詞的 User-Agent(不區分大小寫):

String pattern = "(?i).*\\b(bot|spider|crawler|slurp|facebookexternalhit|duckduckbot|facebot|alexa|applebot|pinterest|twitterbot|linkedinbot|telegrambot|uptimerobot|exabot|msnbot|yahoo|googlebot|bingbot|yandexbot|baiduspider|ahrefsbot|semrushbot)\\b.*";

3. 正則關鍵表達式說明

3.1 (?i):忽略大小寫的標記

  • 作用:表示后續的正則匹配不區分大小寫
  • 原理(?i) 是正則表達式的 模式修飾符(Pattern Modifier),它會從當前位置開始,對整個表達式生效。
  • 示例
    (?i)bot   → 可以匹配 "Bot", "BOT", "bOt" 等任意大小寫組合
    

3.2 \\b: 單詞邊界

  • 作用:表示 單詞邊界(Word Boundary),確保匹配的是一個完整的單詞(而不是單詞的一部分)。
  • 原理\\b 會匹配一個位置,該位置的一側是單詞字符(字母、數字、下劃線),另一側是非單詞字符(如空格、標點或字符串邊界)。
  • 示例
    \\bbot\\b → 匹配 "bot" 但不會匹配 "robot" 或 "bots"
    

3.3 組合后的效果:(?i).*\\b(bot|spider)\\b.*

假設原始正則表達式為:

String pattern = "(?i).*\\b(bot|spider)\\b.*";
3.3.1 匹配邏輯
  1. (?i) → 忽略大小寫。
  2. .* → 允許目標關鍵詞出現在 任意位置(如開頭、中間、結尾)。
  3. \\b → 確保關鍵詞是完整單詞(避免部分匹配,如 robot 中的 bot)。
  4. (bot|spider) → 匹配 “bot” 或 “spider”。
  5. 最后的 .* → 允許關鍵詞后有其他字符。
3.3.2 示例匹配的 User-Agent
  • "Googlebot/2.1" → 匹配 bot
  • "YandexSpider" → 匹配 spider
  • "BingPreviewBot" → 匹配 bot
3.3.3 不匹配的 User-Agent
  • "Robot/1.0"\\bbot\\b 不會匹配 “Robot” 中的 “bot”
  • "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" → 不含關鍵詞

4. Java 代碼實現

import java.util.regex.Pattern;public class CrawlerDetector {private static final String BOT_PATTERN = "(?i).*\\b(bot|spider|crawler|slurp|facebookexternalhit|duckduckbot|facebot|alexa|applebot|pinterest|twitterbot|linkedinbot|telegrambot|uptimerobot|exabot|msnbot|yahoo|googlebot|bingbot|yandexbot|baiduspider|ahrefsbot|semrushbot)\\b.*";private static final Pattern pattern = Pattern.compile(BOT_PATTERN);public static boolean isCrawler(String userAgent) {if (userAgent == null || userAgent.trim().isEmpty()) {return false;}return pattern.matcher(userAgent).matches();}
}

4.1 java 使用示例

public static void main(String[] args) {String userAgent1 = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";String userAgent2 = "Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1";System.out.println("Is crawler 1? " + CrawlerDetector.isCrawler(userAgent1)); // trueSystem.out.println("Is crawler 2? " + CrawlerDetector.isCrawler(userAgent2)); // false
}

5. JS 代碼實現

以下是 JavaScript 版本的正則表達式實現(適配瀏覽器環境):

5.1 JavaScript 正則表達式

const crawlerRegex = /\b(bot|spider|crawler|slurp|facebookexternalhit|duckduckbot|facebot|alexa|applebot|pinterest|twitterbot|linkedinbot|telegrambot|uptimerobot|exabot|msnbot|yahoo|googlebot|bingbot|yandexbot|baiduspider|ahrefsbot|semrushbot)\b/i;

5.2 實現解析

5.2.1 正則結構
  • \b:匹配單詞邊界(確保關鍵詞是完整單詞,避免誤匹配類似 robot 中的 bot)。
  • (bot|spider|...):匹配列表中的任意關鍵詞。
  • i 標志:忽略大小寫(替代 Java 的 (?i))。
5.2.2 瀏覽器端使用示例
// 檢測當前瀏覽器 User-Agent 是否是爬蟲
function isCrawler() {const userAgent = navigator.userAgent;return crawlerRegex.test(userAgent);
}// 調用示例
if (isCrawler()) {console.log("檢測到爬蟲,阻止 WebSocket 連接");
} else {console.log("允許連接 WebSocket");
}

5.3注意事項

  1. 關鍵詞動態更新
    可以將正則關鍵詞提取到配置中,便于動態擴展:

    const botKeywords = ["bot", "spider", "crawler", "slurp", "facebookexternalhit", "duckduckbot", "facebot",// ...其他關鍵詞
    ];
    const crawlerRegex = new RegExp(`\\b(${botKeywords.join("|")})\\b`, "i");
    
  2. 瀏覽器兼容性

    • 所有現代瀏覽器(Chrome/Firefox/Safari/Edge)均支持 RegExpi 標志。
    • 兼容到 IE9+。

5.4 完整代碼

<script>
// 定義正則表達式
const botKeywords = ["bot", "spider", "crawler", "slurp", "facebookexternalhit","duckduckbot", "facebot", "alexa", "applebot", "pinterest","twitterbot", "linkedinbot", "telegrambot", "uptimerobot","exabot", "msnbot", "yahoo", "googlebot", "bingbot","yandexbot", "baiduspider", "ahrefsbot", "semrushbot"
];
const crawlerRegex = new RegExp(`\\b(${botKeywords.join("|")})\\b`, "i");// 檢測邏輯
function isCrawler() {return crawlerRegex.test(navigator.userAgent);
}// 根據檢測結果控制 WebSocket 連接
if (!isCrawler()) {const ws = new WebSocket("wss://your-websocket-endpoint");ws.onopen = () => console.log("WebSocket 已連接");
} else {console.log("爬蟲客戶端,禁止連接 WebSocket");
}
</script>

注意事項

  1. 誤判風險:極少數正常瀏覽器可能包含關鍵詞(如 Bot),但概率極低。
  2. 動態更新:定期更新正則中的關鍵詞列表以覆蓋新出現的爬蟲。
  3. 性能:正則表達式復雜度較低,適合高頻調用。

如果需要更全面的關鍵詞列表,可以參考 user-agents 等公開數據集。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/73017.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73017.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73017.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【AI大模型】LLM訓練deepseek如何識別視頻

要讓像DeepSeek這樣的大語言模型&#xff08;LLM&#xff09;具備視頻識別能力&#xff0c;需要結合多模態學習技術&#xff0c;將視覺信息與文本語義進行融合。以下是實現這一目標的關鍵步驟和技術要點&#xff1a; --- 一、視頻識別的核心挑戰 1. 多模態數據&#xff1a;視頻…

【物聯網-以太網-W5500】

物聯網-以太網-W5500 ■ W5500-簡介■■■■ ■ W5500-簡介 ■ ■ ■ ■

centos linux安裝mysql8 重置密碼 遠程連接

1. 下載并安裝 MySQL Yum 倉庫 從 MySQL 官方網站下載并安裝 Yum 倉庫配置文件。 # 下載MySQL 8.0的Yum倉庫包 wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm # 安裝Yum倉庫包 sudo rpm -ivh mysql80-community-release-el7-5.noarch.rpm2. 啟…

C++【類和對象】(超詳細!!!)

C【類和對象】 1.運算符重載2.賦值運算符重載3.日期類的實現 1.運算符重載 (1).C規定類類型運算符使用時&#xff0c;必須轉換成調用運算符重載。 (2).運算符重載是具有特殊名字的函數&#xff0c;名字等于operator加需要使用的運算符&#xff0c;具有返回類型和參數列表及函數…

【面試】Java 多線程

多線程 1、什么是線程和進程2、創建線程有幾種方式3、線程有幾種狀態4、什么是上下文切換5、什么是守護線程&#xff0c;和普通線程有什么區別6、什么是線程池&#xff0c;如何實現的7、Executor和Executors的區別8、線程池處理任務的流程9、線程數設定成多少更合適10、執行exe…

宿主機運行pyspark任務讀取docker hadoop容器上的數據

熬了四個大夜才搞明白&#xff0c;最晚一天熬到早上十點/(ㄒoㄒ)/~~&#xff0c;最后發現只要加個參數就解決了。。。抱頭痛哭 問題描述&#xff1a; Hadoop集群部署在docker容器中&#xff0c;宿主機執行pyspark程序讀取hive表 問題一&#xff1a;當master(local[*])時&…

《平凡的世界》:在泥土中尋找星辰的勇氣

“平凡不是平庸的代名詞&#xff0c;而是千萬人用脊梁扛起時代的勛章。”——路遙的《平凡的世界》用百萬字書寫了黃土地上孫少安、孫少平兩兄弟的掙扎與覺醒&#xff0c;撕開了“奮斗逆襲”的浪漫濾鏡&#xff0c;告訴你&#xff1a;真正的英雄主義&#xff0c;是在認清了生活…

【SpringMVC】深入解析使用 Postman 和瀏覽器模擬將單個與多個參數傳遞到后端和后端接收過程

SpringMVC—請求(Request) 訪問不同的路徑&#xff0c;就是發送不同的請求&#xff1b;在發送請求時&#xff0c;可能會帶一些參數&#xff0c;所以學習Spring的請求&#xff0c;主要是學習如何傳遞參數到后端以及后端如何接收&#xff1b; 我們主要是使用 瀏覽器 和 Postman …

04 | 初始化 fastgo 項目倉庫

提示&#xff1a; 所有體系課見專欄&#xff1a;Go 項目開發極速入門實戰課&#xff1b;歡迎加入我的訓練營&#xff1a;云原生AI實戰營&#xff0c;一個助力 Go 開發者在 AI 時代建立技術競爭力的實戰營&#xff1b;本節課最終源碼位于 fastgo 項目的 feature/s01 分支&#x…

Docker 安裝成功后,安裝 Dify 中文版本的步驟

Docker 安裝成功后&#xff0c;安裝 Dify 中文版本的步驟如下1&#xff1a; 克隆 Dify 代碼倉庫&#xff1a;在終端中執行以下命令&#xff0c;將 Dify 源代碼克隆至本地環境。 bash git clone https://github.com/langgenius/dify.git進入 Dify 的 docker 目錄&#xff1a; b…

RPC服務調用深度解析:從原理到Java實踐

一、RPC的核心原理與架構設計 1.1 RPC的本質 RPC&#xff08;Remote Procedure Call&#xff09;是一種分布式系統間通信協議&#xff0c;允許程序像調用本地方法一樣調用遠程服務。其核心目標是通過位置透明性和協議標準化隱藏網絡通信細節。RPC的調用流程可抽象為以下步驟&…

電腦的寫字板如何使用?

打開寫字板&#xff1a; 直接按一下鍵盤上的win R 鍵&#xff0c;然后輸入&#xff1a;write &#xff0c; 再按一下回車 , 即可打開寫字板 可以在里面寫文字 和 插入圖片等… &#xff0c; 如下所示&#xff1a; 保存寫字板內容&#xff1a; 當我們寫好了之后&#xff0c;…

醫療AI測試實戰:如何確保人工智能安全賦能醫療行業?

一、醫療AI測試的重要性 人工智能&#xff08;AI&#xff09;正廣泛應用于醫療行業&#xff0c;如疾病診斷、醫學影像分析、藥物研發、手術機器人和智能健康管理等領域。醫療AI技術的應用不僅提高了診斷效率&#xff0c;還能降低誤診率&#xff0c;改善患者治療效果。然而&…

AI日報 - 2025年3月12日

AI日報 - 2025年3月12日 &#x1f31f; 今日概覽&#xff08;60秒速覽&#xff09; ▎&#x1f916; AGI突破 | Anthropic CEO預測AI將主導代碼編寫 &#x1f52c; 自訓練技術顯著提升LLM思維清晰度 ▎&#x1f4bc; 商業動向 | OpenAI與CoreWeave達成119億美元基建協議 &…

跳表數據結構

跳表&#xff08;Skip List&#xff09;是一種支持高效插入、刪除和查找的鏈表結構&#xff0c;用于加速查找操作&#xff0c;特別適用于有序數據集合。它在Redis、LevelDB等系統中被用于**有序集合&#xff08;Sorted Set&#xff09;**的實現。 1. 跳表的結構 跳表的核心思…

系統會把原先的對話狀態堆棧從 [“assistant“] 更新為 [“assistant“, “update_flight“]這個更新的處理過程

這個更新主要是在 State 定義中通過 Annotated 來自動處理的。在 State 類型中&#xff0c;我們對 dialog_state 字段綁定了 update_dialog_stack 函數&#xff0c;如下所示&#xff1a; class State(TypedDict):messages: Annotated[list[AnyMessage], add_messages]user_inf…

HTTP發送POST請求的兩種方式

1、json String json HttpRequest.post(getUrl(method, "v1", url, userId, appKey)).header("Content-type", "application/json") // 設置請求頭為 JSON 格式.body(JSONUtil.toJsonStr(params)) // 請求體為 JSON 字符串.execute().body(); …

Windows 萬興恢復專家 Wondershare Recoverit-v13.5.7.9-[電腦數據恢復工具]

Windows 萬興恢復專家Wondershare_Recoverit 鏈接&#xff1a;https://pan.xunlei.com/s/VOL3z608vzAj_IYTvH-F1q7kA1?pwdiu89# 1. 打開Setup.exe進行安裝&#xff0c;安裝完不要打開軟件&#xff0c;記住安裝目錄 2. 將"Crack"文件夾內的所有文件復制到安裝目錄 …

Blender UV紋理貼圖,導出FBX到Unity

加載ps好的模型貼圖。右下角選擇《材質》基礎色里面選擇《圖像紋理》&#xff0c;選擇你的圖片。 選擇上面UV選項卡。左上角選擇UV編輯器。選中物體&#xff0c;TAB進入編輯模式。即可調整映射的圖像范圍。 其中渲染設置可以在左側下邊脫出。 導出帶紋理FBX模型 路徑選擇復…

華為hcia——Datacom實驗指南——以太網幀和IPV4數據包格式(一)

實驗開始 第一步配置環境 第二步配置客戶端 如圖所示&#xff0c;我們把客戶端的ip配置成192.168.1.10&#xff0c;網關設為192.168.1.1 第三步配置交換機1 system-view sysname LSW1 vlan batch 10 interface ethernet0/0/1 port link-type access port default vlan 10 qu…