Go语言爬虫只是一种开拓思路和代码上手的练习 , 爬虫浪费了go语言的性能 , 且爬虫的效率和代码实现远没有 Python舒服 , 所以 , 学习思路 , 思路远比代码重要 ! ! !
初级 练习 -- 爬取百度贴吧
package main
import (
"fmt"
"strconv"
"net/http"
"io"
"os"
)
// 根据url获取一个网页数据
func HttpGet(url string) string {
// 定义变量,保存一个整个网页数据
var result string
// 发送请求,获取服务器回发应答包
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// 创建缓冲区,保存网页数据
buf := make([]byte,4096)
// 循环 读取数据内容
for {
n, err := resp.Body.Read(buf)
if n ==0 {
break
}
if err !=nil && err != io.EOF {
panic(err)
}
result += string(buf[:n])
}
return result
}
func Save2File(idx int, result string) {
fileName :="第" + strconv.Itoa(idx) +"页.html"
// 创建文件
f, err := os.Create(fileName)
if err != nil {
panic(err)
}
defer f.Close()
// 将一整页数据,写入到文件中。
_, err = f.WriteString(result)
if err != nil {
panic(err)
}
}
func working(start, end int) {
// 按照用户指定的起始、终止页面爬取
for i:=start; i<=end; i++ {
// 获取每一页的url
url :="https://tieba.baidu.com/f?kw=%E7%BB%9D%E5%9C%B0%E6%B1%82%E7%94%9F&ie=utf-8&pn=" + strconv.Itoa((i-1)*50)
fmt.Printf("正在爬取第%d个页面, url:%s\n", i, url)
// 封装函数,根据url获取一个网页数据
result := HttpGet(url)
// 封装函数,将读到的网页数据保存成文件
Save2File(i, result)
fmt.Printf("爬取%d个页面完毕...\n", i)
}
}
func main() {
// 提示用户指定爬取的起始、终止页面
var start, end int
fmt.Print("请输入爬取的起始页面(>=1):")
fmt.Scan(&start)
fmt.Print("请输入爬取的终止页面(>=start):")
fmt.Scan(&end)
// 找寻分页器规律,爬取内容。
working(start, end)
}
爬取百度贴吧 -- 2.0 (并发)
package main
import (
"fmt"
"strconv"
"net/http"
"io"
"os"
)
// 根据url获取一个网页数据
func HttpGet(url string) string {
// 定义变量,保存一个整个网页数据
var result string
// 发送请求,获取服务器回发应答包
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// 创建缓冲区,保存网页数据
buf := make([]byte,4096)
// 循环 读取数据内容
for {
n, err := resp.Body.Read(buf)
if n ==0 {
break
}
if err !=nil && err != io.EOF {
panic(err)
}
result += string(buf[:n])
}
return result
}
func Save2File(idx int, result string) {
fileName :="第" + strconv.Itoa(idx) +"页.html"
// 创建文件
f, err := os.Create(fileName)
if err != nil {
panic(err)
}
defer f.Close()
// 将一整页数据,写入到文件中。
_, err = f.WriteString(result)
if err != nil {
panic(err)
}
}
// 爬取一个页面,保存成一个文件。
func SpiderPage(i int, quitchan<- int) {
// 获取每一页的url
url :="https://tieba.baidu.com/f?kw=%E7%BB%9D%E5%9C%B0%E6%B1%82%E7%94%9F&ie=utf-8&pn=" + strconv.Itoa((i-1)*50)
//fmt.Printf("正在爬取第%d个页面, url:%s\n", i, url)
// 封装函数,根据url获取一个网页数据
result := HttpGet(url)
// 封装函数,将读到的网页数据保存成文件
Save2File(i, result)
quit <- i
}
func working(start, end int) {
// 创建channel ,协调各个go程退出顺序
quit := make(chan int)
// 按照用户指定的起始、终止页面爬取
for i:=start; i<=end; i++ {
go SpiderPage(i, quit)// 并发处理
}
for i:=start; i<=end; i++ {
fmt.Printf("爬取%d个页面完毕...\n", <-quit)
}
}
func main() {
// 提示用户指定爬取的起始、终止页面
var start, end int
fmt.Print("请输入爬取的起始页面(>=1):")
fmt.Scan(&start)
fmt.Print("请输入爬取的终止页面(>=start):")
fmt.Scan(&end)
// 找寻分页器规律,爬取内容。
working(start, end)
}
正则表达式 , 具体应用 --- 正则很重要,要多看哦
package main
import (
"regexp"
"fmt"
)
func main0401() {
str :="abc a7c mfc cat 8ca azc cba"
// 1. 编译正则表达式 —— 得到 go 编译器识别的 正则表达式(结构体类型)。
//ret := regexp.MustCompile(`a.c`)
//ret := regexp.MustCompile(`a[0-9]c`)
ret := regexp.MustCompile(`a\dc`)
// 2. 从原始数据中筛选有用信息
alls := ret.FindAllStringSubmatch(str, -1)
fmt.Println(alls)
}
func main0402() {
str :="3.14 123.123 .68 haha 1.0 abc 7. ab.3 66.6 123. 1.77"
// 编译正则表达式
ret := regexp.MustCompile(`\d+\.\d+`)
// 使用正则筛选数据
alls := ret.FindAllStringSubmatch(str, -1)
fmt.Println(alls)
}
func main() {
str :=`
<title>Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国
">
<meta name="keywords" content="中文, 文档, 标准库, Go语言,Golang,Go社区,Go中文社区,Golang中文社区,Go语言社区,Go语言学习,学习Go语言,Go语言学习园地,Golang 中国,Golang中国,Golang China, Go语言论坛, Go语言中文网">
<meta name="description" content="Go语言文档中文版,Go语言中文网,中国 Golang 社区,Go语言学习园地,致力于构建完善的 Golang 中文社区,Go语言爱好者的学习家园。分享 Go 语言知识,交流使用经验">
<div>2块钱啥时候还?
过了年再说吧!
刚买了车,没钱。。。
`
// 编译正则表达式
//ret := regexp.MustCompile(`
ret := regexp.MustCompile(`<div>(?s:(.*?))</div>`)
// 使用正则筛选数据
alls := ret.FindAllStringSubmatch(str, -1)
len := len(alls)
for i:=0; i
fmt.Printf("alls[%d][0]=%s\n", i, alls[i][0])
fmt.Printf("alls[%d][1]=%s\n", i, alls[i][1])
}
}
有疑问加站长微信联系(非本文作者)