这个程序为什么不打印任何东西?
问题描述:
我正在尝试使用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,但我不明白为什么特别是从不打印任何东西,不管我使用什么网站。这是预期的行为?
文档:
答
,因为它是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)
}
答
这是因为html.Parse返回连接节点的树。而根节点的类型是“文档”,里面没有数据。如何走树
简单的例子:
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)
}
OUTPUT:
NodeType=DocumentNode Data=
NodeType=ElementNode Data=html
NodeType=ElementNode Data=head
NodeType=ElementNode Data=body
NodeType=ElementNode Data=p
NodeType=TextNode Data=Some content
尝试检查 '节点' 的内容。看看它是什么类型等等。[go-spew](https://github.com/davecgh/go-spew)可以帮助解决这个问题。我怀疑node.Data没有包含任何内容,并且可能有很好的理由。 – Flimzy