1.贴吧爬虫
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
)
func HttpGet(url string) (result string, err error) {
resp, err1 := http.Get(url)
if err1 != nil {
err = err1 // 将封装函数内部的错误,传出给调用者。
return
}
defer resp.Body.Close()
time.Sleep(time.Second)
// 循环读取 网页数据, 传出给调用者
buf := make([]byte, 4096)
for {
n, err2 := resp.Body.Read(buf)
if n == 0 {
fmt.Println("读取网页完成")
break
}
if err2 != nil && err2 != io.EOF {
err = err2
return
}
// 累加每一次循环读到的 buf 数据,存入result 一次性返回。
result += string(buf[:n])
}
return
}
// 爬取页面操作。
func working(start, end int) {
fmt.Printf("正在爬取第%d页到%d页....\n", start, end)
// 循环爬取每一页数据
for i := start; i <= end; i++ {
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)
result, err := HttpGet(url)
if err != nil {
fmt.Println("HttpGet err:", err)
continue
}
//fmt.Println("result=", result)
// 将读到的整网页数据,保存成一个文件
f, err := os.Create("第 " + strconv.Itoa(i) + " 页" + ".html")
if err != nil {
fmt.Println("Create err:", err)
continue
}
f.WriteString(result)
f.Close() // 保存好一个文件,关闭一个文件。
}
}
func main01() {
// 指定爬取起始、终止页
var start, end int
fmt.Print("请输入爬取的起始页(>=1):")
fmt.Scan(&start)
fmt.Print("请输入爬取的终止页(>=start):")
fmt.Scan(&end)
working(start, end)
}
2.贴吧并发式爬虫
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
)
func HttpGet2(url string) (result string, err error) {
resp, err1 := http.Get(url)
if err1 != nil {
err = err1 // 将封装函数内部的错误,传出给调用者。
return
}
defer resp.Body.Close()
time.Sleep(time.Second)
// 循环读取 网页数据, 传出给调用者
buf := make([]byte, 4096)
for {
n, err2 := resp.Body.Read(buf)
if n == 0 {
fmt.Println("读取网页完成")
break
}
if err2 != nil && err2 != io.EOF {
err = err2
return
}
// 累加每一次循环读到的 buf 数据,存入result 一次性返回。
result += string(buf[:n])
}
return
}
// 爬取单个页面的函数
func SpiderPage(i int, page chan int) {
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)
result, err := HttpGet2(url)
if err != nil {
fmt.Println("HttpGet err:", err)
return
}
//fmt.Println("result=", result)
// 将读到的整网页数据,保存成一个文件
f, err := os.Create("第 " + strconv.Itoa(i) + " 页" + ".html")
if err != nil {
fmt.Println("Create err:", err)
return
}
f.WriteString(result)
f.Close() // 保存好一个文件,关闭一个文件。
page <- i // 与主go程完成同步。
}
// 爬取页面操作。
func working2(start, end int) {
fmt.Printf("正在爬取第%d页到%d页....\n", start, end)
page := make(chan int)
// 循环爬取每一页数据
for i := start; i <= end; i++ {
go SpiderPage(i, page)
}
for i := start; i <= end; i++ {
fmt.Printf("第 %d 个页面爬取完成\n", <-page)
}
}
func main02() {
// 指定爬取起始、终止页
var start, end int
fmt.Print("请输入爬取的起始页(>=1):")
fmt.Scan(&start)
fmt.Print("请输入爬取的终止页(>=start):")
fmt.Scan(&end)
working2(start, end)
}
3.正则-字符
package main
import (
"fmt"
"regexp"
)
func main() {
str := "abc a7c mfc cat aMc azc cba"
// 解析、编译正则表达式
//ret := regexp.MustCompile(`a.c`) // `` : 表示使用原生字符串
ret := regexp.MustCompile(`a[^0-9a-z]c`) // `` : 表示使用原生字符串
// 提取需要信息
alls := ret.FindAllStringSubmatch(str, -1)
fmt.Println("alls:", alls)
}
4.正则-小数
package main
import (
"fmt"
"regexp"
)
func main04() {
str := "3.14 123.123 .68 haha 1.0 abc 7. ab.3 66.6 123."
// 解析、编译正则表达式
//ret := regexp.MustCompile(`[0-9]+\.[0-9]+`)
//ret := regexp.MustCompile(`\d+\.\d+`)
ret := regexp.MustCompile(`\d\.\d`)
// 提取需要的信息
alls := ret.FindAllStringSubmatch(str, -1)
fmt.Println("alls:", alls)
}
5.正则-标签
package main
import (
"fmt"
"regexp"
)
func main05() {
str := `<html lang="zh-CN">
<head>
<title>Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta charset="utf-8">
<link rel="shortcut icon" href="/static/img/go.ico">
<link rel="apple-touch-icon" type="image/png" href="/static/img/logo2.png">
<meta name="author" content="polaris <polaris@studygolang.com>">
<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 语言知识,交流使用经验">
</head>
<title></title>
<div>hello regexp</div>
<div>hello 2</div>
<div>hello 890</div>
<div>hello 664</div>
<div>
2块钱啥时候还?
过了年再说吧!
刚买了车,没钱。。。
</div>
<body>身体</body>
<frameset cols="15,85">
<frame src="/static/pkgdoc/i.html">
<frame name="main" src="/static/pkgdoc/main.html" tppabs="main.html" >
<noframes>
</noframes>
</frameset>
</html>`
// 解析、编译正则表达式
//ret := regexp.MustCompile(`<div>(.*)</div>`)
ret := regexp.MustCompile(`<div>(?s:(.*?))</div>`)
// 提取需要的信息
alls := ret.FindAllStringSubmatch(str, -1)
fmt.Println("alls:", alls)
for _, one := range alls {
fmt.Println("one[0]=", one[0])
fmt.Println("one[1]=", one[1])
}
}
6.并发提取爬虫
package main
import (
"fmt"
"io"
"net/http"
"os"
"regexp"
"strconv"
)
// 爬取指定url 的页面,返回 result
func HttpGetDB(url string) (result string, err error) {
resp, err1 := http.Get(url)
if err1 != nil {
err = err1
return
}
defer resp.Body.Close()
buf := make([]byte, 4096)
// 循环爬取整页数据
for {
n, err2 := resp.Body.Read(buf)
if n == 0 {
break
}
if err2 != nil && err2 != io.EOF {
err = err2
return
}
result += string(buf[:n])
}
return
}
func Save2file(idx int, filmName, filmScore, peopleNum [][]string) {
path := "C:/itcast/" + "第 " + strconv.Itoa(idx) + " 页.txt"
f, err := os.Create(path)
if err != nil {
fmt.Println("os.Create err:", err)
return
}
defer f.Close()
n := len(filmName) // 得到 条目数。 应该是 25
// 先打印 抬头 电影名称 评分 评分人数
f.WriteString("电影名称" + "\t\t\t" + "评分" + "\t\t" + "评分人数" + "\n")
for i := 0; i < n; i++ {
f.WriteString(filmName[i][1] + "\t\t\t" + filmScore[i][1] + "\t\t" + peopleNum[i][1] + "\n")
}
}
// 爬取一个豆瓣页面数据信息
func SpiderPageDB(idx int, page chan int) {
// 获取 url
url := "https://movie.douban.com/top250?start=" + strconv.Itoa((idx-1)*25) + "&filter="
// 封装 HttpGet2 爬取 url 对应页面
result, err := HttpGetDB(url)
if err != nil {
fmt.Println("HttpGet2 err:", err)
return
}
//fmt.Println("result=", result)
// 解析、编译正则表达式 —— 电影名称:
ret1 := regexp.MustCompile(`<img width="100" alt="(?s:(.*?))"`)
// 提取需要信息
filmName := ret1.FindAllStringSubmatch(result, -1)
// 解析、编译正则表达式 —— 分数:
pattern := `<span class="rating_num" property="v:average">(?s:(.*?))</span>`
ret2 := regexp.MustCompile(pattern)
// 提取需要信息
filmScore := ret2.FindAllStringSubmatch(result, -1)
// 解析、编译正则表达式 —— 评分人数:
ret3 := regexp.MustCompile(`<span>(?s:(\d*?))人评价</span>`)
//ret3 := regexp.MustCompile(`<span>(.*?)人评价</span>`)
// 提取需要信息
peopleNum := ret3.FindAllStringSubmatch(result, -1)
// 将提取的有用信息,封装到文件中。
Save2file(idx, filmName, filmScore, peopleNum)
// 与主go程配合 完成同步
page <- idx
}
func toWork(start, end int) {
fmt.Printf("正在爬取 %d 到 %d 页...\n", start, end)
page := make(chan int) //防止主go 程提前结束
for i := start; i <= end; i++ {
go SpiderPageDB(i, page)
}
for i := start; i <= end; i++ {
fmt.Printf("第 %d 页爬取完毕\n", <-page)
}
}
func main06() {
// 指定爬取起始、终止页
var start, end int
fmt.Print("请输入爬取的起始页(>=1):")
fmt.Scan(&start)
fmt.Print("请输入爬取的终止页(>=start):")
fmt.Scan(&end)
toWork(start, end)
}
版权声明:本文为qq_51685718原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。