- 新增访问统计:visitstats 服务与查询、visit_capture 中间件、爬虫/来源识别、管理端 analytics 页面 - 新增侧边栏:sidebar 服务与 handler、管理端 sidebar 配置页、前端侧边栏组件 - 新增 widget 嵌入代码生成(widgetCode)与 widgetApi - 遥测逻辑迁移至 handler 层,删除 service/telemetry - env 示例补充 Docker 部署可信代理 IP 说明
70 lines
1.9 KiB
Go
70 lines
1.9 KiB
Go
package service
|
|
|
|
import "strings"
|
|
|
|
// botSignatures 爬虫 UA 特征(小写子串 → 展示名),覆盖搜索引擎 / SEO 工具 / AI 爬虫 / 命令行客户端
|
|
var botSignatures = []struct {
|
|
token string
|
|
name string
|
|
}{
|
|
{"googlebot", "Googlebot"},
|
|
{"google-inspectiontool", "Google Inspection Tool"},
|
|
{"apis-google", "Googlebot"},
|
|
{"bingbot", "bingbot"},
|
|
{"baiduspider", "Baiduspider"},
|
|
{"sogou", "Sogou spider"},
|
|
{"yisou", "YisouSpider"},
|
|
{"360spider", "360Spider"},
|
|
{"haosouspider", "HaosouSpider"},
|
|
{"bytespider", "Bytespider"},
|
|
{"duckduckbot", "DuckDuckBot"},
|
|
{"applebot", "Applebot"},
|
|
{"petalbot", "PetalBot"},
|
|
{"yandexbot", "YandexBot"},
|
|
{"semrushbot", "SemrushBot"},
|
|
{"ahrefsbot", "AhrefsBot"},
|
|
{"mj12bot", "MJ12bot"},
|
|
{"dotbot", "DotBot"},
|
|
{"gptbot", "GPTBot"},
|
|
{"claudebot", "ClaudeBot"},
|
|
{"claude-web", "ClaudeBot"},
|
|
{"ccbot", "CCBot"},
|
|
{"perplexitybot", "PerplexityBot"},
|
|
{"amazonbot", "Amazonbot"},
|
|
{"facebookexternalhit", "facebookexternalhit"},
|
|
{"twitterbot", "Twitterbot"},
|
|
{"slackbot", "Slackbot"},
|
|
{"discordbot", "Discordbot"},
|
|
{"linkedinbot", "LinkedInBot"},
|
|
{"curl/", "curl"},
|
|
{"wget", "Wget"},
|
|
{"python-requests", "python-requests"},
|
|
{"python-urllib", "python-urllib"},
|
|
{"httpclient", "HTTP Client"},
|
|
{"go-http-client", "Go-http-client"},
|
|
{"java/", "Java Client"},
|
|
{"okhttp", "OkHttp"},
|
|
{"scrapy", "Scrapy"},
|
|
{"headlesschrome", "HeadlessChrome"},
|
|
{"puppeteer", "Puppeteer"},
|
|
{"phantomjs", "PhantomJS"},
|
|
{"bot;", "Bot"},
|
|
{"spider", "Spider"},
|
|
{"crawler", "Crawler"},
|
|
}
|
|
|
|
// ClassifyBot 根据 User-Agent 判定爬虫;命中返回爬虫展示名,否则返回空串。
|
|
// 纯小写包含匹配,便于单测。
|
|
func ClassifyBot(ua string) string {
|
|
low := strings.ToLower(strings.TrimSpace(ua))
|
|
if low == "" {
|
|
return ""
|
|
}
|
|
for _, sig := range botSignatures {
|
|
if strings.Contains(low, sig.token) {
|
|
return sig.name
|
|
}
|
|
}
|
|
return ""
|
|
}
|