Go言語で画像ダウンローダを書いてみた

先ほどのGo言語で皆大好き htpdate を書いてみたに続いて画像をダウンロードするスクリプトを書いてみました。
PerlやRuby、Pythonほどスクレイピングをするライブラリは充実していないものの”goquery”というライブラリがGo言語でソコソコ使えそうだったので使用してみました。

ライブラリ(goquery)のインストール
# go get github.com/PuerkitoBio/goquery

ソースコード(事情は下に書きますが殴り書きです)
# vi downloader.go

package main

import (
  "os"
  "fmt"
  "path"
  "net/url"
  "net/http"
  "io/ioutil"
  "github.com/PuerkitoBio/goquery"
)

func GetImgUrl(base string) []*url.URL {
  var src_url_list []*url.URL

  doc, _ := goquery.NewDocument(base)
  doc.Find("img").Each(func(_ int, s *goquery.Selection) {
    src, exists := s.Attr("src")
    if exists {
      base, _ := url.Parse(base)
      srcs, _ := url.Parse(src)
      src_url_list = append(src_url_list, base.ResolveReference(srcs))
    }
  })

  return src_url_list
}

func DownloadFiles(url_list []*url.URL) {
  for id, url := range url_list {
    raw_url := url.String()

    _, filename := path.Split(raw_url)
    filepath := path.Join("download", filename)

    response, err := http.Get(raw_url)
    body, err := ioutil.ReadAll(response.Body)

    if err != nil {
      fmt.Println(err)
    }

    file, err := os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY, 0666)

    if err != nil {
      fmt.Println(err)
    }

    file.Write(body)
    file.Close()

    fmt.Printf("[%d]%s %s\n", id, raw_url, filename)
  }
}

func main() {
  url := "http://akiba-pc.watch.impress.co.jp/"
  url_list := GetImgUrl(url)

  DownloadFiles(url_list)

}

ダウンロード先のディレクトリの作成
# mkdir download

スクリプトの実行
# go run downloader.go

[0]http://akiba-pc.watch.impress.co.jp/include/common/p01/images/logo/ah.l.png ah.l.png
[1]http://akiba-pc.watch.impress.co.jp/include/common/p01/images/global-nav/gn_headline.png gn_headline.png
[2]http://akiba-pc.watch.impress.co.jp/include/common/p01/images/global-nav/gn_clw.png gn_clw.png
[3]http://akiba-pc.watch.impress.co.jp/include/common/p01/images/global-nav/gn_pcw.png gn_pcw.png
[4]http://akiba-pc.watch.impress.co.jp/include/common/p01/images/global-nav/gn_dcw.png gn_dcw.png
[5]http://akiba-pc.watch.impress.co.jp/include/common/p01/images/global-nav/gn_ah.png gn_ah.png
~~~以下省略~~~

実は、Go言語の”channel”や”goroutine”など並列処理に関する実装方法について勉強するつもりで殴り書きしてたのですが、今日は時間がなさそうなので書いたところまでメモがてらに記事を書いていたりします(汗

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(Spamcheck Enabled)

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)