使用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文件,以确保爬虫行为合法。
  • 频率限制: 避免过快地发送请求,以免被目标网站封禁。
相关推荐
weixin_4316004420 分钟前
Agent Workflow 学习向:Code 节点,比模板更强的变量加工
后端·python·学习·ai·
Rain的Java大神之路37 分钟前
短信接口被狂刷怎么处理
java·运维·后端·web安全·面试·架构·xss
Lost of 程序猿1 小时前
AOP 实战:面向切面编程从理论到落地
后端·asp.net·aop·面向切片变成
Lost of 程序猿2 小时前
ASP.NET Core 认证授权实战:从 JWT 到 Policy,设计一套企业级 RBAC 权限系统
后端·asp.net
Lost of 程序猿2 小时前
ASP.NET Core 后台任务全景:从 BackgroundService 到 Channel 队列,再到分布式调度
后端·asp.net·.netcore
倾颜2 小时前
NestJS 核心概念梳理:从 Module、Controller 到 Guard、Interceptor
后端·node.js·nestjs
东风破_3 小时前
JWT 1:从一个登录请求开始,理解 React 项目里的 API 层与 Mock
前端·后端
东风破_3 小时前
JWT 3:为什么 Token 要放进 Authorization?Axios 拦截器到底解决了什么?
前端·后端
东风破_3 小时前
JWT 5:路由守卫是什么?把整个 JWT 登录鉴权流程串起来
前端·后端
东风破_3 小时前
JWT 2:HTTP 是无状态的,为什么登录成功后还要给 Token?
前端·后端