美文网首页
go小项目-html解析

go小项目-html解析

作者: c4a1d989518e | 来源:发表于2018-03-15 11:30 被阅读53次

    项目要求

    解析一个html页面,将其中的href标签中的链接地址和href标签所包裹的content内容,组成一个字典,打印出来
    如下图


    实现效果

    项目代码

    上面的图片是如下代码的运行结果。

    package main
    
    import (
        "fmt"
        "strings"
    
        "github.com/gophercises/link"
    )
    
    var exampleHtml = `
    <html>
    <body>
      <h1>Hello!</h1>
      <a href="/other-page">
        A link to another page
        <span> some span  </span>
      </a>
      <a href="/page-two">A link to a second page</a>
    </body>
    </html>
    `
    
    func main() {
        r := strings.NewReader(exampleHtml)
        links, err := link.Parse(r)
        if err != nil {
            panic(err)
        }
        fmt.Printf("%+v\n", links)
    }
    
    

    这段代码没有难点,主要是调用了一个link包,利用了其中的Parse函数。
    link包的代码如下:

    package link
    
    import (
        "io"
        "strings"
    
        "golang.org/x/net/html"
    )
    
    // Link represents a link (<a href="...">) in an HTML
    // document.
    type Link struct {
        Href string
        Text string
    }
    
    // Parse will take in an HTML document and will return a
    // slice of links parsed from it.
    func Parse(r io.Reader) ([]Link, error) {
        doc, err := html.Parse(r)
        if err != nil {
            return nil, err
        }
        nodes := linkNodes(doc)
        var links []Link
        for _, node := range nodes {
            links = append(links, buildLink(node))
        }
        return links, nil
    }
    
    func buildLink(n *html.Node) Link {
        var ret Link
        for _, attr := range n.Attr {
            if attr.Key == "href" {
                ret.Href = attr.Val
                break
            }
        }
        ret.Text = text(n)
        return ret
    }
    
    func text(n *html.Node) string {
        if n.Type == html.TextNode {
            return n.Data
        }
        if n.Type != html.ElementNode {
            return ""
        }
        var ret string
        for c := n.FirstChild; c != nil; c = c.NextSibling {
            ret += text(c)
        }
        return strings.Join(strings.Fields(ret), " ")
    }
    
    func linkNodes(n *html.Node) []*html.Node {
        if n.Type == html.ElementNode && n.Data == "a" {
            return []*html.Node{n}
        }
        var ret []*html.Node
        for c := n.FirstChild; c != nil; c = c.NextSibling {
            ret = append(ret, linkNodes(c)...)
        }
        return ret
    }
    

    项目学习点

    link包可以转换一下,用于其他html内容的提取,这个Parse函数具有一定的通用性,原来的github,给出了4个html页面,用来测试,均可以测试通过,所以此段代码是经过测试的代码。

    参考链接

    https://github.com/gophercises/link/tree/solution

    相关文章

      网友评论

          本文标题:go小项目-html解析

          本文链接:https://www.haomeiwen.com/subject/irofqftx.html