前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >今日营业:go初试

今日营业:go初试

作者头像
仇诺伊
发布2020-04-24 10:22:04
2520
发布2020-04-24 10:22:04
举报
文章被收录于专栏:佳爷的后花媛

study

最近几年,golang挺热门的,使用这个技术栈的公司也不少,前段时间也一直想学习这个来着,但是一直断断续续,忘了又忘,这几天正好看到一个小例子,还挺好玩,感兴趣的可以从这里慢慢入门:

就是一个go的爬虫例子,但是在这个示例中,可以看到go里面一个很有趣的特性,相信这也是为什么很多人喜欢使用go。

首先说下什么是爬虫:

大部分应该都能理解,爬虫其实就是访问各种web服务器,然后获取其中的数据信息。

代码语言:javascript
复制
爬取的流程:
  • 首先确定要爬取的明确目标,比如网页url
  • 然后发送请求,获取应答数据包
  • 保存过滤数据,提取有用信息
  • 使用分析得到数据信息
代码语言:javascript
复制
本次示例(百度贴吧爬取实例)---常规爬取 :
1.指定用户爬取的起始页 创建working函数
2.使用start end 循环爬取每一页数据
3.获取每一页的url---下一页=前一页+50
4.封装HTTP GET函数,实现httpGet,
    目的是获取一个url数据内容,通过result返回。
5. 创建.html文件,分页保存。


使用go并发流程:

封装爬取一个网页的内容,到函数中(SpiderPage),修改相关参数
在working函数中,for循环启动go程调用,相当于爬取多少个页面,起多少个go子程
为防止主go程提前结束,引入chan,实现同步,传入进去spiderPage(chan)
在spiderPage结尾处,向channel写内容,channel<-index
在working函数中,添加新的for循环,从channel中b不断地读取各个子进程的写入的数据
代码如下所示:

package main

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

//crawl single page function 
func spiderPage(index 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((index-1)*50)
  result, err := httpGet(url)
  if err != nil {
    fmt.Println("httpGet err:", err)
    return
  }
  //fmt.Println("result=", result)
  //save read web data in file
  f, err := os.Create("第 " + strconv.Itoa(index) + "页 " + ".html")
  if err != nil {
    fmt.Println("Create err:", err)
    return
  }
  f.WriteString(result)
  f.Close() //save file and close file
  page <- index
}

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
    }
    //累加每一次循环读到的buf数据,存到result中,一次性返回
    result += string(buf[:n])
  }
  return
}

//爬取页面操作
func working(start, end int) {
  fmt.Print("正在爬取第%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.Print("爬取第%d页......\n", <-page)
  }
}

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

  working(start, end)
}

结果如下:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 佳爷的后花媛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档