go語言實現簡單爬蟲獲取頁面圖片

DogeDogeGo發表於2022-11-14
package main

import (
    "bufio"
    "fmt"
    "github.com/antchfx/htmlquery"
    "io"
    "net/http"
    "os"
    "path"
    "strconv"
    "strings"
    "sync"
)

//重寫reader用於實現顯示下載進度
//type Reader struct {
//    io.Reader
//    //bufio.Reader
//    Total   int64
//    Current int64
//}
//
//func (r *Reader) Read(p []byte) (n int, err error) {
//    n, err = r.Reader.Read(p)
//    r.Current += int64(n)
//    fmt.Printf("\r當前進度 %.2f\n", float64((r.Current*10000)/r.Total)/100)
//    return
//}

var wg sync.WaitGroup

func main() {
    //從命令列中獲取網站
    //baseUrl := os.Args[1]

    baseUrl := "https://www.bizhi88.com/"
    dirPath := "./temp/"
    //若目標圖片沒有字尾格式  使用圖片格式png
    imgFormat := ".png"
    imgUrl, _ := getImgUrl(baseUrl)

    //imgUrl := []string{"http://img.sccnn.com/bimg/340/03821.jpg"}
    _ = createDir(dirPath)
    for index, url := range imgUrl {
        wg.Add(1)
        go downloadFile(url, dirPath, imgFormat, index)
    }
    wg.Wait()
}

//獲取圖片地址
func getImgUrl(baseUrl string) (imgUrl []string, err error) {
    doc, err := htmlquery.LoadURL(baseUrl)
    if err != nil {
        panic(err)
        return nil, err
    }

    list := htmlquery.Find(doc, "//img")

    for _, item := range list {

        //imgUrl = append(imgUrl, htmlquery.SelectAttr(item, "src"))

        //對於https://www.bizhi88.com/     圖片真是地址位於標籤data-original中
        if temp := htmlquery.SelectAttr(item, "data-original"); temp != "" {
            //避免某些圖片地址位於標籤src對於的值    取data-original則會為空值
            imgUrl = append(imgUrl, temp)
        }
    }

    return
}

func downloadFile(url string, dirPath string, imgFormat string, index int) {
    fileName := path.Base(url)
    //使用(保留)目標圖片固有格式
    if strings.Contains(fileName, ".jpg") || strings.Contains(fileName, ".png") || strings.Contains(fileName, ".jpeg") || strings.Contains(fileName, ".gif") || strings.Contains(fileName, ".bmp") {
        imgFormat = ""
    }
    res, err := http.Get(url)
    if err != nil {
        fmt.Println(url)
        fmt.Println(index)
        panic(err)
        return
    }
    defer func() {
        err := res.Body.Close()
        if err != nil {
            panic(err)
        }
    }()
    // 獲得get請求響應的reader物件
    bfReader := bufio.NewReaderSize(res.Body, 32*1024)

    //重寫reader用於實現顯示下載進度
    //reader := &Reader{
    //    Reader: bfReader,
    //    Total:  res.ContentLength,
    //}

    file, err := os.Create(dirPath + strconv.Itoa(index) + fileName + imgFormat)
    if err != nil {
        panic(err)
    }
    // 獲得檔案的writer物件
    writer := bufio.NewWriter(file)

    _, _ = io.Copy(writer, bfReader)

    //重寫reader用於實現顯示下載進度
    //_, _ = io.Copy(writer, reader)

    wg.Done()
}

//建立資料夾
func createDir(path string) (err error) {
    _, err = os.Stat(path) //   "./temp/"
    if err != nil {
        //資料夾不存在 建立資料夾
        err = os.Mkdir(path, os.ModePerm)
        if err != nil {
            panic(err)
        }
    }
    return
}

Xpath:

htmlquery:

有個網頁圖片地址並非位於img下src中

爬蟲程式需靈活定製

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章