go语言goquery下载图片实例「建议收藏」

crawl.gopackagemainimport(“fmt””strings””strconv””net/http””net/url””io/ioutil””os””log””runtime””flag””github.com/PuerkitoBio/goquery”)constH

大家好,又见面了,我是你们的朋友全栈君。

crawl.go

package main

import (
    "fmt"
    "strings"
    "strconv"
    "net/http"
    "net/url"
    "io/ioutil"
    "os"
    "log"
    "runtime"
    "flag"
    "github.com/PuerkitoBio/goquery"
)

const HOST     string  = "http://www.aitaotu.com"
const DOC_URL  string  = "http://www.aitaotu.com/search/%E9%BB%91%E4%B8%9D%E7%BE%8E%E8%85%BF/"

var (
    ch1 chan string
    ch2 chan string
    ch3 chan int
    img_dir string
)

//初始化变量
func init(){
    ch1 = make(chan string, 20)
    ch2 = make(chan string, 1000)
    ch3 = make(chan int, 1000)

    logfile, err := os.OpenFile("/var/log/crawl.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0777)
    if err != nil {
        os.Exit(1)
    }

    log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
    log.SetOutput(logfile)
}

func main(){
    runtime.GOMAXPROCS(runtime.NumCPU())

    img_path := flag.String("img_path", "/data/pic/", "where is image to save")
    flag.Parse()

    img_dir =  *img_path
    //检查目录是否存在
    file, err := os.Stat(img_dir)
    if err != nil || !file.IsDir() {
        dir_err := os.Mkdir(img_dir, os.ModePerm)
        if dir_err != nil {
            fmt.Println("create dir failed")
            os.Exit(1)
        }
    }

    go getListUrl()
    go parseListUrl()
    go downloadImage()

    count := 0
    for num := range ch3 {
        count = count + num
        fmt.Println("count:", count)
    }
    fmt.Println("crawl end")
}

func getListUrl(){
    doc, err := goquery.NewDocument(DOC_URL)
    if err  != nil {
        fmt.Println("err:", err)
        os.Exit(1)
    }

    doc.Find(".picbox").Each(func(i int, s *goquery.Selection){
        text, _    := s.Find("a").Attr("href")
        list_url   := HOST + text
        ch1 <- list_url
    })
}

//根据模块和总数据列出所有的图片页面
func parseListUrl(){
    suffix := ".html"
    for list_url := range ch1 {
        page_count := getPageCount(list_url)
        prefix     := strings.TrimRight(list_url, suffix)
        for i := 1; i <= page_count; i++ {
            img_list_url := prefix + "_" + strconv.Itoa(i) + suffix
            ch2 <- img_list_url
        }
    }
}

//获取总页数
func getPageCount(list_url string) (count int){
    count = 0
    doc, _ := goquery.NewDocument(list_url)
    doc.Find(".pages ul li").Each(func(i int, s *goquery.Selection){
        text := s.Find("a").Text()
        if text == "末页" {
            last_page_url, _ := s.Find("a").Attr("href")
            prefix := strings.Trim(last_page_url, ".html")
            index  := strings.Index(prefix, "_")
            last_page_num := prefix[index+1:]
            page_num, _   := strconv.Atoi(last_page_num)
            count = page_num
        }
    })
    return count
}

//解析图片url
func downloadImage(){
    for img_list_url := range ch2 {
        doc, _ := goquery.NewDocument(img_list_url)
        doc.Find("#big-pic p a").Each(func(i int, s *goquery.Selection){
            img_url, _ := s.Find("img").Attr("src")
            go func(){
                saveImages(img_url)
            }()
        })
    }
}

//下载图片
func saveImages(img_url string){
    log.Println(img_url)
    u, err := url.Parse(img_url)
    if err != nil {
        log.Println("parse url failed:", img_url, err)
        return 
    }

    //去掉最左边的'/'
    tmp := strings.TrimLeft(u.Path, "/")
    filename := img_dir + strings.ToLower(strings.Replace(tmp, "/", "-", -1))

    exists := checkExists(filename)
    if exists {
        return 
    }

    response, err := http.Get(img_url)
    if err != nil {
        log.Println("get img_url failed:", err)
        return 
    }

    defer response.Body.Close()

    data, err := ioutil.ReadAll(response.Body)
    if err != nil {
        log.Println("read data failed:", img_url, err)
        return 
    }

    image, err := os.Create(filename)
    if err != nil {
        log.Println("create file failed:", filename, err)
        return 
    }

    ch3 <- 1
    defer image.Close()
    image.Write(data)
}

func checkExists(filename string) bool {
    _, err := os.Stat(filename)
    return err == nil 
}

cd $GOPATH/bin
编译:go build crawl
运行:./crawl –img_path=/data/pic

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/127443.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 电视液晶屏好坏测试工具(分辨率4k测试工具)

    原标题:如何检测电视屏幕真伪4K、坏点漏光?两款工具一键辨别!现在的智能电视屏幕越大越薄,且许多品牌的电视都打着4K屏幕的旗号,但你真的买对电视了吗?对于大屏智能电视来说,屏幕真的很重要,在选购需要必须确定电视屏幕无坏点漏光现象,非伪4K电视屏。今天当贝市场小编分享的这两款工具,能一键辨别电视屏幕真伪4K,是否有坏点漏光等现象。1、屏幕大师屏幕大师专为智能电视及网络机顶盒设备打造,提供了包括色…

    2022年4月16日
    302
  • 安装yum(Ubuntu中的安装,带讲解,以及源的更新)

    安装yum(Ubuntu中的安装,带讲解,以及源的更新)Ubuntu 中 yum 的安装 带讲解 先放上我这只菜鸟的绝望 在网上找了好久都搞不定 那些文章都不带人思考 一路给一堆命令 然而都搞不定 白瞎了 或者说我实在太菜 冷静 calmdown 重要的一步 我们来分析一下 这边说的是在软件包里面无法定位 yum 问题是什么 怎么解决直接的问题呢 right 直接的解决方法就是去更新软件包 而那种去找各种代码来安装 yum 的 只要源一修改 什么软件没

    2025年6月23日
    3
  • unbuntu安装google浏览器和谷歌浏览器驱动

    unbuntu安装google浏览器和谷歌浏览器驱动1、安装google浏览器sudowgethttp://www.linuxidc.com/files/repo/google-chrome.list-P/etc/apt/sources.list.d/wget-q-O-https://dl.google.com/linux/linux_signing_key.pub|sudoapt-keyadd-sudoapt-…

    2022年6月11日
    32
  • Spring 4.2.2以上版本和swagger集成方案和踩过的坑

    Spring 4.2.2以上版本和swagger集成方案和踩过的坑

    2021年6月17日
    89
  • 外汇区块链内容平台_组建外汇交易工作室

    外汇区块链内容平台_组建外汇交易工作室在过去几年中,由区块链驱动的比特币对全球财务,特别是外汇行业产生了重大影响。这种创新的加密货币在全球范围内大肆挥霍,并成为头条新闻,很快就能感受到它的存在。虽然比特币很可能继续对外汇行业产生影响,但它实际上是锁定链,这种货币背后的技术,将对外汇行业产生更显着和不可逆转的影响。外汇产业的当前景观外汇市场是全球最大,最具流动性的市场。该行业每周五天,每天24小时开放,主要位于伦敦,而纽约市的每日营…

    2025年10月24日
    4
  • 单据保存后的存储过程称为_原始单据保存多少年

    单据保存后的存储过程称为_原始单据保存多少年(一)报关单证保存后的存储过程更新T_modulelist的StorageProductAfterSave值UPDATET_ModuleListSETStorageProductAfterSave=‘SaveInvoiceAfter’wheremodulename=‘报关单证’2.创建存储过程CREATEPROCSaveInvoiceAfter(@InvoiceNumvarchar(30))AsBegin…写你的逻辑,其中参数@InvoiceNum是单据号end(二)出

    2022年9月21日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号