zoukankan      html  css  js  c++  java
  • Go语言之进阶篇爬捧腹网

    1、爬捧腹网

    网页规律:

    https://www.pengfu.com/xiaohua_1.html   下一页 +1

    https://www.pengfu.com/xiaohua_2.html

    主页面规律:

    <h1 class="dp-b"><a href="  一个段子url连接   “ 

    段子url:

    <h1>    标题  </h1>  只取1个

    <div class="content-txt pt10"> 段子内容 <a id="prew" href=">

    2、爬捧腹网

    示例: 并发版本

    package main
    
    import (
    	"fmt"
    	"net/http"
    	"os"
    	"regexp"
    	"strconv"
    	"strings"
    )
    
    func HttpGet(url string) (result string, err error) {
    	resp, err1 := http.Get(url) //发送get请求
    	if err1 != nil {
    		err = err1
    		return
    	}
    
    	defer resp.Body.Close()
    
    	//读取网页内容
    	buf := make([]byte, 4*1024)
    	for {
    		n, _ := resp.Body.Read(buf)
    		if n == 0 {
    			break
    		}
    
    		result += string(buf[:n]) //累加读取的内容
    	}
    
    	return
    }
    
    //开始爬取每一个笑话,每一个段子 title, content, err := SpiderOneJoy(url)
    func SpiderOneJoy(url string) (title, content string, err error) {
    	//开始爬取页面内容
    	result, err1 := HttpGet(url)
    	if err1 != nil {
    		//fmt.Println("HttpGet err = ", err)
    		err = err1
    		return
    	}
    
    	//取关键信息
    	//取标题  <h1>  标题 </h1>  只取1个
    	re1 := regexp.MustCompile(`<h1>(?s:(.*?))</h1>`)
    	if re1 == nil {
    		//fmt.Println("regexp.MustCompile err")
    		err = fmt.Errorf("%s", "regexp.MustCompile err")
    		return
    	}
    	//取内容
    	tmpTitle := re1.FindAllStringSubmatch(result, 1) //最后一个参数为1,只过滤第一个
    	for _, data := range tmpTitle {
    		title = data[1]
    		//		title = strings.Replace(title, "
    ", "", -1)
    		//		title = strings.Replace(title, "
    ", "", -1)
    		//		title = strings.Replace(title, " ", "", -1)
    		title = strings.Replace(title, "	", "", -1)
    		break
    	}
    
    	//取内容 <div class="content-txt pt10"> 段子内容 <a id="prev" href="
    	re2 := regexp.MustCompile(`<div class="content-txt pt10">(?s:(.*?))<a id="prev" href="`)
    	if re2 == nil {
    		//fmt.Println("regexp.MustCompile err")
    		err = fmt.Errorf("%s", "regexp.MustCompile err2")
    		return
    	}
    
    	//取内容
    	tmpContent := re2.FindAllStringSubmatch(result, -1)
    	for _, data := range tmpContent {
    		content = data[1]
    		content = strings.Replace(content, "	", "", -1)
    		content = strings.Replace(content, "
    ", "", -1)
    		content = strings.Replace(content, "
    ", "", -1)
    		content = strings.Replace(content, "<br />", "", -1)
    		break
    	}
    
    	return
    }
    
    //把内容写入到文件
    func StoreJoyToFile(i int, fileTitle, fileContent []string) {
    	//新建文件
    	f, err := os.Create(strconv.Itoa(i) + ".txt")
    	if err != nil {
    		fmt.Println("os.Create err = ", err)
    		return
    	}
    
    	defer f.Close()
    
    	//写内容
    	n := len(fileTitle)
    	for i := 0; i < n; i++ {
    		//写标题
    		f.WriteString(fileTitle[i] + "
    ")
    		//写内容
    		f.WriteString(fileContent[i] + "
    ")
    
    		f.WriteString("
    =================================================================
    ")
    	}
    
    }
    
    func SpiderPape(i int, page chan int) {
    	//明确爬取的url
    	//https://www.pengfu.com/xiaohua_1.html
    	url := "https://www.pengfu.com/xiaohua_" + strconv.Itoa(i) + ".html"
    	fmt.Printf("正在爬取第%d个网页:%s
    ", i, url)
    
    	//开始爬取页面内容
    	result, err := HttpGet(url)
    	if err != nil {
    		fmt.Println("HttpGet err = ", err)
    		return
    	}
    
    	//fmt.Println("r = ", result)
    	//取,<h1 class="dp-b"><a href=" 一个段子url连接   "
    	//解释表达式
    	re := regexp.MustCompile(`<h1 class="dp-b"><a href="(?s:(.*?))"`)
    	if re == nil {
    		fmt.Println("regexp.MustCompile err")
    		return
    	}
    
    	//取关键信息
    	joyUrls := re.FindAllStringSubmatch(result, -1)
    	//fmt.Println("joyUrls = ", joyUrls)
    
    	fileTitle := make([]string, 0)
    	fileContent := make([]string, 0)
    
    	//取网址
    	//第一个返回下标,第二个返回内容
    	for _, data := range joyUrls {
    		//fmt.Println("url = ", data[1])
    
    		//开始爬取每一个笑话,每一个段子
    		title, content, err := SpiderOneJoy(data[1])
    		if err != nil {
    			fmt.Println("SpiderOneJoy err = ", err)
    			continue
    		}
    		//fmt.Printf("title = #%v#", title)
    		//fmt.Printf("content = #%v#", content)
    
    		fileTitle = append(fileTitle, title)       //追加内容
    		fileContent = append(fileContent, content) //追加内容
    	}
    
    	//fmt.Println("fileTitle= ", fileTitle)
    	//fmt.Println("fileContent= ", fileContent)
    
    	//把内容写入到文件
    	StoreJoyToFile(i, fileTitle, fileContent)
    
    	page <- i //写内容,写num
    
    }
    
    func DoWork(start, end int) {
    	fmt.Printf("准备爬取第%d页到%d页的网址
    ", start, end)
    
    	page := make(chan int)
    
    	for i := start; i <= end; i++ {
    		//定义一个函数,爬主页面
    		go SpiderPape(i, page)
    	}
    
    	for i := start; i <= end; i++ {
    		fmt.Printf("第%d个页面爬取完成
    ", <-page)
    	}
    
    }
    
    func main() {
    	var start, end int
    	fmt.Printf("请输入起始页( >= 1) :")
    	fmt.Scan(&start)
    	fmt.Printf("请输入终止页( >= 起始页) :")
    	fmt.Scan(&end)
    
    	DoWork(start, end) //工作函数
    }
    

    执行结果:

    D:GoFilessrchello_01>go run get_pengfu.go
    请输入起始页( >= 1) :1
    请输入终止页( >= 起始页) :5
    准备爬取第1页到5页的网址
    正在爬取第5个网页:https://www.pengfu.com/xiaohua_5.html
    正在爬取第2个网页:https://www.pengfu.com/xiaohua_2.html
    正在爬取第3个网页:https://www.pengfu.com/xiaohua_3.html
    正在爬取第4个网页:https://www.pengfu.com/xiaohua_4.html
    正在爬取第1个网页:https://www.pengfu.com/xiaohua_1.html
    第4个页面爬取完成
    第3个页面爬取完成
    第1个页面爬取完成
    第5个页面爬取完成
    第2个页面爬取完成
    

      

  • 相关阅读:
    easyui datagrid 显示 footer
    ie浏览器 vuejs axios Promise 未定义
    react引入富文本编辑器TinyMCE
    react中ant-design组件实现textarea获取光标位置并插入表情图片
    前端日志埋点优化
    iframe父子页面通讯
    HTML5中的audio在react中的使用----语音播放进度条、倍速播放、下载等
    echarts简单入门
    在textarea里实现获取光标位置和选中内容
    lodash数组发现之旅--------The second day
  • 原文地址:https://www.cnblogs.com/nulige/p/10325753.html
Copyright © 2011-2022 走看看