我试图使用Go来解析HTML。我想将html打印到终端,我不明白为什么这不会打印任何东西:
package main
import (
"fmt"
"log"
"net/http"
"golang.org/x/net/html"
)
func main() {
r, err := http.Get("https://google.com")
if err != nil {
log.Panicln(err)
}
defer func() {
err := r.Body.Close()
if err != nil {
fmt.Println(err)
}
}()
node, err := html.Parse(r.Body)
if err != nil {
log.Panicln(err)
}
fmt.Println(node.Data)
}
我知道有不同的方法来打印html,但我不明白为什么这个特别是从来没有打印任何东西,无论我使用什么网站。这是预期的行为吗?
文档:
答案 0 :(得分:2)
因为它是HTML的树。上层是空的。 例如,如果您需要解析来自html的所有网址:
package main
import (
"fmt"
"log"
"net/http"
"golang.org/x/net/html"
)
func main() {
r, err := http.Get("https://google.com")
if err != nil {
log.Panicln(err)
}
defer func() {
err := r.Body.Close()
if err != nil {
fmt.Println(err)
}
}()
node, err := html.Parse(r.Body)
if err != nil {
log.Panicln(err)
}
fmt.Println(node.Data)
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(node)
}
答案 1 :(得分:2)
这是因为html.Parse返回连接节点的树。并且根节点的类型为" document"里面没有数据。
如何走树的简单示例:
package main
import (
"fmt"
"golang.org/x/net/html"
"strings"
)
func nodeTypeAsString(nodeType html.NodeType) string{
switch(nodeType){
case html.ErrorNode : return "ErrorNode"
case html.TextNode : return "TextNode"
case html.DocumentNode : return "DocumentNode"
case html.ElementNode : return "ElementNode"
case html.CommentNode : return "CommentNode"
case html.DoctypeNode: return "DoctypeNode"
}
return "UNKNOWN"
}
func main() {
s := "<html><body><p>Some content</p></body></html>"
node, err := html.Parse(strings.NewReader(s))
if err != nil {
panic(err.Error())
}
// Root node
fmt.Printf("NodeType=%s Data=%s\n",nodeTypeAsString(node.Type),node.Data)
// Step deeper
node = node.FirstChild
fmt.Printf("NodeType=%s Data=%s\n",nodeTypeAsString(node.Type),node.Data)
// Step deeper
node = node.FirstChild
fmt.Printf("NodeType=%s Data=%s\n",nodeTypeAsString(node.Type),node.Data)
// Step over to sibling
node = node.NextSibling
fmt.Printf("NodeType=%s Data=%s\n",nodeTypeAsString(node.Type),node.Data)
// Step deeper
node = node.FirstChild
fmt.Printf("NodeType=%s Data=%s\n",nodeTypeAsString(node.Type),node.Data)
// Step deeper
node = node.FirstChild
fmt.Printf("NodeType=%s Data=%s\n",nodeTypeAsString(node.Type),node.Data)
}
输出:
NodeType=DocumentNode Data=
NodeType=ElementNode Data=html
NodeType=ElementNode Data=head
NodeType=ElementNode Data=body
NodeType=ElementNode Data=p
NodeType=TextNode Data=Some content