当前位置: 首页 > news >正文

爬虫的精准识别:基于 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 等公开数据集。

相关文章:

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

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

Python数据分析之数据可视化

Python 数据分析重点知识点 本系列不同其他的知识点讲解&#xff0c;力求通过例子让新同学学习用法&#xff0c;帮助老同学快速回忆知识点 可视化系列&#xff1a; Python基础数据分析工具数据处理与分析数据可视化机器学习基础 四、数据可视化 图表类型与选择 根据数据特…...

【免费】2004-2020年各省货运量数据

2004-2020年各省货运量数据 1、时间&#xff1a;2004-2020年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区、年份、货运量(万吨) 4、范围&#xff1a;31省 5、指标解释&#xff1a;货运量指在一定时期内&#xff0c;各种运输工具实际运…...

【CXX】6.6 UniquePtr<T> — std::unique_ptr<T>

std::unique_ptr 的 Rust 绑定称为 UniquePtr。有关 Rust API 的文档&#xff0c;请参见链接。 限制&#xff1a; 目前仅支持 std::unique_ptr<T, std::default_delete>。未来可能会支持自定义删除器。 UniquePtr 不支持 T 为不透明的 Rust 类型。对于在语言边界传递不…...

Java 集合框架大师课:集合框架源码解剖室(五)

&#x1f525;Java 集合框架大师课&#xff1a;集合框架源码解剖室&#xff08;五&#xff09; &#x1f4a3; 警告&#xff1a;本章包含大量 裸码级硬核分析&#xff0c;建议搭配咖啡因饮料阅读&#xff01;☕️ 第一章 ArrayList 的扩容玄学 1.1 动态扩容核心代码大卸八块 …...

llamafactory 微调教程

文章目录 llamlafactory微调deepseekr1-0.5b1.1 说明1.2 搭建环境创建GPU实例连接实例部署llama_factory创建隧道&#xff0c;配置端口转发访问llama_factory 1.3 微调大模型从huggingface上下载基座模型查看模型是否下载成功准备数据集微调评估微调效果导出合并后的模型 释放实…...

代码随想录|二叉树|04二叉树的统一迭代法

一刷我这里放了。。。 代码随想录...

【教学类-43-25】20240311 数独3宫格的所有可能(图片版 12套样式,空1格-空8格,每套510张,共6120小图)

背景需求&#xff1a; 有一位客户买3宫格所有可能&#xff08;WORD表格版&#xff09; 【教学类-43-25】20241203 数独3宫格的所有可能-使用模版替换-用时少报错少&#xff08;12套样式&#xff0c;空1格-空8格&#xff0c;每套510张&#xff0c;共6120小图&#xff09;_数独三…...

Manus AI:多语言手写识别的技术革命与未来图景

摘要&#xff1a;在全球化浪潮下&#xff0c;跨语言沟通的需求日益迫切&#xff0c;但手写文字的多样性却成为技术突破的难点。Manus AI凭借其多语言手写识别技术&#xff0c;将潦草笔迹转化为精准数字文本&#xff0c;覆盖全球超百种语言。本文从技术原理、应用场景、行业价值…...

领域驱动设计(DDD)是什么?

领域驱动设计&#xff08;DDD&#xff09;是什么&#xff1f; 在软件开发的世界里&#xff0c;我们总在寻找那把打开业务之门的钥匙。有人迷恋MVC的简洁&#xff0c;有人追逐微服务的潮流&#xff0c;而DDD&#xff08;领域驱动设计&#xff09;则像一位沉默的智者&#xff0c;…...

JavaScript 模块 vs C# 类:封装逻辑的两种哲学

引言 在现代软件开发中&#xff0c;模块化和面向对象设计是代码组织的核心课题。本文通过对比 JavaScript 模块&#xff08;ES6 Module&#xff09;与 C# 类&#xff08;Class&#xff09;的实现方式&#xff0c;探讨两种语言在封装逻辑时的不同哲学&#xff0c;并给出实际应用…...

2.2 企业级ESLint/Prettier规则定制

文章目录 1. 为什么需要企业级代码规范2. 工具选型对比3. 完整配置流程3.1 项目初始化3.2 ESLint深度配置3.3 Prettier精细配置3.4 解决规则冲突4. 高级定制方案4.1 自定义ESLint规则4.2 扩展Prettier插件5. 团队协作策略5.1 配置共享方案5.2 版本控制策略6. CI/CD集成7. 常见问…...

Linux学习(十五)(故障排除(ICMP,Ping,Traceroute,网络统计,数据包分析))

故障排除是任何 Linux 用户或管理员的基本技能。这涉及识别和解决 Linux 系统中的问题。这些问题的范围包括常见的系统错误、硬件或软件问题、网络连接问题以及系统资源的管理。Linux 中的故障排除过程通常涉及使用命令行工具、检查系统和应用程序日志文件、了解系统进程&#…...

DeepIn Wps 字体缺失问题

系统缺失字体 Symbol 、Wingdings 、Wingdings2、Wingdings3、MT—extra 字体问题 问了下DeepSeek 在应用商店安装或者在windows 里面找 装了一个GB-18030 还是不行 在windows里面复制了缺失的字体 将字体复制到DeepIn 的字体目录&#xff08;Ubuntu 应该也是这个目录&am…...

(二分 数学推导 统计公平数对的数目)leetcode 2563

数学推导&#xff1a; lower < nums[i] nums[j] < upper且0 < i < j < n 则lower-nums[j]<nums[i]<upper-nums[j] 找到这个范围的nums[i]的个数就是我们要的值 所以枚举j 在0--&#xff08;j-1&#xff09;的范围内 找到第一个大于等于lower-nums[j]…...

临界比例法PID调整-附带pidtune工具和GA算法

代码已上传&#xff1a;计算机控制系统PID参数整定法资源-CSDN文库 1背景 为了模拟PID参数整定&#xff0c;把教材上的案例进行分析。 1题目 单位闭环传递函数&#xff0c;开环传函G(s)1/((s1)(s2)), Ts0.1s, PID调整器输出后&#xff0c;接零阶保持器ZOH。 2 代码 PID含积…...

LabVIEW基于双通道FFT共轭相乘的噪声抑制

对于双通道采集的含噪信号&#xff0c;通过FFT获取复数频谱后&#xff0c;对第二通道频谱取共轭并与第一通道频谱相乘&#xff0c;理论上可增强相关信号成分并抑制非相关噪声。此方法适用于通道间信号高度相关、噪声独立的场景&#xff08;如共模干扰抑制&#xff09;。以下为L…...

小程序SSL证书过期怎么办?

SSL证书就像小程序的“安全锁”&#xff0c;一旦过期&#xff0c;用户访问时会被提示“不安全”&#xff0c;轻则流失客户&#xff0c;重则数据泄露&#xff01;作为企业负责人&#xff0c;如何快速解决证书过期问题&#xff1f;又该如何避免再次踩坑&#xff1f;这篇指南给你答…...

ELK日志分析实战

ELK日志分析实战&#xff1a;从异常流量定位提权攻击 摘要&#xff1a;本文通过模拟真实攻防场景&#xff0c;结合ELK技术栈&#xff08;ElasticsearchLogstashKibana&#xff09;&#xff0c;演示如何从海量服务器日志中快速定位异常流量并追踪提权攻击行为。包含完整的日志收…...

阿里云操作系统控制台实战评测:提升云资源管理与监控效率

文章目录 前言产品介绍操作系统控制台体验阿里云操作系统开通 帮助与总结建议 前言 随着云计算和虚拟化技术的发展&#xff0c;操作系统控制台作为运维管理的核心工具之一&#xff0c;在现代IT环境中发挥着越来越重要的作用。它提供了一种更加直观、高效的方式来管理操作系统&…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...