feat: 站点访问统计与可配置侧边栏组件
- 新增访问统计:visitstats 服务与查询、visit_capture 中间件、爬虫/来源识别、管理端 analytics 页面 - 新增侧边栏:sidebar 服务与 handler、管理端 sidebar 配置页、前端侧边栏组件 - 新增 widget 嵌入代码生成(widgetCode)与 widgetApi - 遥测逻辑迁移至 handler 层,删除 service/telemetry - env 示例补充 Docker 部署可信代理 IP 说明
This commit is contained in:
69
backend/service/visit_bot.go
Normal file
69
backend/service/visit_bot.go
Normal file
@@ -0,0 +1,69 @@
|
||||
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 ""
|
||||
}
|
||||
Reference in New Issue
Block a user