洛杉矶MC机房 高速低价18元起

DIYVM

Golang协程并发爬取图片源码,仅供学习

提示:如果官网是英文页面,建议使用谷歌浏览器能同步翻译页面。点击下载【谷歌浏览器最新绿色便携版】
注意:部分文章发布时间较长,可能存在未知因素,购买时建议在本站搜索商家名称,先充分了解商家动态。
交流:唯一投稿邮箱:hostvps@88.com。

网友 ***an.net 说:

package main

import (
        &*uot;fmt&*uot;
        &*uot;io/ioutil&*uot;
        &*uot;net/http&*uot;
        &*uot;os&*uot;
        &*uot;regexp&*uot;
        &*uot;strconv&*uot;
        &*uot;st**ngs&*uot;
        &*uot;sync&*uot;
        &*uot;time&*uot;
)

var (
        reImg        = `https?://[^&*uot;]+?(\.((jpg)|(png)|(jpeg)|(gif)|(bmp)))`
        taskChan     chan st**ng                                                      // 记录任务完成的通道
        imgChan      chan st**ng                                                      // 图片通道
        waitG**up    sync.WaitG**up                                                   // 协程会涉及到并发,这个的作用具体的可百度
        pageStart    int            = 1                                               // 从第几页开始
        pageSize     int            = 30                                              // 扫描页数
        DownLoadPath st**ng         = &*uot;D:/HBuilderX/p**ject/GolangP**ject/爬虫小案例/img/&*uot; // 此处是图片下载的地址,需要修改为你们自己的地址
)

func main() {
        fmt.P**ntln(&*uot;从第几页开始&*uot;)
        fmt.Scanln(&pageStart)

        fmt.P**ntln(&*uot;扫描页数&*uot;)
        fmt.Scanln(&pageSize)

        taskChan = make(chan st**ng, pageSize) // 给管道缓冲值
        imgChan = make(chan st**ng, 100000)    // 给管道缓冲值

        for i := pageStart; i < pageStart+pageSize; i++ {
                waitG**up.Add(1)
                go getWebBody(i) // 获取地址的body
        }

        waitG**up.Add(1)
        go handleImg() // 处理img

        waitG**up.Add(1)
        go checkOk()

        waitG**up.Wait()

        fmt.P**ntln(&*uot;执行完毕,回车退出&*uot;)
        var input st**ng
        fmt.Scanln(&input)
}

func getWebBody(i int) {
        **l := &*uot;https://www.bizhizu.cn/shouji/tag-%E5%8F%AF%E7%88%B1/&*uot; + strconv.Itoa(i) + &*uot;.html&*uot;
        resp, err := http.Get(**l)
        if err != nil {
                fmt.P**ntln(err)
        }
        defer resp.Body.Close() // 此处不可少,否则会造成内存泄露或者溢出问题

        body, _ := ioutil.ReadAll(resp.Body)

        re := regexp.MustCompile(reImg) // 正则匹配图片地址

        result := re.FindAllSt**ngSubmatch(st**ng(body), -1)

        p**ntln(&*uot;第&*uot; + strconv.Itoa(i) + &*uot;页找到数据&*uot; + strconv.Itoa(len(result)) + &*uot;条&*uot;)

        for _, v := range result {
                imgChan <- v[0] // 把得到的数据写到 管道 里
        }

        taskChan <- **l

        waitG**up.Done()
}

// 处理图片方法
func handleImg() {
        for **l := range imgChan {
                fileName := GetFilenameF**mUrl(**l)
                result := DownloadFile(**l, fileName)
                if result {
                        fmt.P**ntf(&*uot;已下载完毕 %v \n&*uot;, **l)
                } else {
                        fmt.P**ntf(&*uot;下载失败 %v \n&*uot;, **l)
                }
        }
        waitG**up.Done()
}

// **管道任务是否完成
func checkOk() {
        count := 0
        for {
                **l := <-taskChan
                fmt.P**ntf(&*uot;完成爬取:%v \n&*uot;, **l)
                count++
                if count == pageSize {
                        close(imgChan)
                        close(taskChan)
                        break
                }
        }

        waitG**up.Done()
}

// 截取**l名字
func GetFilenameF**mUrl(**l st**ng) (filename st**ng) {
        // 返回最后一个/的位置
        lastIndex := st**ngs.LastIndex(**l, &*uot;/&*uot;)
        // 切出来
        filename = **l[lastIndex+1:]
        // 时间*解决重名
        timePrefix := strconv.Itoa(int(time.Now().UnixNano()))
        filename = timePrefix + &*uot;_&*uot; + filename
        ret**n
}

// 下载文件方法
func DownloadFile(**l st**ng, filename st**ng) bool {
        var err er**r
        resp, err := http.Get(**l)
        if err != nil {
                fmt.P**ntln(err)
        }
        defer resp.Body.Close()
        bytes, err := ioutil.ReadAll(resp.Body)
        if err != nil {
                fmt.P**ntln(err)
        }

        if _, err := os.Stat(DownLoadPath); os.IsNotExist(err) {
                // 必须分成两步
                // 先创建文件夹
                os.Mkdir(DownLoadPath, 0777)
                // 再修改权限
                os.Chmod(DownLoadPath, 0666)
        }

        filename = DownLoadPath + filename
        err = ioutil.W**teFile(filename, bytes, 0666)
        if err != nil {
                ret**n false
        }
        ret**n true
}
网友 Twice 说:

人生苦短,我用PYTHON


网友 Mr.Bean 说:

支持看到了if err 舒服了

About 贝壳

【声明】:本博客不参与任何交易,也非中介,仅记录个人感兴趣的主机测评结果和优惠活动,内容均不作直接、间接、法定、约定的保证。访问本博客请务必遵守有关互联网的相关法律、规定与规则。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。

 收藏 (0) 打赏

您可以选择一种方式赞助本站

支付宝扫一扫赞助

微信钱包扫描赞助

本文链接:贝壳主机网 » Golang协程并发爬取图片源码,仅供学习

分享到: 生成海报
香港/美国/国内高速VPS
切换注册

登录

忘记密码 ?

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活