使用golang编写一个程序,获取给出域名的根域名,不是顶级域名

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

发表回复 0