2017-02-24 121 views
-1

我正在嘗試使用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,但我不明白爲什麼特別是從不打印任何東西,不管我使用什麼網站。這是預期的行爲?

文檔:

https://godoc.org/golang.org/x/net/html#Node

https://github.com/golang/net/blob/master/html/node.go#L38

+0

嘗試檢查 '節點' 的內容。看看它是什麼類型等等。[go-spew](https://github.com/davecgh/go-spew)可以幫助解決這個問題。我懷疑node.Data沒有包含任何內容,並且可能有很好的理由。 – Flimzy

回答

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) 
} 
2

這是因爲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 
相關問題