我怎样才能获得html.Node的内容

时间:2013-08-16 13:29:02

标签: html-parsing go

我想使用http://godoc.org/code.google.com/p/go.net/html中的GO第三方库从网址获取数据。但我遇到了一个问题,就是我无法获得html.Node的内容。

参考文档中有一个示例代码,这是代码。

s := `<p>Links:</p><ul><li><a href="foo">Foo</a><li><a href="/bar/baz">BarBaz</a></ul>`
doc, err := html.Parse(strings.NewReader(s))
if err != nil {
    log.Fatal(err)
}
var f func(*html.Node)
f = func(n *html.Node) {
    if n.Type == html.ElementNode && n.Data == "a" {
        for _, a := range n.Attr {
            if a.Key == "href" {
                fmt.Println(a.Val)
                break
            }
        }
    }
    for c := n.FirstChild; c != nil; c = c.NextSibling {
        f(c)
    }
}
f(doc)

输出结果为:

foo
/bar/baz

如果我想要

Foo
BarBaz

我该怎么办?

1 个答案:

答案 0 :(得分:0)

<a href="link"><strong>Foo</strong>Bar</a>的树看起来基本上是这样的:

  • ElementNode“a”(此节点还包括属性列表)
    • ElementNode“strong”
      • TextNode“Foo”
    • TextNode“Bar”

因此,假设您想要获取链接的纯文本(例如FooBar),您必须走过树并收集所有文本节点。例如:

func collectText(n *html.Node, buf *bytes.Buffer) {
    if n.Type == html.TextNode {
        buf.WriteString(n.Data)
    }
    for c := n.FirstChild; c != nil; c = c.NextSibling {
        collectText(c, buf)
    }
}

你职能的变化:

var f func(*html.Node)
f = func(n *html.Node) {
    if n.Type == html.ElementNode && n.Data == "a" {
        text := &bytes.Buffer{}
        collectText(n, text)
        fmt.Println(text)
    }
    for c := n.FirstChild; c != nil; c = c.NextSibling {
        f(c)
    }
}