package main
import (
"fmt"
"net/url"
"strings"
"github.com/Puerkitobio/purell"
"golang.org/x/net/publicsuffix"
)
func GetRootDomain(input string) (string, error) {
// 添加默认协议以便解析无协议的输入
if !strings.Contains(input, "://") && !strings.HasPrefix(input, "//") {
input = "http://" + input
}
// 规范化URL(处理冗余字符和路径)
normalized, err := purell.NormalizeURLString(input, purell.FlagsUsuallySafeNonGreedy)
if err != nil {
return "", fmt.Errorf("URL规范化失败: %v", err)
}
// 解析URL获取主机名
u, err := url.Parse(normalized)
if err != nil {
return "", fmt.Errorf("URL解析失败: %v", err)
}
hostname := u.Hostname()
if hostname == "" {
return "", fmt.Errorf("输入中未找到域名")
}
// 提取根域名(TLD+1)
root, err := publicsuffix.EffectiveTLDPlusOne(hostname)
if err != nil {
// 若无法提取(如纯TLD),返回原始域名
return hostname, nil
}
return root, nil
}
func main() {
testCases := []struct {
input string
expected string
}{
{"www.example.co.uk", "example.co.uk"},
{"http://blog.example.com", "example.com"},
{"https://sub.sub.example.org/path", "example.org"},
{"co.uk", "co.uk"}, // 纯TLD,无法提取更上一级
{"localhost", "localhost"}, // 特殊域名
{"something.appspot.com", "something.appspot.com"}, // 公共后缀的特殊处理
}
for _, tc := range testCases {
root, err := GetRootDomain(tc.input)
if err != nil {
fmt.Printf("错误: %v\n", err)
continue
}
fmt.Printf("输入: %-30s → 根域名: %-20s (预期: %s)\n", tc.input, root, tc.expected)
}
}
Was this helpful?
0 / 0