我正在制作一个网络刮板,我以前从未这样做过所以请指出我做错了什么
我正在使用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外部表标签中的所有内容吗?
答案 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>`