Go
golang
初心者
ポエム
圡善旅館

GoビギナーがPDFのクローラー作った

More than 1 year has passed since last update.


はじめに

2017年4月22日〜23日,千葉県某所にてGoエンジニア合宿に参加したので,

そこで作ってみた物と,Goの感想などを記事にしようと思います.

参加したイベント詳細

Go合宿2017

a5356bf154130f483221a0d4e01fadf9.png

Gopherかわえぇ...


自分のスペック


  • Go歴(ほぼ)0日

  • A Tour of Goリタイア勢

  • 最近はSwiftでアプリ作ってる

  • サーバーサイドはほとんど触ったことない


Go&クローラーの話

おそらく一番有名なチュートリアルのA Tour of Goでフィボナッチ数列の練習問題までやったら謎の自信が出て来た()

Goの,goroutineとchannelを使って非同期でバババッと気持ちいいことしたくなったので,

クローラーを作ることに

クローラー概要・使い方

main関数内のurlにダウンロードしたいPDFがあるページのURLを入れる.

実行.

PDFがデフォのいい感じの名前になってダウンロードされる.

ディレクトリを指定してダウンロードするやり方がわからなかったので,残念なことにソースコードと同じディレクトリに保存される(本当に残念)

以下ソースコード

package main

import (
//goのスクレイピングモジュール
"github.com/PuerkitoBio/goquery"
"net/url"
"net/http"
"strings"
"io"
"os"
"sync"
"log"
)

func GetPdf_goroutine(url_string string) {
//
wait := new(sync.WaitGroup)
doc, _ := goquery.NewDocument(url_string)
doc.Find("a").Each(func(_ int, s *goquery.Selection) {
path , _ := s.Attr("href")
if (strings.Index(path, ".pdf") != -1 ) {
result, _ := url.Parse(url_string)
//この辺が冗長な気がする
i := strings.LastIndex(path, "/")
file_name := path[i+1:len(path)]
go func(path string) {
wait.Add(1)
//この辺も冗長な気がする
response, err := http.Get(result.Scheme + "://" + result.Host + path)
if err != nil {
panic(err)
}
defer response.Body.Close()
file, _ := os.Create(string(file_name))
defer file.Close()
io.Copy(file, response.Body)
wait.Done()
}(path)
wait.Wait()
}
})
}

func GetPdf(url_string string) {
doc, _ := goquery.NewDocument(url_string)
doc.Find("a").Each(func(_ int, s *goquery.Selection) {
path , _ := s.Attr("href")
if (strings.Index(path, ".pdf") != -1 ) {
result, _ := url.Parse(url_string)
//この辺も冗長な気がする
i := strings.LastIndex(path, "/")
file_name := path[i+1:len(path)]
//この辺も冗長な気がする
response, err := http.Get(result.Scheme + "://" + result.Host + path)
if err != nil {
panic(err)
}
defer response.Body.Close()
file, _ := os.Create(string(file_name))
defer file.Close()
io.Copy(file, response.Body)
}
})
}

func main() {
log.Print("Start",)
        //例として大学の入試ページの入試要項を保存する.大学のサーバーごめんなさい.
        url := "http://www.iwate-pu.ac.jp/examination/gakubu.html"
GetPdf_goroutine(url)
log.Print("Finish",)
}


goroutine有無の比較

スクリーンショット 2017-04-23 20.35.30.png

syncの使い方が怪しいのですが,これくらい差が出ました.データを引っ張って来たりする時はgoを付ける(単純)

goroutineを使うことで半分の時間,倍の速度でダウンロードできた.これすごくない?

Node.jsで作るクローラーより,ソースコードが見やすい,非同期処理がめっちゃ簡単という印象を受けた.

逆にめんどくせーなと思ったのは,未使用のパッケージをインポートしてると怒られるところ.ポチポチコメントアウトしながらコード書いてるので,いちいち指摘されるのは少々面倒


圡善旅館の話



圡善旅館

研究室の合宿はここでしよう(岩手並感)


まとめ感想

ただただ勉強しただけなのに,賞までいただけたので,本当に実りある合宿になった.

初めてGoを勉強したが,Cから入った自分にはとても既視感のある言語でとっつきやすい.

早い,単純,みんなで開発しやすそう

今後もGoでなんかやることが増えそう

みんな圡善旅館に行こう‼︎


参考にした記事