tn3w/crua
GitHub: tn3w/crua
这是一个轻量级的 Python 库,旨在通过解析 User-Agent 字符串来快速区分爬虫与真实浏览器,并提取设备与系统信息。
Stars: 0 | Forks: 0
面向 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注入, 反爬虫, 后端开发, 数据清洗, 机器人识别, 浏览器指纹, 爬虫检测, 自动化工具检测, 蓝队分析, 逆向工具