网络爬虫是一种从网站中提取数据的技术,也是从互联网收集信息的一款强力工具。本文将探讨如何使用Go语言(一种以简单易用、支持并发以及功能强大的标准库而闻名的流行编程语言)来爬取HTML表格。
引言
什么是 HTML 表格?
HTML表格是HTML(超文本标记语言)中的一种元素,用于在网页上呈现表格数据。一个HTML表格由包含文本、图像或其他HTML元素的单元格行和列组成。HTML表格通过table元素创建,其结构由‘<tr>’(表格行)、‘<td>(表格单元格)、‘<th>’(表格标题)、‘<caption>’、‘<col>’、‘<colgroup>’、‘<tbody>’(表格主体)、‘<thead>’(表格页眉)以及‘<tfoot>’(表格页脚)等元素构建而成。现在让我们逐一详细探讨:
- table 元素:定义 HTML 表格的起始和结束。
- tr(表格行)元素:定义 HTML 表格中的一行。
- td(表格单元格)元素:定义 HTML 表格中的一个单元格。
- th(表格标题)元素:定义 HTML 表格中的标题单元格。标题单元格默认以粗体居中显示,用于标注表格的行或列。
- caption 元素:定义 HTML 表格的标题。标题通常显示在表格上方或下方。
- col 和 colgroup 元素:定义 HTML 表格中列的属性,例如宽度或对齐方式。
- tbody、thead 和 tfoot 元素:分别定义 HTML 表格的主体、表头和表尾部分。这些元素可用于分组行,并为表格的特定部分应用样式或属性。
为了更好地理解这一概念,让我们看看 HTML 表格是什么样子的:
乍看之下,它似乎是一个普通的表格,我们无法看到上述元素构成的结构。这并不意味着它们不存在,而是浏览器已经为我们解析了这些内容。为了查看 HTML 结构,你需要深入一步并使用开发者工具。 具体操作方法是:右键点击页面,选择“检查”,点击“选择元素”工具,然后点击您想查看其 HTML 结构的元素(本例中为 table)。完成这些步骤后,您应该会看到类似以下内容:
HTML表格常用于以结构化、表格化的形式呈现数据,例如整理结果或展示数据库内容。它们广泛存在于各类网站中,也是从网络抓取数据时需要重点考虑的元素。
环境配置
在开始抓取之前,我们需要配置 Go 开发环境并安装必要的依赖项。请确保您的系统已安装并配置好 Go 语言,然后创建一个新的项目目录并初始化 `go.mod` 文件:
$ mkdir scraping-project
$ cd scraping-project
$ go mod init <NAME-OF-YOUR-PROJECT>$ touch main.go
接下来,我们需要安装用于发送 HTTP 请求和解析 HTML 的库。虽然有多种选择,但本文将使用标准库中的 `net/http` 包以及用于解析 HTML 的 golang.org/x/net/html 包。可通过运行以下命令安装这些包:
$ go get -u net/http golang.org/x/net/html
现在环境已准备就绪,我们可以开始使用 Golang 构建 HTML 表格抓取工具了。
开始抓取
环境配置完成后,我们可以开始构建用于从 HTML 表格中提取数据的爬虫。第一步是向包含目标 HTML 表格的网页发送 HTTP 请求。我们可以使用 `net/http` 包中的 `http.Get` 函数发送 GET 请求并获取 HTML 内容:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
resp, err := http.Get("https://www.w3schools.com/html/html_tables.asp")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Read the response body and convert it to a string
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
html := string(body)
fmt.Println(html)
}接下来,我们可以使用 goquery 包中的 `goquery.NewDocumentFromReader` 函数来解析 HTML 内容并提取所需数据。与其他 Go 语言包一样,您需要先按以下方式安装它:
$ go get github.com/PuerkitoBio/goquery
然后添加以下代码来解析页面的 HTML:
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
log.Fatal(err)
}现在我们已经有了 HTML 解析器和元素提取器,可以利用 Goquery 包的 `doc.Find()` 功能来查找我们需要的特定元素,在本例中即为表格。使用方法如下:
doc.Find("table").Each(func(i int, sel * goquery.Selection) {
// For sake of simplicity taking the first table of the page
if i == 0 {
// Looping through headers
headers: = sel.Find("th").Each(func(_ int, sel * goquery.Selection) {
if sel != nil {
fmt.Print(sel.Text())
fmt.Print(" ")
}
})
fmt.Println()
// Looping through cells
sel.Find("td").Each(func(index int, sel * goquery.Selection) {
if sel != nil {
fmt.Print(sel.Text())
fmt.Print(" ")
}
// Printing columns nicely
if (index + 1) % headers.Size() == 0 {
fmt.Println()
}
})
}
})就这样,您现在已经能够使用 Go 语言抓取表格,屏幕上应该会显示如下内容:
您可能已经注意到,这种结构可能相当混乱且难以阅读。好消息是,您可以做得更好,将数据以易于阅读的表格格式美观地展示出来。这正是 tablewriter 包的绝佳用武之地,您可以按以下方式安装它:
$ go get github.com/olekukonko/tablewriter
现在,在将数据传递给 tablewriter 之前,我们需要对代码进行一些调整,例如定义表格标题、结构体并将它们存储到数组中。代码应类似如下:
package main
import (
"log"
"net/http"
"os"
"github.com/PuerkitoBio/goquery"
"github.com/olekukonko/tablewriter"
)
type Company struct {
Company string
Contact string
Country string
}
func main() {
resp, err := http.Get("https://www.w3schools.com/html/html_tables.asp")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Read the response body and convert it to a string
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
log.Fatal(err)
}
var companies []Company
doc.Find("table").Each(func(i int, sel *goquery.Selection) {
if i == 0 {
e := Company{}
sel.Find("td").Each(func(index int, sel *goquery.Selection) {
if index%3 == 0 {
e.Company = sel.Text()
}
if index%3 == 1 {
e.Contact = sel.Text()
}
if index%3 == 2 {
e.Country = sel.Text()
}
// Add the element to our array
if index != 0 && (index+1)%3 == 0 {
companies = append(companies, e)
}
})
}
})
table := tablewriter.NewWriter(os.Stdout)
// Setting our headers
table.SetHeader([]string{"Company", "Contact", "Country"})
for _, Company := range companies {
s := []string{
Company.Company,
Company.Contact,
Company.Country,
}
table.Append(s)
}
table.Render()
}现在,您应该能够看到数据以这种格式显示:
至此,你已成功用 Go 语言构建了一个能抓取网页、并以美观形式存储和展示数据的爬虫。你还可以修改代码,从其他网站抓取表格数据。 请注意,并非所有网站都像这样容易抓取数据。许多网站都实施了高级防护措施来防止抓取,例如验证码(CAPTCHA)和IP地址封禁,但幸运的是,有第三方服务(如WebScrapingAPI)提供IP轮换和验证码绕过功能,使您能够抓取这些目标。
深入探讨
虽然我们迄今介绍的技术足以应对简单的 HTML 表格,但仍有多种方法可以对其进行改进。
一个潜在问题是,不同网页的 HTML 表格结构可能不一致。例如,表格的列数可能不同,或者数据可能嵌套在不同的 HTML 元素中。为处理这些情况,您可以使用更高级的技术,如 CSS 选择器或 XPath 表达式,来定位需要提取的数据。
另一个问题是,网页通常会使用 AJAX 或其他客户端技术,在页面加载到浏览器后继续加载额外数据。这意味着您正在抓取的 HTML 表格可能并不包含您所需的所有数据。 要抓取此类页面,您可能需要使用无头浏览器等工具,它能像普通网页浏览器一样执行 JavaScript 并渲染页面。一个不错的替代方案是使用我们的抓取工具,它能在页面完成 JavaScript 渲染后返回数据。您可查阅我们的文档了解更多详情。
最后,务必考虑爬虫的性能和可扩展性。如果您需要抓取大型表格或多页内容,可能需要采用并发处理或速率限制等技术,以确保爬虫能够承受工作负载。
总结
希望本文能为您使用 Go 语言抓取 HTML 表格提供一个良好的起点。我们已详细演示了如何使用 Go 编程语言从 HTML 表格中抓取数据。 我们探讨了如何获取网页的 HTML 内容,将其输出到屏幕上,并以表格形式呈现,便于人眼阅读。此外,我们还讨论了在抓取 HTML 表格时可能遇到的挑战,包括表格结构不一致、客户端数据加载,以及性能和可扩展性问题。
虽然您可以利用本文所述的技术构建自己的爬虫,但使用专业的爬取服务通常更为高效且可靠。这些服务具备完善的基础设施、专业技术及安全措施,能够处理海量数据和复杂的爬取任务,并且通常能以 CSV 或 JSON 等结构化且便捷的格式提供数据。
总而言之,抓取 HTML 表格是提取网络数据的一种有效方法,但必须仔细权衡自行构建抓取工具与使用专业服务之间的利弊。




