読者です 読者をやめる 読者になる 読者になる

十を聞いて一を知る

要領の悪い高専生がプログラミングをします。

Mechanizeを使ってWeb予約を自動化してみる

自動化 2016年度春休み連載

こんばんは。
私は今、春休みを使って自動車学校に通っているのですが、もちろん同じ考えの人はごまんといるわけで、技能教習の予約が大変取りづらくなっています。
では、ここで質問です。

Q.以下の条件から求められる結論を答えなさい。

  1. 技能教習の予約はWeb上でできる。
  2. 私は高専生である。

A.Web予約を自動化する。

ということで、今日からのテーマは「自動車学校の技能教習の予約を自動化する」です。

今日は下準備までしようと思います。

目次

使うライブラリ

The Mechanize library is used for automating interaction with websites. Mechanize automatically stores and sends cookies, follows redirects, and can follow links and submit forms. Form fields can be populated and submitted. Mechanize also keeps track of the sites that you have visited as a history.

簡単に言うと、面倒なHTTPリクエストを簡単に送れて、しかもクッキーの管理も自動でしてくれて、フォームに値を入れることもできる優れもの。しかもnokogiriの機能も使えるすごいやつ。

今のところこれぐらいしか使ってないです。というかMechanizeが万能すぎる。

下準備

まずはMechanizeをインストール

$ gem install mechanize


こんな感じで書いていけばいいそうです。

First thing is first. Make sure that you’ve required mechanize and that you instantiate a new mechanize object:

require 'rubygems'    
require 'mechanize'

agent = Mechanize.new  

Now we’ll use the agent we’ve created to fetch a page. Let’s fetch google with our mechanize agent:

page = agent.get('http://google.com/')

(引用 Getting Started With Mechanize

そのまま書いていきます。

$ irb
>> require 'mechanize'
=> true
>> agent = Mechanize.new
=> #<Mechanize...........>
>> page = agent.get('https://google.com')
=> #<Mechanize::Page...........>

できました。


では、同じ手順で目的のサイトにアクセスします。
といきたいところですが、ログインが必要です。
まずはどういったパラメータをPOSTしているか見てみましょう。
手順は以下の通りです。

  1. ログインページにアクセスする
  2. デベロッパツールを開く(Chromeなら command+option+i )
  3. ログインする
  4. NetworkタブでHTTPステータスコードが302になっているものを探す(図1)
  5. Form Dataの欄でパラメータをみる

f:id:taira1999120:20170305021702p:plain

図1




パラメータがわかったので、先に進みます。
フォームに値を入れてPOSTする場合は

require 'mechanize'
agent = Mechanize.new
page = agent.get('http://bestgems.org/')
form = page.forms[0]    # formタグがついている一番最初の要素を取得
form.q = 'x2ch'    # qは入力項目の名前

(引用 楽々スクレイピング! Ruby Mechanizeの使い方

とするそうです。

自動車学校のログインページにはもちろんログインフォームがあったのですが、パラメータにはフォームに無いものまで含まれていました。
ですので、今回はpostメソッドを使います。

post(uri, query = {}, headers = {})
POST to the given uri with the given query. The query is specified by either a string, or a list of key-value pairs represented by a hash or an array of arrays. Examples:

agent.post 'http://example.com/', "foo" => "bar"

agent.post 'http://example.com/', [%w[foo bar]]
agent.post('http://example.com/', "<message>hello</message>",
           'Content-Type' => 'application/xml')

(引用 class Mechanize

$ irb
>> require 'mechanize'
=> true
>> agent = Mechanize.new
=> #<Mechanize...........>
>> page = agent.post('ログインページのURL', {"パラメータ1":"パラメータ1の値", "パラメータ2":"パラメータ2の値"...})
=> #<Mechanize::Page
       {url #<URI::HTTP ログインページ後のページのURI>}
     ...........>

成功したらログイン後のページのURIを持ったPageクラスがpageに代入されます。

中途半端ですが今日はここまでです。
今日はなんとなく気分良く書けた気がします。自分が本当に欲しいツールだからですかね。

それではまた明日。