爬虫的精准识别:基于 User-Agent 的正则实现

06-01 1103阅读

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。

技术合作请加本人wx(注明来自csdn):foreast_sea

爬虫的精准识别:基于 User-Agent 的正则实现

------爬虫的精准识别:基于 User-Agent 的正则实现

爬虫的精准识别:基于 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)); // true
              System.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)均支持 RegExp 和 i 标志。
              • 兼容到 IE9+。

            5.4 完整代码

            // 定义正则表达式
            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");
            }
            
            

            注意事项

            1. 误判风险:极少数正常浏览器可能包含关键词(如 Bot),但概率极低。
            2. 动态更新:定期更新正则中的关键词列表以覆盖新出现的爬虫。
            3. 性能:正则表达式复杂度较低,适合高频调用。

            如果需要更全面的关键词列表,可以参考 user-agents 等公开数据集。

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码