🧑 博主简介: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 工具、社交媒体、监控服务等类型的爬虫机器人:

关键词(不区分大小写) 示例爬虫名称
bot Googlebot, Bingbot
spider YandexSpider, Baiduspider
crawler AhrefsBot, SemrushBot
slurp Yahoo! Slurp
facebookexternalhit Facebook 链接预览机器人
duckduckbot DuckDuckGo 爬虫
facebot Facebook 爬虫
alexa Amazon 的 Alexa 爬虫
applebot Apple 的搜索引擎爬虫
pinterest Pinterest 爬虫
twitterbot Twitter 爬虫
linkedinbot LinkedIn 爬虫
telegrambot Telegram 爬虫
uptimerobot UptimeRobot 监控服务
exabot Exalead 搜索引擎
msnbot MSN 搜索引擎爬虫
yahoo Yahoo 爬虫

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)均支持 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 等公开数据集。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐