在 Go 中,使用 net/http 包可以轻松实现一个简单的爬虫。基本的爬虫通常需要以下几个步骤:
- 向目标网站发送 HTTP 请求。
- 获取并解析响应(如 HTML)。
- 提取并处理其中的链接或其他数据。
- 遇到新的链接时,递归地爬取。
下面是一个简单的示例,展示了如何使用 Go 的 net/http 和 /x/net/html 包来抓取网页并解析其中的链接。
示例代码:简单的 HTTP 爬虫
package main
import (
"fmt"
"/x/net/html"
"net/http"
"os"
"log"
"strings"
)
func main() {
url := "https://example.com" // 你想爬取的目标URL
// 调用爬取函数
links, err := getLinks(url)
if err != nil {
log.Fatal(err)
}
// 打印所有爬到的链接
for _, link := range links {
fmt.Println(link)
}
}
// getLinks 请求页面并解析其中的所有链接
func getLinks(url string) ([]string, error) {
// 发起 HTTP 请求
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("请求失败: %v", err)
}
defer resp.Body.Close()
// 检查响应状态
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("响应错误: %v", resp.StatusCode)
}
// 解析 HTML
doc, err := html.Parse(resp.Body)
if err != nil {
return nil, fmt.Errorf("HTML解析失败: %v", err)
}
// 提取页面中的链接
var links []string
var f func(*html.Node)
f = func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "a" {
// 提取 <a> 标签的 href 属性
for _, attr := range n.Attributes {
if attr.Key == "href" {
link := attr.Val
// 过滤掉空链接和不以 http 或 https 开头的链接
if link != "" && (strings.HasPrefix(link, "http") || strings.HasPrefix(link, "https")) {
links = append(links, link)
}
break
}
}
}
}
// 遍历 HTML 文档
_ = traverseHTML(doc, f)
return links, nil
}
// traverseHTML 遍历 HTML 文档的节点
func traverseHTML(n *html.Node, f func(*html.Node)) {
if n == nil {
return
}
f(n)
for c := n.FirstChild; c != nil; c = c.NextSibling {
traverseHTML(c, f)
}
}代码说明:
- HTTP 请求:使用
http.Get(url)发起 HTTP 请求获取页面内容。 - HTML 解析:使用
/x/net/html包解析 HTML 文档。html.Parse将返回一个 HTML 树的根节点。 - 提取链接:通过递归遍历 HTML 节点,找到
<a>标签并提取其href属性,得到页面上的链接。 - 过滤链接:为了避免抓取到不相关的链接(如空链接、相对路径链接等),我们只提取以
http或https开头的链接。
如何运行:
- 安装依赖:运行爬虫前,需要安装
/x/net/html包:
go get /x/net/html- 运行代码:直接运行
go run main.go,如果目标 URL 存在,程序会爬取并打印出页面中的所有链接。
示例输出:
假设爬取的页面包含以下链接:
https://example.com/about
https://example.com/contact
https://example.com/privacy爬虫将输出:
https://example.com/about
https://example.com/contact
https://example.com/privacy注意事项:
- 爬取频率:在实际爬虫中,频繁请求服务器可能会导致服务器负担过重或触发反爬虫机制。可以考虑加入延时、限制请求频率等。
- 爬虫礼仪:请遵守目标网站的
robots.txt文件规则,避免爬取不允许的页面。 - 递归爬取:如果想要递归地爬取其他链接,可以在提取到链接后再次调用
getLinks对这些链接进行爬取。要注意设置深度限制和防止爬虫陷入死循环。
进一步优化:
- 你可以增加并发请求来提高爬取速度,使用 Go 的 goroutine 和 channel 来并发地抓取多个页面。
- 使用 Go 的
time.Sleep来控制爬取间隔,避免过于频繁的请求导致被封禁。
















