如何使用golang将HTML表转换为数组



我在尝试将 HTML 表转换为 Golang 数组时遇到问题。我试图使用 x/net/html 和 goquery 来实现它,但两者都没有成功。

假设我们有这个 HTML 表:

<html>
  <body>
    <table>
      <tr>
        <td>Row 1, Content 1</td>
        <td>Row 1, Content 2</td>
        <td>Row 1, Content 3</td>
        <td>Row 1, Content 4</td>
      </tr>
      <tr>
        <td>Row 2, Content 1</td>
        <td>Row 2, Content 2</td>
        <td>Row 2, Content 3</td>
        <td>Row 2, Content 4</td>
      </tr>
    </table>
  </body>
</html>

我想以这个数组结束:

------------------------------------
|Row 1, Content 1| Row 1, Content 2|
------------------------------------
|Row 2, Content 1| Row 2, Content 2|
------------------------------------

正如你们所看到的,我只是忽略了内容 3 和 4。

我的提取代码:

func extractValue(content []byte) {
  doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(content))
  doc.Find("table tr td").Each(func(i int, td *goquery.Selection) {
    // ...
  })
}

试图添加一个控制器号码,该号码将负责忽略我不想转换和调用的<td>

td.NextAll()

但没有运气。你们知道我应该怎么做才能完成它吗?

谢谢。

您只能使用套餐golang.org/x/net/html

var body = strings.NewReader(`                                                                                                                            
        <html>                                                                                                                                            
        <body>                                                                                                                                            
        <table>                                                                                                                                           
        <tr>                                                                                                                                              
        <td>Row 1, Content 1</td>                                                                                                                          
        <td>Row 1, Content 2</td>                                                                                                                          
        <td>Row 1, Content 3</td>                                                                                                                          
        <td>Row 1, Content 4</td>                                                                                                                          
        </tr>                                                                                                                                             
        <tr>                                                                                                                                              
        <td>Row 2, Content 1</td>                                                                                                        
        <td>Row 2, Content 2</td>                                                                                                                          
        <td>Row 2, Content 3</td>                                                                                                                          
        <td>Row 2, Content 4</td>                                                                                                                          
        </tr>  
        </table>                                                                                                                                          
        </body>                                                                                                                                           
        </html>`)          
func main() {
    z := html.NewTokenizer(body)
    content := []string{}
    // While have not hit the </html> tag
    for z.Token().Data != "html" {
        tt := z.Next()
        if tt == html.StartTagToken {
            t := z.Token()
            if t.Data == "td" {
                inner := z.Next()
                if inner == html.TextToken {
                    text := (string)(z.Text())
                    t := strings.TrimSpace(text)
                    content = append(content, t)
                }
            }
        }
    }
    // Print to check the slice's content
    fmt.Println(content)
}

代码仅针对此典型 HTML 模式编写,但重构它以使其更通用并不难。

如果您需要一种更结构化的方式来从 HTML 表中提取数据,https://github.com/nfx/go-htmltable 确实支持行/列跨

type AM4 struct {
    Model             string `header:"Model"`
    ReleaseDate       string `header:"Release date"`
    PCIeSupport       string `header:"PCIesupport[a]"`
    MultiGpuCrossFire bool   `header:"Multi-GPU CrossFire"`
    MultiGpuSLI       bool   `header:"Multi-GPU SLI"`
    USBSupport        string `header:"USBsupport[b]"`
    SATAPorts         int    `header:"Storage features SATAports"`
    RAID              string `header:"Storage features RAID"`
    AMDStoreMI        bool   `header:"Storage features AMD StoreMI"`
    Overclocking      string `header:"Processoroverclocking"`
    TDP               string `header:"TDP"`
    SupportExcavator  string `header:"CPU support[14] Excavator"`
    SupportZen        string `header:"CPU support[14] Zen"`
    SupportZenPlus    string `header:"CPU support[14] Zen+"`
    SupportZen2       string `header:"CPU support[14] Zen 2"`
    SupportZen3       string `header:"CPU support[14] Zen 3"`
    Architecture      string `header:"Architecture"`
}
am4Chipsets, _ := htmltable.NewSliceFromURL[AM4]("https://en.wikipedia.org/wiki/List_of_AMD_chipsets")
fmt.Println(am4Chipsets[2].Model)
fmt.Println(am4Chipsets[2].SupportZen2)
// Output:
// X370
// Varies[c]

尝试这样的方法来制作二维数组并处理可变的行大小:

    z := html.NewTokenizer(body)
    table := [][]string{}
    row := []string{}
    for z.Token().Data != "html" {
        tt := z.Next()
        if tt == html.StartTagToken {
            t := z.Token()
            if t.Data == "tr" {
                if len(row) > 0 {
                    table = append(table, row)
                    row = []string{}
                }
            }
            if t.Data == "td" {
                inner := z.Next()
                if inner == html.TextToken {
                    text := (string)(z.Text())
                    t := strings.TrimSpace(text)
                    row = append(row, t)
                }
            }
        }
    }
    if len(row) > 0 {
        table = append(table, row)
    }

相关内容

  • 没有找到相关文章

最新更新