使用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文件,以确保爬虫行为合法。
  • 频率限制: 避免过快地发送请求,以免被目标网站封禁。
相关推荐
爱勇宝34 分钟前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
AskHarries1 小时前
工具失败时怎么办:重试、回滚、人工确认和风险提示
后端·程序员
苏三说技术2 小时前
Claude Code从失控到起飞,只用了这些技巧
后端
天衍四九3 小时前
Git从0到实战(四):冲突解决与版本回退 —— 别怕,出错了也能救
github
长栎3 小时前
写 for 循环写了十年,你却从没用过迭代器模式最狠的那一面
后端
LiaCode3 小时前
Redis 在生产项目的使用
前端·后端
用户559822481223 小时前
Docker Compose Down 导致容器数据误删——ext4 日志恢复全记录
后端
LiaCode3 小时前
一天学完 redis 的爽翻版核心知识总结
前端·后端
大刚测试开发实战3 小时前
如何内网穿透访问本地私有化部署的TestHub
前端·后端·github
xiaodaoluanzha4 小时前
迄今為止,最簡單的編程語言 Nolang
前端·后端