| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- package crawler
- import (
- "net/url"
- "regexp"
- "strings"
- )
- // FilterResult URL 过滤结果
- type FilterResult int
- const (
- FilterDiscard FilterResult = iota // 直接丢弃
- FilterValid // 确定是导航站
- FilterUncertain // 不确定,需 LLM 判断
- )
- // 黑名单域名
- var blacklistDomains = []string{
- "t.me", "telegram.me", "twitter.com", "x.com", "facebook.com",
- "instagram.com", "youtube.com", "google.com", "baidu.com",
- "weibo.com", "zhihu.com", "github.com", "stackoverflow.com",
- "wikipedia.org", "amazon.com", "taobao.com", "jd.com", "tmall.com",
- "qq.com", "163.com", "126.com", "sina.com.cn", "sohu.com",
- "tencent.com", "alipay.com", "wechat.com", "apple.com",
- "microsoft.com", "windows.com", "android.com",
- }
- // 黑名单扩展名
- var blacklistExtensions = []string{
- ".apk", ".zip", ".pdf", ".exe", ".dmg", ".ipa", ".rar", ".7z",
- ".mp4", ".mp3", ".avi", ".jpg", ".png", ".gif", ".svg",
- ".css", ".js", ".json", ".xml",
- }
- // 黑名单路径片段
- var blacklistPaths = []string{
- "/api/", "/login/", "/logout/", "/register/", "/signup/",
- "/wp-admin/", "/admin/", "?ref=", "?utm_", "/cdn-cgi/",
- }
- // 正向信号
- var navSignals = []string{
- "nav", "directory", "catalog", "daohang", "dh", "list",
- "导航", "目录", "聚合", "推荐", "收录",
- }
- // RuleFilter 规则引擎过滤
- func RuleFilter(rawURL string) FilterResult {
- u, err := url.Parse(rawURL)
- if err != nil {
- return FilterDiscard
- }
- host := strings.ToLower(u.Hostname())
- path := strings.ToLower(u.Path)
- fullURL := strings.ToLower(rawURL)
- // 黑名单域名
- for _, d := range blacklistDomains {
- if strings.Contains(host, d) {
- return FilterDiscard
- }
- }
- // 黑名单扩展名
- for _, ext := range blacklistExtensions {
- if strings.HasSuffix(path, ext) {
- return FilterDiscard
- }
- }
- // 黑名单路径
- for _, p := range blacklistPaths {
- if strings.Contains(fullURL, p) {
- return FilterDiscard
- }
- }
- // 正向信号
- for _, sig := range navSignals {
- if strings.Contains(fullURL, sig) {
- return FilterValid
- }
- }
- return FilterUncertain
- }
- // ExtractDomain 提取域名
- func ExtractDomain(rawURL string) string {
- u, err := url.Parse(rawURL)
- if err != nil {
- return ""
- }
- return u.Hostname()
- }
- // ExtractTGUsername 从 URL 提取 TG 用户名
- func ExtractTGUsername(rawURL string) string {
- re := regexp.MustCompile(`t(?:elegram)?\.me/([a-zA-Z][a-zA-Z0-9_]{4,31})`)
- m := re.FindStringSubmatch(rawURL)
- if len(m) > 1 {
- return m[1]
- }
- return ""
- }
|