我想用Go提取所有列表项(每个<li></li>
的内容)。我应该使用正则表达式获取<li>
项目还是有其他任何库?
我的目的是在Go中获取一个包含特定html网页中所有列表项的列表或数组。我该怎么做?
答案 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.NewReader
或bytes.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