go語言解析html

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

有兩個不錯的庫:

https://github.com/PuerkitoBio/goquery

一個是

http://code.google.com/p/go.net/html

html是html的解析器,把html文本解析出來,goquery基於html包,在此基礎上結合cascadia 包(一個css選取器工具),實作類別似於jquery的功能,操作html非常方便。

使用goquery來尋找,選擇相應的html節點,但如果要對選擇的節點進行修改,刪除操作,還需要深入使用html包。

html包把html文本解析為一個樹,這個樹有很多Node組成,操作的核心就在於對Node的操作。

用幾個例子來說明一下吧:

doc, err := goquery.NewDocument("http://sports.sina.com.cn")

產生一個goquery的doc。

goquery用的最多的是Find函數,類似於jquery的$(),可以選擇dom結構。

例1:

dhead := doc.Find("head")dcharset := dhead.Find("meta[http-equiv]")charset, _ := dcharset.Attr("content")

這個例子用來找出頁面的charset。

例2:

logo := doc.Find("#retina_logo")

這個是根據html中的id來選擇dom

例3:

bread := doc.Find("div.blkBreadcrumbLink")

選擇doc中class為blkBreadcrumbLink的div

例4:

var faceImg stringvar innerImg = []string{}dom_body.Find("div.img_wrapper").Each(func(i int, s *goquery.Selection) {imgpath, exists := s.Find("img").Attr("src")if !exists {return}if i == 0 {faceImg = imgpath}innerImg = append(innerImg, imgpath)})

找出所有class為img_wrapper的div,然後在每個div下搜尋img,擷取img的src

例5:

dom_node := doc.Find("[bosszone='ztTopic']").Find("a")

這個是根據屬性/值來尋找相應的元素

如果要對html進行編輯操作,需要使用html.Node,這裡提供一個清洗div的代碼,使用了遞迴:

func clear_dom(pn *html.Node, isgb2312 bool) error {var err errorfor nd := pn.FirstChild; nd != nil; {switch nd.Type {case html.ElementNode:tn := strings.ToLower(nd.Data)//fmt.Printf("element node: %s\n", tn)if tn == "script" || tn == "style" {// delete the elementtmp := ndnd = tmp.NextSiblingpn.RemoveChild(tmp)} else if tn == "a" {tmp := ndnd = nd.NextSiblingif err = convert_dom(tmp, isgb2312); err != nil {return err}} else if tn == "span" {tmp := ndnd = nd.NextSiblingclear_dom(tmp, isgb2312)} else {tmp := ndnd = nd.NextSiblingif err = convert_dom(tmp, isgb2312); err != nil {return err}}case html.CommentNode:tmp := ndnd = tmp.NextSiblingpn.RemoveChild(tmp)case html.TextNode:tmp := ndnd = nd.NextSiblingif err = convert_dom(tmp, isgb2312); err != nil {return err}default:nd = nd.NextSibling}}return nil}

其中conver_dom是對node節點的text進行轉碼操作,如果不需要,可以忽略。

func Nodehtml(n *html.Node) string {var buf = bytes.NewBuffer([]byte{})html.Render(buf, n)return buf.String()}func Nodetext(node *html.Node) string {if node.Type == html.TextNode {// Keep newlines and spaces, like jQueryreturn node.Data} else if node.FirstChild != nil {var buf bytes.Bufferfor c := node.FirstChild; c != nil; c = c.NextSibling {buf.WriteString(Nodetext(c))}return buf.String()}return ""}

上面的兩個函數,分別擷取節點的html代碼和text代碼。html代碼和text代碼的區別是,html代碼是原封不動的html代碼,text代碼僅僅顯示html代碼的內容,例如一段html: 例子,它的text代碼是”例子”

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.