使用Go从html解析列表项

时间:2015-03-28 15:05:36

标签: go

我想用Go提取所有列表项(每个<li></li>的内容)。我应该使用正则表达式获取<li>项目还是有其他任何库?

我的目的是在Go中获取一个包含特定html网页中所有列表项的列表或数组。我该怎么做?

2 个答案:

答案 0 :(得分:1)

您可能想要使用golang.org/x/net/html package。 它不在Go标准包中,而是在Go Sub-repositories中。 (子存储库是Go项目的一部分,但在主Go树之外。它们是在比Go核心更宽松的兼容性要求下开发的。)

该文档中有an example可能与您想要的类似。

如果由于某种原因需要坚持使用Go标准包,那么 for&#34;典型的HTML&#34;你可以使用encoding/xml

两个软件包都倾向于使用io.Reader进行输入。如果您有string[]byte变量,则可以使用strings.NewReaderbytes.Buffer对其进行换行,以获得io.Reader

对于HTML,您更有可能来自http.Response机构 (确保完成后关闭它)。 也许是这样的事情:

    resp, err := http.Get(someURL)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    doc, err := html.parse(resp.Body)
    if err != nil {
        return err
    }
    // Recursively visit nodes in the parse tree
    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)
}

当然,解析获取的网页对于在客户端使用JavaScript修改自己内容的页面不起作用。

答案 1 :(得分:0)

这是我找到解决这个问题的一种方法。

如果您尝试在li元素之后提取文本,则首先找到li元素,然后将标记生成器移动到下一个元素,这将是文本(希望如此)。如果下一个元素是锚点,跨度等,则可能必须使用某些逻辑。

resp, err := http.Get(url)
if err!=nil{
    log.Fatal(err)
}
defer resp.Body.Close()

z := html.NewTokenizer(bufio.NewReader(resp.Body))
for {
    tt := z.Next()
    switch tt {
    case html.ErrorToken:
        return
    case html.StartTagToken:
        t := z.Token()
        swith t.Data {
        case "li":
            z.Next()
            t = z.Token()
            fmt.Println(t.Data)
        }
    }
}

但实际上,您应该使用github.com/PuerkitoBio/goquery