• 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{resp.Body.Read(buf)/result += string(buf[:n]) return}
    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页...
    ", 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 页
    ", 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页...
    ", 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 页都页面完成...
    ", <-page)
    	}
    }
    
    func main() {
    
    	var start, end int
    	fmt.Print("请输入爬取的起始页(>=1):")
    	fmt.Scan(&start)
    	fmt.Print("请输入爬取的终止页(>=start):")
    	fmt.Scan(&end)
    
    	working(start, end)
    }
    
    
  • 相关阅读:
    JDK8 Optional类使用
    Kafka RocketMQ
    Dubbo,ElasticSearch,JVM,多线程/高并发,消息中间件 常问问题
    Redis
    java jvm 虚拟机
    25 岁做什么,可在 5 年后受益匪浅?
    设计模式
    并发与并行的理解
    多线程学习
    FireFox 如何在当前页面打开书签
  • 原文地址:https://www.cnblogs.com/haima/p/12642564.html
Copyright © 2020-2023  润新知