使用Go语言编写简单爬虫程序

步骤1:导入必要的包

首先,你需要导入以下包:

  • net/http: 用于发送HTTP请求。
  • io : 用于读取响应内容(在Go 1.16及后续版本中,使用io.ReadAll代替ioutil.ReadAll)。
  • regexp: 用于正则表达式匹配(如果需要从HTML中提取特定信息)。
  • fmt: 用于打印输出。
go 复制代码
import (
    "fmt"
    "io"
    "log"
    "net/http"
    "regexp"
)

步骤2:定义函数获取网页源码

创建一个函数来发送GET请求并获取网页源码:

go 复制代码
func fetch(url string) (string, error) {
    resp, err := http.Get(url)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return string(body), nil
}

示例:设置User-Agent头

部分网站可能会根据User-Agent头来限制爬虫访问。可以通过设置http.Client的请求头来模拟浏览器的User-Agent:

go 复制代码
func fetchWithUserAgent(url string) (string, error) {
    client := &http.Client{}
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return "", err
    }
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3")

    resp, err := client.Do(req)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return string(body), nil
}

步骤3:解析HTML内容

如果你需要从HTML中提取特定信息,可以使用正则表达式。例如,提取所有链接:

go 复制代码
func extractLinks(html string) []string {
    re := regexp.MustCompile(`href="([^"]+)"`)
    matches := re.FindAllStringSubmatch(html, -1)
    var links []string
    for _, match := range matches {
        links = append(links, match[1])
    }
    return links
}

示例:提取所有图片URL

你也可以使用正则表达式提取所有图片URL:

go 复制代码
func extractImages(html string) []string {
    re := regexp.MustCompile(`src="([^"]+)"`)
    matches := re.FindAllStringSubmatch(html, -1)
    var images []string
    for _, match := range matches {
        images = append(images, match[1])
    }
    return images
}

步骤4:运行爬虫

在main函数中调用上述函数:

go 复制代码
func main() {
    url := "https://example.com"
    html, err := fetch(url)
    if err != nil {
        log.Fatal(err)
    }

    links := extractLinks(html)
    for _, link := range links {
        fmt.Println(link)
    }

    images := extractImages(html)
    fmt.Println("Images:")
    for _, image := range images {
        fmt.Println(image)
    }
}

完整代码

go 复制代码
package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "regexp"
)

func fetch(url string) (string, error) {
    resp, err := http.Get(url)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return string(body), nil
}

func fetchWithUserAgent(url string) (string, error) {
    client := &http.Client{}
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return "", err
    }
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3")

    resp, err := client.Do(req)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return string(body), nil
}

func extractLinks(html string) []string {
    re := regexp.MustCompile(`href="([^"]+)"`)
    matches := re.FindAllStringSubmatch(html, -1)
    var links []string
    for _, match := range matches {
        links = append(links, match[1])
    }
    return links
}

func extractImages(html string) []string {
    re := regexp.MustCompile(`src="([^"]+)"`)
    matches := re.FindAllStringSubmatch(html, -1)
    var images []string
    for _, match := range matches {
        images = append(images, match[1])
    }
    return images
}

func main() {
    url := "https://example.com"
    html, err := fetch(url)
    if err != nil {
        log.Fatal(err)
    }

    links := extractLinks(html)
    fmt.Println("Links:")
    for _, link := range links {
        fmt.Println(link)
    }

    images := extractImages(html)
    fmt.Println("Images:")
    for _, image := range images {
        fmt.Println(image)
    }
}

注意事项

  • User-Agent头 : 部分网站可能会根据User-Agent头来限制爬虫访问。可以通过设置http.Client的请求头来模拟浏览器的User-Agent。
  • robots.txt : 在爬取前,应检查目标网站的robots.txt文件,以确保爬虫行为合法。
  • 频率限制: 避免过快地发送请求,以免被目标网站封禁。
相关推荐
古希腊掌管代码的神THU10 分钟前
为什么DPO中chosen/rejected概率同时下降?
人工智能·深度学习·机器学习·自然语言处理·面试
金銀銅鐵32 分钟前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
Mk598782 小时前
给 Agent 装上对话框 —— AgentScope-Java 接入 Spring Boot 与 SSE 流式实战
后端
付威20232 小时前
从 Loop 到 Runtime:rpi Agent Loop 与 Cordis 的边界、取舍与组合
后端
IT_陈寒2 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
小奏技术3 小时前
为什么 2026 年了,我又写了一个 API 调试工具
github
miofly3 小时前
Kling 4.0 上线 API 调用,支持 30 秒原生音频视频生成
开源·github
考虑考虑4 小时前
JDK26的JEP 500属性
java·后端·java ee
miofly4 小时前
山东大学研究:代码智能体的复杂 harness 主要提升 token 消耗而非性能
开源·github