Golang 爬虫01

学习地址:

https://www.bilibili.com/video/BV1Nt411H7sP?p=4

目录站:

https://tieba.baidu.com/f?kw=绝地求生&ie=utf-8&pn=0
https://tieba.baidu.com/f?kw=绝地求生&ie=utf-8&pn=50
https://tieba.baidu.com/f?kw=绝地求生&ie=utf-8&pn=100

爬虫概念:

访问web服务器,获取指定数据信息的一段程序.

工作流程:

  1. 明确目标Url.
  2. 发送请求,获取应答数据包.
  3. 保存,过滤数据.提取有用信息.
  4. 使用,分析得到数据信息.

百度贴吧爬虫实现:

go实战代码

单进程

实现过程:

  1. 提示用户指定起始,终止页.创建working函数.
  2. 使用start,end循环爬取每一页数据.
  3. 获取第一页的url--下一页=前一页+50.
  4. 封闭实现HttpGet()函数,爬取一个网页的数据内容,通过result返回.
    httpGet/resp.Body.Close/buf:=make(4096)/for
  5. 创建.html文件.使用循环因子i命名.
  6. 将result写入文件WriteString(result).f.close() 不推荐使用defer.
package main

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

// HttpGet ...
func HttpGet(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 {
			fmt.Println("读取网页完成")
			break
		}
		if err2 != nil && err2 != io.EOF {
			err = err2
			return
		}
		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 main() {

	var start, end int
	fmt.Print("请输入爬取的起始页(>=1):")
	fmt.Scan(&start)
	fmt.Print("请输入爬取的终止页(>=start):")
	fmt.Scan(&end)

	working(start, end)
}


并发爬取

实现过程:

package main

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

// HttpGet ...
func HttpGet(url string, i int) (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 {
			fmt.Printf("正在读取第 %d 页\n", i)
			break
		}
		if err2 != nil && err2 != io.EOF {
			err = err2
			return
		}
		result += string(buf[:n])
	}

	return
}

//SpiderPage ...
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(url, i)
	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
}
func working(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 main() {

	var start, end int
	fmt.Print("请输入爬取的起始页(>=1):")
	fmt.Scan(&start)
	fmt.Print("请输入爬取的终止页(>=start):")
	fmt.Scan(&end)

	working(start, end)
}

posted @ 2020-04-06 16:10  HaimaBlog  阅读(257)  评论(0编辑  收藏  举报