很多语言都可以写爬虫,包括python,java、c++、Pythhon等。而Go本身是开源的,很多大佬为Python的功能扩展写了很多成熟的工具,也就是网络上常说的xx库,我们可以利用这些工具快速实现我们的需求,比较好入门。
另外,需要强调的是,网络上并不是什么东西都可以爬,针对这个问题,我国有着一套完备的法律。爬了不该爬的内容,比如大量个人信息,那可以快速实现“从入门到入狱”。
我们仅用go标准库来试试看。
先用新建项目目录
# 创建项目目录
mkdir firstProject
# 进入目录
cd firstProject
# 初始化项目
go mod init gitcode.com/m
# 创建main文件
touch main.go
粘贴下面代码
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
resp, err := http.Get("https://www.baidu.com")
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 是 Go 实现的比较有名的一款爬虫框架,而且 Go 在高并发和分布式场景的优势也正是爬虫技术所需要的。它的主要特点是轻量、快速,设计非常优雅,并且分布式的支持也非常简单,易于扩展。
先在cmder窗口执行go get github.com/gocolly/colly
安装colly模块。安装后,go.mod多了一些依赖项模块。
package main
import (
"fmt"
"github.com/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.cn/bizhi/10231.html")
}
AllowedDomains
: 设置收集器使用的域白名单,设置后不在白名单内链接,报错:Forbidden domain
。AllowURLRevisit
: 设置收集器允许对同一 URL 进行多次下载。Async
: 设置收集器为异步请求,需很Wait()
配合使用。Debugger
: 开启Debug,开启后会打印请求日志。MaxDepth
: 设置爬取页面的深度。UserAgent
: 设置收集器使用的用户代理。MaxBodySize
: 以字节为单位设置检索到的响应正文的限制。IgnoreRobotsTxt
: 忽略目标机器中的robots.txt
声明。创建采集器
collector := colly.NewCollector(
colly.AllowedDomains("www.baidu.com",".baidu.com"),//白名单域名
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`声明
)
配置可以写在里面,也可以写在外面。
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.
您可以将不同类型的回调函数附加到“收集器”,以控制收集作业或检索信息。查看软件包文档中的相关部分。
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)
})
Called before a request
在请求之前调用
Called if error occured during the request
如果请求过程中发生错误,则调用
Called after response received
收到响应后调用
Called right after OnResponse
if the received content is HTML
如果接收到的内容是HTML,则在“OnResponse”之后立即调用
Called right after OnHTML
if the received content is HTML or XML
如果接收到的内容是HTML或XML,则在“OnHTML”之后立即调用
Called after OnXML
callbacks
在OnXML
回调后调用
OnHTML
方法的第一个参数是选择器,goquery选择器语法类似jquery,可以认为它是jquery的go版本实现。这里简单介绍常用的选择器,具体可以参考jquery选择器使用。
Colly 官方文档学习从入门到入土
Go常用包(二十六):知名爬虫框架Colly
Go每日一库之170:user-agent
Go 爬虫三种框架的基本使用介绍
Python爬虫系列(一)——手把手教你写Python爬虫
https://blog.csdn.net/cun_king/article/details/120936013
Uber Go 语言编码规范