golang-爬虫案例实践(代码片段)

konghui konghui     2023-03-15     589

关键词:

Golang - 爬虫案例实践

1. 爬虫步骤

  1. 明确目标(确定在哪个网址搜索)
  2. 爬(爬下数据)
  3. 取(去掉没用的数据)
  4. 处理数据(按具体业务去使用数据)

2. 正则表达式

  • 文档:https://studygolang.com/pkgdoc
  • API
  • re := regexp.MustCompile(reStr):传入正则表达式,得到正则表达式对象
  • ret := re.FindAllStringSubmatch(srcStr,-1):用正则对象提取页面中内容,srcStr是页面内容,-1代表取所有
  • 爬邮箱
  • 爬超链接
  • 爬手机号
  • http://www.zhaohaowang.com/
  • 爬身份证号
  • http://henan.qq.com/a/20171107/069413.htm
  • 爬图片链接

      package main
    
      import (
         "net/http"
         "fmt"
         "io/ioutil"
         "regexp"
      )
    
      var (
         //d代表数字
         reQQEmail = `(d+)@qq.com`
         //匹配邮箱
         reEmail = `[email protected]w+.w+(.w+)?`
         //链接
         reLink = `href="(https?://[sS]+?)"`
         rePhone=`1[3456789]ds?d4s?d4`
         //410222 1987 06 13 4038
         reIdcard=`[12345678]d5((19d2)|(20[01]))((0[1-9]|[1[012]]))((0[1-9])|[12]d|[3[01]])d3[dXx]`
         reImg=`"(https?://[^"]+?(.((jpg)|(jpeg)|(png)|(gif)|(ico))))"`
      )
    
      func main2() 
         //1.爬邮箱
         //GetEmail()
         //2.抽取爬邮箱的方法
         //GetEmail2("http://tieba.baidu.com/p/2544042204")
         //3.爬超链接
         //GetLink("http://www.baidu.com/s?wd=岛国%20留下邮箱")
         //4.爬手机号
         //GetPhone("http://www.zhaohaowang.com/")
         //5.爬身份证
         //GetIdcard("http://henan.qq.com/a/20171107/069413.htm")
         //6.爬图片链接
         //GetImg("http://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E7%BE%8E%E5%A5%B3")
      
    
      //爬邮箱
      func GetEmail() 
         //1.发送http请求,获取页面内容
         resp, err := http.Get("http://tieba.baidu.com/p/2544042204")
         //处理异常
         HandleError(err, "http.Get url")
         //关闭资源
         defer resp.Body.Close()
         //接收页面
         pageBytes, err := ioutil.ReadAll(resp.Body)
         HandleError(err, "ioutil.ReadAll")
         //打印页面内容
         pageStr := string(pageBytes)
         fmt.Println(pageStr)
    
         //2.捕获邮箱,先搞定qq邮箱
         //传入正则
         re := regexp.MustCompile(reQQEmail)
         results := re.FindAllStringSubmatch(pageStr, -1)
         for _, result := range results 
            //fmt.Println(result)
            fmt.Printf("email=%s qq=%s
    ", result[0], result[1])
         
      
    
      //处理异常
      func HandleError(err error, why string) 
         if err != nil 
            fmt.Println(why, err)
         
      
    
      //抽取的爬邮箱的方法
      func GetEmail2(url string) 
         //爬页面所有数据
         pageStr := GetPageStr(url)
         re := regexp.MustCompile(reEmail)
         results := re.FindAllStringSubmatch(pageStr, -1)
         for _, result := range results 
            fmt.Println(result)
         
      
    
      //根据url获取页面内容
      func GetPageStr(url string) (pageStr string) 
         //1.发送http请求,获取页面内容
         resp, err := http.Get(url)
         //处理异常
         HandleError(err, "http.Get url")
         //关闭资源
         defer resp.Body.Close()
         //接收页面
         pageBytes, err := ioutil.ReadAll(resp.Body)
         HandleError(err, "ioutil.ReadAll")
         //打印页面内容
         pageStr = string(pageBytes)
         return pageStr
      
    
      func GetLink(url string)  
         pageStr := GetPageStr(url)
         fmt.Println(pageStr)
         re := regexp.MustCompile(reLink)
         results := re.FindAllStringSubmatch(pageStr, -1)
         fmt.Printf("找到%d条结果:
    ",len(results))
         for _, result := range results 
            //fmt.Println(result)
            fmt.Println(result[1])
         
      
    
      func GetPhone(url string)  
         pageStr := GetPageStr(url)
         fmt.Println(pageStr)
         re := regexp.MustCompile(rePhone)
         results := re.FindAllStringSubmatch(pageStr, -1)
         fmt.Printf("找到%d条结果:
    ",len(results))
         for _, result := range results 
            //fmt.Println(result)
            fmt.Println(result)
         
      
    
      func GetIdcard(url string)  
         pageStr := GetPageStr(url)
         fmt.Println(pageStr)
         re := regexp.MustCompile(reIdcard)
         results := re.FindAllStringSubmatch(pageStr, -1)
         fmt.Printf("找到%d条结果:
    ",len(results))
         for _, result := range results 
            //fmt.Println(result)
            fmt.Println(result)
         
      
    
      func GetImg(url string)  
         pageStr := GetPageStr(url)
         fmt.Println(pageStr)
         re := regexp.MustCompile(reImg)
         results := re.FindAllStringSubmatch(pageStr, -1)
         fmt.Printf("找到%d条结果:
    ",len(results))
         for _, result := range results 
            //fmt.Println(result)
            fmt.Println(result[0])
         
      

3. 并发爬取美图

  • http://www.umei.cc/bizhitupian/meinvbizhi/1.htm
  • 基本分析:
  • 先测试获取页面所有内容
  • 完成图片下载

  • 并发爬虫分析:
  • 初始化数据通道(2个)
  • 爬虫协程:65个协程向管道中添加图片链接
  • 任务统计协程:检查65个任务是否都完成,完成就关闭通道
  • 下载协程:从管道中读取链接并下载

      package main
    
      import (
         "fmt"
         "net/http"
         "io/ioutil"
         "sync"
         "strconv"
         "regexp"
         "strings"
         "time"
      )
    
      //测试是否能拿到数据
      func myTest() 
         //1.获取页面内容
         pageStr := GetPageStr("http://www.umei.cc/bizhitupian/meinvbizhi/1.htm")
         fmt.Println(pageStr)
         //2.获取图片链接
         GetImg("http://www.umei.cc/bizhitupian/meinvbizhi/1.htm")
      
    
      //图片下载
      func TestDownloadImg() 
         ok := DownloadFile("http://i1.whymtj.com/uploads/tu/201903/9999/rne35bbd2303.jpg", "1.jpg")
         if ok 
            fmt.Println("下载成功")
          else 
            fmt.Println("下载失败")
         
      
    
      //下载
      func DownloadFile(url string, filename string) (ok bool) 
         //发请求
         resp, err := http.Get(url)
         if err != nil 
            HandleError(err, "http.Get")
            return
         
         //关闭资源
         defer resp.Body.Close()
         //读取响应内容
         fBytes, e := ioutil.ReadAll(resp.Body)
         HandleError(e, "ioutil resp.Body")
         //拼接
         filename = "D:/go_work/src/goapp01/07/img/" + filename
         //写入硬盘
         err = ioutil.WriteFile(filename, fBytes, 644)
         HandleError(err, "http.GetWrite")
         if err != nil 
            return false
          else 
            return true
         
      
    
      var (
         //存图片链接的数据通道,string
         chanImageUrls chan string
         //监控通道
         chanTask  chan string
         waitGroup sync.WaitGroup
      )
    
      func main() 
         //myTest()
         //TestDownloadImg()
    
         //1.初始化数据通道
         chanImageUrls = make(chan string, 1000000)
         chanTask = make(chan string, 65)
    
         //2.爬虫协程
         for i := 1; i < 66; i++ 
            waitGroup.Add(1)
            //获取某个页面所有图片链接
            //strconv.Itoa(i):将整数转为字符串
            go getImgUrls("http://www.umei.cc/bizhitupian/weimeibizhi/" + strconv.Itoa(i) + ".htm")
         
    
         //3.任务统计协程
         waitGroup.Add(1)
         go CheckOk()
    
         //4.下载协程
         //少开几个下载协程,开5个
         for i := 0; i < 5; i++ 
            waitGroup.Add(1)
            //下载
            go DownloadImg()
         
         waitGroup.Wait()
      
    
      //爬当前页所有图片链接,并添加到管道
      func getImgUrls(url string) 
         //爬当前页所有图片链接
         urls := getImgs(url)
         //添加到管道
         for _, url := range urls 
            chanImageUrls <- url
         
         //标志当前协程任务完成
         chanTask <- url
         waitGroup.Done()
      
    
      //拿图片链接
      func getImgs(url string) (urls []string) 
         //根据url取内容
         pageStr := GetPageStr(url)
         //获取正则对象
         re := regexp.MustCompile(reImg)
         results := re.FindAllStringSubmatch(pageStr, -1)
         fmt.Printf("找到%d条结果:
    ", len(results))
         for _, result := range results 
            //fmt.Println(result)
            //fmt.Println(result)
            url := result[1]
            urls = append(urls, url)
         
         return
      
    
      //监控65个任务是否完成,完成则关闭通道
      func CheckOk() 
         //计数
         var count int
         for 
            url := <-chanTask
            fmt.Printf("%s 完成爬取任务
    ", url)
            count++
            if count == 65 
               close(chanImageUrls)
               break
            
         
         waitGroup.Done()
      
    
      //下载图片
      func DownloadImg() 
         for url := range chanImageUrls 
            //得到全路径
            filename := GetFilenameFromUrl(url, "D:/go_work/src/goapp01/07/img/")
            //保存到硬盘
            ok := DownloadFile(url, filename)
            if ok 
               fmt.Printf("%s 下载成功
    ", filename)
             else 
               fmt.Printf("%s 下载失败
    ", filename)
            
         
      
    
      //拼接文件名
      func GetFilenameFromUrl(url string, dirPath string) (filename string) 
         //strings包的方法,截取最后一个/
         lastIndex := strings.LastIndex(url, "/")
         filename = url[lastIndex+1:]
         //加一个时间戳,防止重名
         timePrefix := strconv.Itoa(int(time.Now().UnixNano()))
         filename = timePrefix + "_" + filename
         filename = dirPath + filename
         return
      

golang高效实践之deferpanicrecover实践(代码片段)

 前言我们知道Golang处理异常是用error返回的方式,然后调用方根据error的值走不同的处理逻辑。但是,如果程序触发其他的严重异常,比如说数组越界,程序就要直接崩溃。Golang有没有一种异常捕获和恢复机制呢?这个就是... 查看详情

golang模拟搜索引擎爬虫(代码片段)

最近网站需要针对百度做SEO优化,相关同学提交代码之后,我这边用Go写了个程序,模拟百度的爬虫,测试返回的内容是否正确。其实很简单,就是发送一个请求,把百度相关的信息放入请求头中即可,代码如下:packagemainimport(&... 查看详情

golang版并发爬虫(代码片段)

准备爬取内涵段子的几则笑话,先查看网址:http://www.budejie.com/text/简单分析后发现每页的url呈加1趋势第一页: http://www.budejie.com/text/1第二页:http://www.budejie.com/text/2... 每页的段子:<ahref="/detail-28278217.html">内容</a&g 查看详情

go开源宝藏golang爬虫|整点新花样(代码片段)

写在前面Python爬虫可能大家都玩腻了,那就玩一下Golang的爬虫吧!这篇文章会持续更新哒!思维导图想获取原图或是.xmind格式可在文末扫描并回复Go爬虫目录写在前面思维导图1.发送请求2.解析网页2.1CSS选择器2.2Xpath语... 查看详情

爬虫——综合案例流程版(代码片段)

爬虫综合案例开发步骤:导入类库创建爬虫通用类初始化init方法类中编写重试下载模块类中编写真正下载模块类外编写保存函数类外编写获取robots.txt函数类外编写抽取网址函数类中编写网址正常化函数创建下载限流类爬虫通用... 查看详情

window下golang使用grpc入门案例(代码片段)

一、检查golang的安装环境https://golang.org/dl/需要墙,或者在这里下载https://pan.baidu.com/s/12tTmrVIel6sfeBInpt9lQA最新版本1.10下载msi安装即可goversion验证安装 查看详情

8.爬虫训练场,第一个爬虫目标页设计,单页爬虫案例(代码片段)

单页爬虫配置案例相关文件第二个图片案例单页表格首页完善在初学爬虫采集时,很多人都是从一个单页采集需求开始的,单页案例也分为三种,分别如下:单篇新闻一些图片合集单页表格本篇博客就在爬虫训练... 查看详情

urllib爬虫(流程+案例)(代码片段)

  网络爬虫是一种按照一定规则自动抓取万维网信息的程序。在如今网络发展,信息爆炸的时代,信息的处理变得尤为重要。而这之前就需要获取到数据。有关爬虫的概念可以到网上查看详细的说明,今天在这里介绍一下使用... 查看详情

爬虫案例(代码片段)

1、爬取肯德基的所有餐厅信息  kfc.com.cn/kfccda/storelist/index.aspx  肯德基官网--餐厅查询--输入查询关键字--点击查询       发现地址栏没有发生变化,说明发送的是ajax请求2、爬取国家药品监督管... 查看详情

第⼀个爬虫案例(代码片段)

第⼀个爬虫案例前言百度开刀前言⾸先,我们还是需要回顾⼀下爬⾍的概念.爬⾍就是我们通过我们写的程序去抓取互联⽹上的数据资源.⽐如,此时我需要百度的资源.在不考虑爬⾍的情况下,我们肯定是打开浏览器,然后输⼊百度的... 查看详情

10.爬虫训练场,分页爬虫案例前端页面制作(代码片段)

...现,如果不是顺序阅读过来,可以先查看上一篇博客《9.爬虫训练场,分页爬虫案例设计Demo,打通PythonFlask和MySQL》文章目录PythonFlask分页实现PythonFlask分页控制器实现前端分页组件实现PythonFlask分页实现实现PythonFlask分页会涉及如... 查看详情

golang实践录:获取系统信息(代码片段)

...库也要往这方向考虑,比如线程库和socket库。当接触golang后,因 查看详情

python爬虫案例:下载酷某音乐文件(代码片段)

文章目录1、Python爬虫案例下载音乐1.1、前期准备1.2、分析1.2.1、第一步1.2.2、第二步1.2.3、第三步1.2.4、第四步1.3、代码实现1.4、运行结果1、Python爬虫案例下载音乐1.1、前期准备要有rquests、re、json包,如果不存在,先用pip... 查看详情

python爬虫案例:下载酷某音乐文件(代码片段)

文章目录1、Python爬虫案例下载音乐1.1、前期准备1.2、分析1.2.1、第一步1.2.2、第二步1.2.3、第三步1.2.4、第四步1.3、代码实现1.4、运行结果1、Python爬虫案例下载音乐1.1、前期准备要有rquests、re、json包,如果不存在,先用pip... 查看详情

值!一篇博客,容纳11个python爬虫案例总结,《爬虫100例》专栏第6篇复盘文章(代码片段)

...a;《海王》评论数据抓取scrapy案例34:掘金网全站用户爬虫scrapy案例35~案例40:今日复盘结论收藏时间案例29: 查看详情

值!一篇博客,容纳11个python爬虫案例总结,《爬虫100例》专栏第6篇复盘文章(代码片段)

...a;《海王》评论数据抓取scrapy案例34:掘金网全站用户爬虫scrapy案例35~案例40:今日复盘结论收藏时间案例29: 查看详情

(scrapy框架)爬虫获取百度新冠疫情数据|爬虫案例(代码片段)

目录前言环境部署插件推荐爬虫目标项目创建webdriver部署项目代码Item定义中间件定义定义爬虫pipeline输出结果文本配置文件改动验证结果总结前言闲来无聊,写了一个爬虫程序获取百度疫情数据。申明一下,研究而已。... 查看详情

python爬虫实践——爬取京东商品信息(代码片段)

1‘‘‘2爬取京东商品信息:3请求url:4https://www.jd.com/5提取商品信息:61.商品详情页72.商品名称83.商品价格94.评价人数105.商品商家11‘‘‘12fromseleniumimportwebdriver13fromselenium.webdriver.common.keysimportKeys14importtime151617defget_good(driv 查看详情