プログラミング

【golang】agoutiでスクレイピングツール作成日記vol.1

どうもダイコーです。現在プログラミングにハマっているんですが、これがなかなか難しい。駆け出し修行僧の身分なんですが、備忘録的な感じで書いていこうと思います。覚えたら書く!っていうアレですね。

というかスクレイピングツール作成とか書いてますけど、全然完成とかしてないです。ログインするとこだけしかできてません。先は長いですが頑張っていきましょう!

agoutiでのスクレイピングツール作成時に悩んだこと:ログインしたいけど…

結構時間かかりました。ログインするサイトを変えるだけで手こずるとは…情けない。でももう大丈夫なはずなのでとりあえず書きます。

参考にしたサイト
https://qiita.com/tenten0213/items/1f897ff8a64bd8b5270c

今回の全コード

login.go

package main
 import (
     "github.com/sclevine/agouti"
     "log"
 )
 func main() {
     // ブラウザはChromeを指定して起動
     driver := agouti.ChromeDriver(agouti.Browser("chrome"))
     if err := driver.Start(); err != nil {
         log.Fatalf("Failed to start driver:%v", err)
     }
     defer driver.Stop()

     page, err := driver.NewPage() 
     if err != nil {
         log.Fatalf("Failed to open page:%v", err) 
     } // ログインページに遷移
     if err := page.Navigate("指定したいURL"); err != nil {
         log.Fatalf("Failed to navigate:%v", err) 
     }
     // ID, Passの要素を取得し、値を設定
     identity := page.FindByID("user_login")//ユーザー名欄のhtmlのidの部分を入力
     password := page.FindByID("user_pass") //パスワード欄のhtmlのidの部分を入力
     identity.Fill("ログイン時のユーザー名") 
     password.Fill("ログイン時のパスワード") 
     // formをサブミット 
     if err := page.FindByClass("button-large").Submit(); err != nil { 
         log.Fatalf("Failed to login:%v", err) 
     } 
     // 処理完了後、3秒間ブラウザを表示しておく
 }

IDとPASSWORDを入力後、ログインする時

関数Findを使ったんですが、Findの部分の先に FindBy IDやFindBy Classと言うふうにどの部分を抜き出すかを選択することができます。

例えばWordPressのログインフォームのユーザー名を入力する場所のhtmlが以下のようになっているとします。(私がやったときはこれだった)

<input type="text" name="log" id="user_login" class="input" value size="20" autocapitalize="off">

この場合、

identity := page.FindByID("user_login")

とすることでhtmlの「id="user_login" 」の情報を指定していることになるみたいです。

その後ユーザー名を実際に入力してもらうために関数Fillを利用して

identity.Fill("ログイン時に入力するユーザー名")

と書けばちゃんとログインフォームにユーザー名を入力してくれます。同じ要領でパスワードもできます。

ログインボタンを押してもらいたい

上記の方法でユーザー名とパスワードを入力できました。あとはログインボタンをポチッと押してもらうだけ…だったのですが。

なかなかうまくいきません。てかいろいろ遠回りしてたみたいで、実際はめちゃくちゃ簡単でした。悔しいィ

先に答えを書いておきます。これを書けばログインボタンを押してくれました。

if err := page.FindByClass("button-large").Submit(); err != nil { 
     log.Fatalf("Failed to login:%v", err)  
}

問題はこのClassの中身の"button-large"を入力するまでに時間がかかったと言うことです。この部分を正しく書いておかないとユーザー名とパスワードを入力しただけで止まってしまいます。

んで元のコードを改造しようとしていた初めの頃は、どうして先に進んでくれないのかがわかっていませんでした。他のサイトから関数clickを使っているコードを見つけたので試したりしたんですがうまくいかない(おそらく正しく書けばclickでもうまくログインボタンを押してくれる)。

と言うのも安易な気持ちで

click := page.Find("click")
click.Click()

と言うふうに書いてみたら

パスワードを表示させるボタンをポチッとしちゃいました。「そこじゃねぇよ!!」と思いながらコードを確認し直してようやく原因がFindByClassにあると気づいたんですね。

そしてそこからがまた長かった。どこを抜き出せばいいのか分からなかったからですね。実際のhtmlのコードは

<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="ログイン">

と言うふうになっていました。じゃあ今まで通りclassの中身である"button button-primary button-large"を入れればいいと思っていたら動作せず…何がいけないんだとずっと考えてました。ちなみに参考にしたQiitaにログインするためのコードはこれです。

   if err := page.FindByClass("loginSessionsForm_submit").Submit(); err != nil {
        log.Fatalf("Failed to login:%v", err)
    }

そしてやっと気づきました。それは検証で確認しているときでした。

「…ん?もしかしてinput~の最後の.以下だけじゃないか?」

そう思い実行するとビンゴ!やっと完成しました。いやぁよかった。

本日の教訓:検証ツールと参考コードはよく見比べるべし

無事完成!

と言うことで無事ログインを自動化させることができました。この部分以外は完全に丸パクリで、自分で書けと言われれば絶対無理です。できっこない。でもこういう悩んで解決を繰り返していくことで、いつかちゃんと自分で理解しながらコードを書けるようになれると信じて勉強していこうと思います。

  • この記事を書いた人

じん

自作PC組み立ての代行をやってます。 チェンソーマンとDr.Stoneが好き。

-プログラミング