admin 管理员组

文章数量: 887021

文章目录

  • 爬虫
  • 第一个爬虫
  • colly爬虫框架
    • colly爬虫示例-爬取图片
    • colly采集器配置
    • Callbacks
      • Add callbacks to a Collector
      • Call order of callbacks
        • 1. OnRequest
        • 2. OnError
        • 3. OnResponse
        • 4. OnHTML
        • 5. OnXML
        • 6. OnScraped
    • OnHTML方法
  • 参考资料

爬虫

很多语言都可以写爬虫,包括python,java、c++、Pythhon等。而Go本身是开源的,很多大佬为Python的功能扩展写了很多成熟的工具,也就是网络上常说的xx库,我们可以利用这些工具快速实现我们的需求,比较好入门。

另外,需要强调的是,网络上并不是什么东西都可以爬,针对这个问题,我国有着一套完备的法律。爬了不该爬的内容,比如大量个人信息,那可以快速实现“从入门到入狱”。

第一个爬虫

我们仅用go标准库来试试看。
先用新建项目目录

# 创建项目目录
mkdir firstProject
# 进入目录
cd firstProject
# 初始化项目
go mod init gitcode/m
# 创建main文件
touch main.go

粘贴下面代码

package main

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

func main() {
	resp, err := http.Get("https://www.baidu")
	if err != nil {
		fmt.Println("请求失败:", err)
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取响应失败:", err)
	}
	fmt.Println(string(body))
}

在cmder窗口运行

$ go build
$ .\m.exe

或者go build && m


成功返回网页。仅用标准库有很大的局限性.

colly爬虫框架

colly 是 Go 实现的比较有名的一款爬虫框架,而且 Go 在高并发和分布式场景的优势也正是爬虫技术所需要的。它的主要特点是轻量、快速,设计非常优雅,并且分布式的支持也非常简单,易于扩展。

colly爬虫示例-爬取图片

先在cmder窗口执行go get github/gocolly/colly 安装colly模块。安装后,go.mod多了一些依赖项模块。


代码

package main

import (
	"fmt"
	"github/gocolly/colly"
	"io"
	"math/rand"
	"net/http"
	"os"
	"strconv"
)

func main() {
	//创建采集器对象
	c := colly.NewCollector()

	// 在访问页面之前执行的回调函数
	c.OnRequest(func(r *colly.Request) {
		fmt.Println("Visiting", r.URL.String())
	})

	// 在访问页面之后执行的回调函数
	c.OnResponse(func(r *colly.Response) {
		fmt.Println("Visited", r.Request.URL.String())
	})

	// 在访问页面时发生错误时执行的回调函数
	c.OnError(func(r *colly.Response, err error) {
		fmt.Println("Error:", err)
	})

	// 在访问页面时发现图片时执行的回调函数
	c.OnHTML(".bizhi_tjs img", func(e *colly.HTMLElement) {
		url := e.Attr("src")
		if url != "" {
			fmt.Println("Found image:", url)
			resp, err := http.Get(url)
			if err != nil {
				fmt.Println("Error:", err)
				return
			}
			defer resp.Body.Close()

			randnum := rand.Intn(90) + 10
			strRandnum := strconv.Itoa(randnum)
			filename := "E:\\Download\\img\\" + strRandnum + ".jpg"
			file, err := os.Create(filename)
			if err != nil {
				fmt.Println("Error:", err)
				return
			}
			defer file.Close()

			io.Copy(file, resp.Body)
			fmt.Println("Image saved to", file.Name())
		}
	})

	// 发起访问  输入你要访问的网址
	c.Visit("https://www.bizhizu/bizhi/10231.html")
}

运行go build && m

colly采集器配置

  • AllowedDomains: 设置收集器使用的域白名单,设置后不在白名单内链接,报错:Forbidden domain
  • AllowURLRevisit: 设置收集器允许对同一 URL 进行多次下载。
  • Async: 设置收集器为异步请求,需很Wait()配合使用。
  • Debugger: 开启Debug,开启后会打印请求日志。
  • MaxDepth: 设置爬取页面的深度。
  • UserAgent: 设置收集器使用的用户代理。
  • MaxBodySize : 以字节为单位设置检索到的响应正文的限制。
  • IgnoreRobotsTxt: 忽略目标机器中的robots.txt声明。

创建采集器

collector := colly.NewCollector(
	colly.AllowedDomains("www.baidu",".baidu"),//白名单域名
	colly.AllowURLRevisit(),//允许对同一 URL 进行多次下载
	colly.Async(true),//设置为异步请求
	colly.Debugger(&debug.LogDebugger{}),// 开启debug
	colly.MaxDepth(2),//爬取页面深度,最多为两层
	colly.MaxBodySize(1024 * 1024),//响应正文最大字节数
	colly.UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "),
	colly.IgnoreRobotsTxt(),//忽略目标机器中的`robots.txt`声明
)

配置可以写在里面,也可以写在外面。

Callbacks

You can attach different type of callback functions to a Collector to control a collecting job or retrieve information. Check out the related section in the package documentation.

您可以将不同类型的回调函数附加到“收集器”,以控制收集作业或检索信息。查看软件包文档中的相关部分。

Add callbacks to a Collector

c.OnRequest(func(r *colly.Request) {
    fmt.Println("Visiting", r.URL)
})

c.OnError(func(_ *colly.Response, err error) {
    log.Println("Something went wrong:", err)
})

c.OnResponse(func(r *colly.Response) {
    fmt.Println("Visited", r.Request.URL)
})

c.OnHTML("a[href]", func(e *colly.HTMLElement) {
    e.Request.Visit(e.Attr("href"))
})

c.OnHTML("tr td:nth-of-type(1)", func(e *colly.HTMLElement) {
    fmt.Println("First column of a table row:", e.Text)
})

c.OnXML("//h1", func(e *colly.XMLElement) {
    fmt.Println(e.Text)
})

c.OnScraped(func(r *colly.Response) {
    fmt.Println("Finished", r.Request.URL)
})

Call order of callbacks

1. OnRequest

Called before a request

在请求之前调用

2. OnError

Called if error occured during the request

如果请求过程中发生错误,则调用

3. OnResponse

Called after response received

收到响应后调用

4. OnHTML

Called right after OnResponse if the received content is HTML

如果接收到的内容是HTML,则在“OnResponse”之后立即调用

5. OnXML

Called right after OnHTML if the received content is HTML or XML

如果接收到的内容是HTML或XML,则在“OnHTML”之后立即调用

6. OnScraped

Called after OnXML callbacks

OnXML回调后调用

OnHTML方法

OnHTML方法的第一个参数是选择器,goquery选择器语法类似jquery,可以认为它是jquery的go版本实现。这里简单介绍常用的选择器,具体可以参考jquery选择器使用。

  • ID选择器: #id-name 根据元素id属性进行选择
  • 类选择器:.class-name 根据class名称选择
  • 标签选择器:div 根据标签名字选择
  • 子元素选择器:parent>child 筛选parent这个父元素下,符合child这个条件的最直接的子元素,不会匹配孙子元素
  • 子孙选择器:parent son 空格隔开代表可以匹配非直接子元素也就包括子孙元素了
  • prev+next相邻选择器:选择相邻的元素

参考资料

Colly 官方文档学习从入门到入土
Go常用包(二十六):知名爬虫框架Colly
Go每日一库之170:user-agent
Go 爬虫三种框架的基本使用介绍
Python爬虫系列(一)——手把手教你写Python爬虫
https://blog.csdn/cun_king/article/details/120936013
Uber Go 语言编码规范

本文标签: 爬虫 学习笔记 入门 golang Colly