〇最初の目的
いくつかやってみたいことがあってWebスクレイピングをやってみることにした。
https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406
https://qiita.com/Azunyan1111/items/a1b6c58dc868814efb51
単純に今まで触っていた言語の.NETなりPythonで書けばすぐに終わる気もするが、
これぐらいだったらやったことのない言語で試してみようかと思い、Golangを使ってみることに。
〇Golangの環境構築
ということで、スクレイピングといいながらGolangの環境構築から
以下、参考サイト
http://www.softplus.jp/wiki/?Go%E8%A8%80%E8%AA%9E%28golang%29%E9%96%8B%E7%99%BA%2F%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%28Windows%29
https://qiita.com/murachi1208/items/ba44c650c13da78c60fd
https://qiita.com/kent_ocean/items/566e6a23d76ef3b4d125
https://qiita.com/spiegel-im-spiegel/items/dca0df389df1470bdbfa
〇Golangのインストール
以下からDLしてインストール
https://golang.org/dl/
※現時点だと[1.10]が最新だった。
PATHの設定
https://qiita.com/kent_ocean/items/566e6a23d76ef3b4d125
→でも最新だと設定しなくてもいけるかも。
〇Git For Windows
以下からDLしてインストール
https://gitforwindows.org/
〇エディタ
VSCodeにしてみる。
※VSでできればよかったんだけども、こっちの拡張には入ってない?
以下からDLしてインストール
https://code.visualstudio.com/download
現時点でだと[VSCode 1.20.1]
〇一回再起動
ここまでやって再起動
→Hello Worldを書いてみたらGolangの実行そのものできた
package main
import "fmt"
func main(){
fmt.Printf("Hello World!\n")
}
ただ、IDEの補完機能がちゃんと動いていない。
→もう一回再起動させてみたら、gocodeなどのInstallを要求する文言が出てきたので改めてInstall Allを実施。
これで補完機能も含めて使えるようになった。
ここまで簡単に終わったなと思ったけども、1.5Hぐらいかかってた。
〇実際にGolangでスクレイピングしてみる。
調べてみるとHTMLをパースするのにPythonのBeautifulSoupを使うと便利らしい。
早くも後悔。
とはいえ調べてみるとGolangにも似たようなモジュールはあるっぽい
上記サイトを参考に以下でモジュールをGET
go get github.com/PuerkitoBio/goquery
※パワーシェルなり、コマンドプロンプトに上記を入力でOK
あとはサイトを見ながら欲しい情報が取れそうな方法を考える。
JQueryと同じようなセレクタが使えるので、まあこの辺はJQueryのセレクタを調べたほうが豊富かも。
今回おりあえずということで毎日変更される日経平均をとってみることにした。
https://www.nikkei.com/markets/worldidx/chart/nk225/
サイトを眺めてみると
economic_value_now
というクラスが設定されているっぽいので、ダイレクトにこれを取得してしまうことに。
5日移動平均や25日移動平均あたりも一緒にとっておくと後で使えるかもしれない。
→移動平均はとりにくそうだったので止めた。どうせデータが溜まれば算出できるし。
〇CSV出力
http://tsujitaku50.hatenablog.com/entry/2017/12/31/234922
ファイルIO関連
https://hackerslog.net/post/labs/golang-io-summary/
サンプルを参考に単純に出力してみたら""が付く項目と付かない項目が混在していたのでしばし悩みましたが、
いろいろと試してみたら解決。
対象の変数にカンマが含まれていたら""が付くし、それ以外では付かないだけだった。
※勝手についたりつかなかったりするのはなんか気持ち悪い。オプションで指定できたりするのかな。
〇DateTime Now的なやつ
ファイルに出すなら、出力時間も出力したい!ということでDateTime.Now的なものも探してみた。
time.now()
簡単だった。
ただし文字列にする際のフォーマットが若干気持ち悪い。
※一応理由はあるらしい。
https://qiita.com/ruiu/items/5936b4c3bd6eb487c182
〇カンマいらない
どうせ後で引き算することになるのでカンマが入っているよりもないほうが計算しやすいと思うので
リプレイスでカンマを削っておく。
strings.Replace(str, "Replace", "rep", -1)
〇いったん出来上がり
ということで出来上がったのが以下。
初めてのGolangである。
お作法が全然わからずサンプルを見ながら書いたので、書きながらまだまだ気持ち悪い。
[:=]で定義しながら代入で[=]だけだと代入なのかね。
IDEのおかげで必要なものを勝手にImportの中に入れてくれるのは非常に便利。
package main
import (
"encoding/csv"
"fmt"
"log"
"net/url"
"os"
"strconv"
"strings"
"time"
"github.com/PuerkitoBio/goquery"
)
func main() {
_url := "https://www.nikkei.com/markets/worldidx/chart/nk225/"
doc, err := goquery.NewDocument(_url)
if err != nil {
panic(err)
}
u := url.URL{}
u.Scheme = doc.Url.Scheme
u.Host = doc.Url.Host
//economic_value_now のものが日経平均っぽい
economic_value_now := doc.Find(".economic_value_now").Text()
fmt.Println(economic_value_now)
economic_value_now = strings.Replace(economic_value_now, ",", "", -1)
fmt.Println(economic_value_now)
economic_value_time := doc.Find(".economic_value_time").Text()
fmt.Println(economic_value_time)
now := time.Now().Format("2006/01/02")
file2, err := os.OpenFile("test_o2.csv", os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatal("Error:", err)
}
defer file2.Close()
writer := csv.NewWriter(file2)
writer.UseCRLF = true //デフォルトはLFのみ
writer.Write([]string{now, economic_value_time, economic_value_now})
writer.Flush()
}
※ちなみにこのまま動かすと[test_o2.csv]というファイルを用意しておかないとエラーになります。
※出力対象ファイルがなかったら生成というオプションがあるのかないのか。
〇定期的に出力したい
あとはタスクスケジューラで定期実行させればいいと思われる。
〇サーバでの実行環境
ここまで作成してさてサーバで実行させようかなと思ったが、
実行環境はどうしたらええんやろ?
サーバ側でも同じようにインストールせにゃならんのか?
必要なモジュールもGETしないといけないのか?
なんかめんどくさくない?そんなわけないと思うのだが。
→違った。どうやらコンパイルするらしい。
https://qiita.com/spiegel-im-spiegel/items/dca0df389df1470bdbfa
正確にはBuildするとEXEが生成されるのでそれをもっていけばよかったみたい。
簡単だ。
これでEXEをタスクスケジューラから定期的に実行
日経平均の取得なのでとりあえず16時に。