应优先使用goquery或golang.org/x/net/html解析dom提取链接,正则仅适用于极简可控场景;因html结构多变、编码复杂、易受注释和js干扰,正则易漏匹配、性能差且难维护。

别用正则直接扫整个 HTML 字符串提取 @#@#@#@#@#@#@#@#@#@0);二是做预处理,比如从 DOM 提取的纯文本中再捞 URL(此时已无标签干扰)。
- 用
regexp.FindAllStringSubmatch比FindAllString更安全:它能分离捕获组,避免手动切字符串出错 - 正则模式别写太宽,例如
`href=["']([^"']+)["']`比`<a>]*href=["']([^"']*)["'][^>]*>`</a>更稳定——前者只关心属性值,后者还得匹配整个标签结构 - 如果必须匹配带文本的链接,用命名捕获组 +
FindAllStringSubmatchIndex配合string()切片更可控,避免[][]byte转换出错 - 永远设超时:正则匹配失控时会卡死,尤其面对畸形 HTML,建议用
regexp.CompilePOSIX(更保守)或限制最大匹配长度
golang.org/x/net/html 解析的轻量替代方案
如果你不想引入 goquery(它依赖 net/html + jQuery 风格封装),又觉得正则太脆,net/html 原生 API 是最小依赖解法,但要注意递归边界和内存管理。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 别用
html.Parse(io.Reader)直接读大文件——它会一次性加载全部节点到内存,10MB HTML 可能吃掉 50MB+ RAM - 遍历用
forEachNode递归函数,但务必在n.Type == html.ElementNode && n.Data == "a"时立即提取href属性,不要攒全量节点再处理 - 提取属性得手动遍历
n.Attrslice,href不一定在第一个位置,需循环比对key == "href" - 注意相对 URL:
href值可能是/path或./img.png,要用url.URL.ResolveReference转成绝对地址,否则后续请求会 404
真正耗时的从来不是“怎么写正则”或“怎么选库”,而是字符编码判断、Body 是否被提前读取、HTTP 状态码忽略、相对路径未补全这四点——它们不出错时一切顺利,一出就是静默失败。
doc, err := goquery.NewDocumentFromReader(bufio.NewReader(resp.Body))
if err != nil {
return nil, err
}
var links []string
doc.Find("a").Each(func(i int, s *goquery.Selection) {
if href, ok := s.Attr("href"); ok && href != "" {
links = append(links, href)
}
})
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










