十四、爬虫

1.爬取百度贴吧

//HTTP网页请求
func HttpGet(i int, url string) (result string, err error) {
	resp, err1 := http.Get(url)
	if err1 != nil {
		err = err1 //将封装函数内部的错误,传出给调用者。
		fmt.Println("http.Get err:", err)
		return
	}
	defer resp.Body.Close()
	time.Sleep(time.Second)

	//循环读取网页数据,传出给调用者
	buf := make([]byte, 4096)
	for {
		n, err2 := resp.Body.Read(buf)
		if n == 0 {
			fmt.Printf("第%d页读取完毕。\n", i)
			break
		}
		if err2 != nil && err2 != io.EOF {
			err = err2
			fmt.Println("resp.Body.Read err:", err)
			return
		}
		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 := HttpGet(i, url)
	if err != nil {
		fmt.Println("HttpGet err:", err)
		return
	}

	// 将读到的整网页数据,保存成一个文件
	f, err := os.Create("第 " + strconv.Itoa(i) + " 页" + ".html")
	if err != nil {
		fmt.Println("os.Create err:", err)
		return
	}
	f.WriteString(result)
	f.Close() // 保存好一个文件,关闭一个文件。
	page <- i //与主go程完成同步
}

//爬取页面操作
func working(start int, 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 main() {
	//指定爬取起始、终止页
	start := 1
	end := 10
	//爬取页面操作
	working(start, end)
}

2.正则表达式

func main() {
	str := "abc a7c mfc cat 8ca azc cba"
	// 1. 解析、编译正则表达式
	ret := regexp.MustCompile("a.c")
	// 2. 提取需要信息,这里查找到3个匹配,-1表示全部提取。
	result := ret.FindAllStringSubmatch(str, -1)
	fmt.Println(result) //[[abc] [a7c] [azc]]
	fmt.Printf("------------------------------------\n")

	str = `<!DOCTYPE html>
			<html lang="zh-CN">
				<title>标题</title>
				<div>过年来吃鸡啊</div>
				<div>hello regexp</div>
				<div>你在吗?</div>
				<body>呵呵</body>
				<div>
					2块钱啥时候还?
					过了年再说吧!
					刚买了车,没钱。。。
				</div>
			</html>`
	ret = regexp.MustCompile(`<div>(?s:(.*?))</div>`)
	result = ret.FindAllStringSubmatch(str, -1)
	fmt.Println(result) //[[<div>过年来吃鸡啊</div> 过年来吃鸡啊] [<div>hello regexp</div> hello regexp] ...]
	//这里再解释下 FindAllStringSubmatch()函数的返回值[ ][ ]string:[[string1 string2]...]
	//其中:string1: 表示带有匹配参考项的全部字串。string2: 表示去除匹配参考项后的字串。
	//因此,如果我们想得到不包含<div></div>标签的数据内容,可以使用下标[1]来直接获取。
	for _, data := range result {
		fmt.Println(data[0], "  ", data[1]) //<div>过年来吃鸡啊</div>    过年来吃鸡啊
	}
}

3.爬取豆瓣电影

package main

import (
	"net/http"
	"fmt"
	"time"
	"io"
	"strconv"
	"regexp"
)

//HTTP网页请求
func HttpGet(i int, url string) (result string, err error) {
	resp, err1 := http.Get(url)
	if err1 != nil {
		err = err1 //将封装函数内部的错误,传出给调用者。
		fmt.Println("http.Get err:", err)
		return
	}
	defer resp.Body.Close()
	time.Sleep(time.Second)

	//循环读取网页数据,传出给调用者
	buf := make([]byte, 4096)
	for {
		n, err2 := resp.Body.Read(buf)
		if n == 0 {
			fmt.Printf("------>第%d页读取完毕。\n", i)
			break
		}
		if err2 != nil && err2 != io.EOF {
			err = err2
			fmt.Println("resp.Body.Read err:", err)
			return
		}
		result += string(buf[:n]) // 累加读到的数据内容
	}
	return
}

//爬取单个页面的函数
func SpiderPage(i int, page chan int) {
	url := "https://movie.douban.com/top250?start=" + strconv.Itoa((i-1)*25) + "&filter="
	result, err := HttpGet(i, url)
	if err != nil {
		fmt.Println("HttpGet err:", err)
		return
	}

	// 从读到的整网页数据,提取想要的数据
	ret1 := regexp.MustCompile(`<img width="100" alt="(.*?)"`)
	ret2 := regexp.MustCompile(`<span class="rating_num" property="v:average">(.*?)</span>`)
	ret3 := regexp.MustCompile(`<span>(.*?)人评价</span>`)
	name := ret1.FindAllStringSubmatch(result, -1)  //电影名称
	score := ret2.FindAllStringSubmatch(result, -1) //分数
	pers := ret3.FindAllStringSubmatch(result, -1)  //评分人数
	for i := 0; i < len(name); i++ {
		//霸王别姬 	 9.6 分	 977848 人
		fmt.Println(name[i][1], "\t", score[i][1], "分\t", pers[i][1], "人")
	}

	page <- i //与主go程完成同步
}

func main() {
	//指定爬取起始、终止页
	start, end := 1, 10

	//爬取页面操作
	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)
	}
}

4.爬虫框架

4.1 go爬虫框架:
  • gocolly
  • gocolly是用go实现的网络爬虫框架gocolly快速优雅,在单核上每秒可以发起1K以上请求;以回调函数的形式提供了一组接口,可以实现任意类型的爬虫;依赖goquery库可以像jquery一样选择web元素。
  • gocolly的官方网站是http://go-colly.org/,提供了详细的文档和示例代码。
4.2 go开源爬虫项目:
  • Pholcus
  • Pholcus(幽灵蛛)是一款纯Go语言编写的支持分布式的高并发、重量级爬虫软件,定位于互联网数据采集,为具备一定Go或JS编程基础的人提供一个只需关注规则定制的功能强大的爬虫工具。
  • 它支持单机、服务端、客户端三种运行模式,拥有Web、GUI、命令行三种操作界面;规则简单灵活、批量任务并发、输出方式丰富(mysql/mongodb/csv/excel等)、有大量Demo共享;另外它还支持横纵向两种抓取模式,支持模拟登录和任务暂停、取消等一系列高级功能。
  • Pholcus 官方网站是https://www.oschina.net/p/pholcus
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值