如何在golang中访问内部标记令牌?

时间:2016-10-09 19:34:02

标签: html go web-scraping

我正在制作一个网络刮板,我以前从未这样做过所以请指出我做错了什么

我正在使用golang来废弃

假设我有一张桌子

<table>
   <tr>
         <td>XYZ</td>
         <td>XYZ</td>
         <td>XYZ</td> 
   </tr>
   <tr>
         <td>XYZ</td>
         <td>XYZ</td>
         <td>XYZ</td> 
   </tr>
   <tr>
         <td>XYZ</td>
         <td>XYZ</td>
         <td>XYZ</td> 
   </tr>
   <tr>
         <td>XYZ</td>
         <td>XYZ</td>
         <td>XYZ</td> 
   </tr>
</table>

我想从每个tr中提取数据,但只提取第二个td

我也可以返回一个新的html字符串,只包含table标签内的内容并删除html外部表标签中的所有内容吗?

2 个答案:

答案 0 :(得分:1)

首先,您的HTML示例错误,您错过了所有关闭标记&lt; / tr &gt; &lt; / td &gt;

对于这种工作总是更好地使用某种DOM选择器,如jQuery。对于Go我推荐goquery,这是一个小小的库,效果很好。你的解决方案:

package main

import (
    "log"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    doc, err := goquery.NewDocument("http://your.url.com/foo.html")
    if err != nil {
        log.Fatal(err)
    }

    doc.Find("table tr").Each(func(_ int, tr *goquery.Selection) {

        // for each <tr> found, find the <td>s inside
        // ix is the index
        tr.Find("td").Each(func(ix int, td *goquery.Selection) {

            // print only the td number 2 (index == 1)
            if ix == 1 {
                log.Printf("index: %d content: '%s'", ix, td.Text())
            }
        })
    })
}

您可能会注意到 td.Text()包含每个 td 标记的内容。 我留下了用于测试https://play.golang.org/p/Rtb1Tqz1Wb

的完整文件

答案 1 :(得分:0)

使用golang.org/x/net/html的另一种方式。

(NB速度可以通过将t.DataAtom替换为t.Data来获得,因为整数匹配可能更有效。)

package main

// https://stackoverflow.com/questions/39947716/how-to-access-inner-tags-token-in-golang

import (
    "fmt"
    "strings"

    "golang.org/x/net/html"
)

func main() {

    r := strings.NewReader(s)

    z := html.NewTokenizer(r)

    i := 0

    for {
        tt := z.Next()
        switch tt {

        case html.ErrorToken:
            return

        case html.StartTagToken:
            t := z.Token()

            switch t.Data {

            case "tr":
                i = 0

            case "td":
                if i == 1 {
                    z.Next()
                    t = z.Token()
                    fmt.Println(t.Data)
                }
                i++
            }
        }
    }
}

var s string = `
<table>
   <tr>
         <td>XYZ</td>
         <td>keep</td>
         <td>XYZ</td> 
   </tr>
   <tr>
         <td>XYZ</td>
         <td>it</td>
         <td>XYZ</td> 
   </tr>
   <tr>
         <td>XYZ</td>
         <td>simple</td>
         <td>XYZ</td> 
   </tr>
   <tr>
         <td>XYZ</td>
         <td>sister</td>
         <td>XYZ</td> 
   </tr>
</table>`

https://play.golang.org/p/tAORrHy8eFJ