为了账号安全,请及时绑定邮箱和手机立即绑定

如何匹配 `<a>` 标记之前的文本然后返回 `<a>` 节点?

如何匹配 `<a>` 标记之前的文本然后返回 `<a>` 节点?

Go
森林海 2022-04-26 10:50:46
我有以下内容,我试图仅捕获文本匹配的第二种情况But I want this one here。目前,它涵盖了这两种情况。package mainimport (    "bytes"    "fmt"    "io"    "strings"    "golang.org/x/net/html")func getTag(doc *html.Node, tag string) []*html.Node {    var nodes []*html.Node    var crawler func(*html.Node)    crawler = func(node *html.Node) {        if node.Type == html.ElementNode && node.Data == tag {            nodes = append(nodes, node)            return        }        for child := node.FirstChild; child != nil; child = child.NextSibling {            crawler(child)        }    }    crawler(doc)    return nodes}func main() {    doc, _ := html.Parse(strings.NewReader(testHTML))    nodes := getTag(doc, "a")    var buf bytes.Buffer    w := io.Writer(&buf)    for i, node := range nodes {        html.Render(w, node)        if i < (len(nodes) - 1) {            w.Write([]byte("\n"))        }    }    fmt.Println(buf.String())}var testHTML = `<html><body>I do not want this link here <a href="blah">link text</a>But I want this one here <a href="blah blah">more link text</a></body></html>`这输出:<a href="blah">link text</a><a href="blah blah">more link text</a>我想匹配<a>标签之前的特定文本,如果匹配,则返回<a>节点。例如,传入But I want this one here并返回<a href="blah blah">more link text</a>. 有人告诉我不要用正则表达式解析 html,但现在我被卡住了。
查看完整描述

1 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

您实际上非常接近,因为您已经在使用正确的解析器(html.Parsefrom golang.org/x/net/html)。


这里的诀窍是页面的各种元素很方便地绑定在一起,所以crawler如果你愿意,你可以使用你现有的代码和以后的过滤功能。(您可以改为将过滤直接组合到爬虫中。)


每个n *html.ElementNode前面都有一些东西,除非它是块中的初始元素(文档的第一个元素或第一个子节点),并且某个东西在n.PrevSibling. 如果它的类型是html.TextNode你有一个形式的序列:


some text<a ...>thing</a>

您可以检查上一个节点中的“一些文本”:


func wanted(re *regexp.Regexp, n *html.Node) bool {

    if n.PrevSibling == nil || n.PrevSibling.Type != html.TextNode {

        return false

    }

    return re.MatchString(n.PrevSibling.Data)

}

这并不完美,因为您可以拥有,例如:


text <font></font> broken <font></font>up<a href="lastlink">last link</a>

并且代码将尝试匹配 string up,当您可能应该将文本放在一起text broken up并将其传递给匹配器时。在此处查看更完整的示例。


查看完整回答
反对 回复 2022-04-26
  • 1 回答
  • 0 关注
  • 142 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号