tn3w/crua

GitHub: tn3w/crua

这是一个轻量级的 Python 库,旨在通过解析 User-Agent 字符串来快速区分爬虫与真实浏览器,并提取设备与系统信息。

Stars: 0 | Forks: 0

CRUA banner

PyPI Version Publish Status License

面向 Python 的快速爬虫检测与浏览器解析。

专为每个后端最终都会问到的常见问题而构建:
这些流量是真实的浏览器,还是某种机器人?

## 为什么选择 CRUA? CRUA 为你提供了一个小型 API,用于分类 user agent、提取浏览器元数据,并在出现异常时调试爬虫匹配。
快速
基于正则驱动且轻量。
实用
专注于实际应用和日志处理需求。
可调试
explain_crawler() 显示匹配原因。
## 安装 ``` pip install crua ``` 可选的更快的正则后端: ``` pip install google-re2 ``` ## 快速开始 ``` from crua import explain_crawler, is_crawler, parse ua = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/120.0.0.0 Safari/537.36" ) result = parse(ua) result.is_crawler # False result.browser.browser # "Chrome" result.browser.os # "Windows" result.browser.device # "Desktop" is_crawler("Googlebot/2.1 (+http://www.google.com/bot.html)") # True explain_crawler("Mozilla/5.0 Chrome/110.0 Safari/537.36 Chrome-Lighthouse").matched # ["browser_crawler_token"] ``` ## API ``` from crua import ( explain_crawler, extract_user_agents, is_browser, is_crawler, normalize_user_agent, parse, parse_browser, parse_crawler, parse_or_none, safe_parse, ) ``` | Function | 功能 | | ------------------------ | ------------------------------------------------------------ | | `is_crawler()` | 当 user agent 应被视为爬虫时返回 `True` | | `is_browser()` | `is_crawler()` 的便捷反向方法 | | `parse()` | 返回结构化的爬虫和浏览器元数据 | | `parse_crawler()` | 当 UA 被分类为爬虫时返回爬虫信息 | | `parse_browser()` | 返回浏览器、引擎、操作系统和设备信息 | | `parse_or_none()` | 防御性解析,对于空的规范化输入返回 `None` | | `safe_parse()` | `parse_or_none()` 的别名 | | `normalize_user_agent()` | 解析前修剪并规范化空白字符 | | `explain_crawler()` | 返回匹配的爬虫启发式规则和排除项 | | `extract_user_agents()` | 从文本和日志块中提取 user-agent 字符串 | ## 常用示例 ### 防御性解析 ``` from crua import safe_parse safe_parse(b"curl/8.7.1\r\n").crawler.name # "curl" safe_parse(" ") # None ``` ### 规范化噪声输入 ``` from crua import normalize_user_agent normalize_user_agent(" Mozilla/5.0 \n Chrome/120.0 Safari/537.36 ") # "Mozilla/5.0 Chrome/120.0 Safari/537.36" ``` ### 从日志中提取 ``` from crua import extract_user_agents line = ( '127.0.0.1 - - [08/Apr/2026:12:00:00 +0000] ' '"GET / HTTP/1.1" 200 123 "-" ' '"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"' ) extract_user_agents(line) # ["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " # "(KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"] ``` ## 返回对象 ### `UserAgent` ``` result = parse("Googlebot/2.1 (+http://www.google.com/bot.html)") result.raw result.is_crawler result.crawler result.browser ``` | Field | Type | 含义 | | ------------ | --------------------- | ----------------------------- | | `raw` | `str` | 原始 user-agent 字符串 | | `is_crawler` | `bool` | 最终的爬虫分类 | | `crawler` | `CrawlerInfo \| None` | 检测到时的爬虫元数据 | | `browser` | `BrowserInfo \| None` | 浏览器、引擎、操作系统和设备元数据 | ### `CrawlerInfo` ``` result = parse("Googlebot/2.1 (+http://www.google.com/bot.html)") result.crawler.name result.crawler.version result.crawler.url ``` | Field | Type | 含义 | | --------- | ------------- | ------------------------------------------ | | `name` | `str \| None` | 爬虫系列或 token 名称,如 `"Googlebot"` | | `version` | `str \| None` | 解析出的爬虫版本(如果存在) | | `url` | `str \| None` | 在 user agent 中找到的联系或信息 URL | ### `BrowserInfo` ``` result = parse( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/120.0.0.0 Safari/537.36" ) result.browser.browser result.browser.browser_version result.browser.os result.browser.device ``` | Field | Type | 含义 | | ----------------- | ------------- | --------------------------------------------------------- | | `product_token` | `str \| None` | 第一个 product token,通常为 `"Mozilla/5.0"` | | `comment` | `str \| None` | 第一个括号注释块 | | `engine` | `str \| None` | 渲染引擎,例如 `Blink`、`AppleWebKit` 或 `Gecko` | | `engine_version` | `str \| None` | 可用的引擎版本 | | `browser` | `str \| None` | 浏览器名称,例如 `Chrome`、`Firefox` 或 `Safari` | | `browser_version` | `str \| None` | 可用的浏览器版本 | | `os` | `str \| None` | 操作系统名称 | | `os_version` | `str \| None` | 可用的操作系统版本 | | `device` | `str \| None` | 设备类别,如 `Desktop`、`Mobile`、`Tablet` 或 `SmartTV` | | `rendering` | `str \| None` | 额外的渲染提示,例如 `KHTML, like Gecko` | ### `CrawlerExplanation` ``` explanation = explain_crawler( "Mozilla/5.0 Chrome/110.0 Safari/537.36 Chrome-Lighthouse" ) explanation.is_crawler explanation.matched explanation.excluded ``` 所有返回的 dataclass 均暴露 `to_dict()` 方法。 ## 典型用例 - 从分析或限流逻辑中过滤机器人 - 在日志中将爬虫流量与浏览器流量分开 - 解析浏览器、操作系统和设备信息用于仪表盘 - 使用 `explain_crawler()` 调试误报 - 使用 `safe_parse()` 安全处理混合或混乱的输入 ## 开发 ``` pip install -e .[dev] pytest ``` ## 格式化 ``` pip install black isort isort . && black . npx prtfm ```
标签:Apache-2.0, Google-RE2, Python包, User-Agent解析, Web安全, XML注入, 反爬虫, 后端开发, 数据清洗, 机器人识别, 浏览器指纹, 爬虫检测, 自动化工具检测, 蓝队分析, 逆向工具