Help us understand the problem. What is going on with this article?

So-net ゼロSIMの今の使用量を自動で取得するRuby Script

More than 3 years have passed since last update.

GCP上のRailsで定期実行させるために作ったRuby Code部分について書いてみました.
Mechanize機能の勉強も兼ねてだったので,いろいろ抜けているものもあるかも.


機能

MechanizeとXPATHを利用して,So-netのゼロSIM使用量確認ページにLoginして今の使用量を取得するRuby Script.
Cronに入れたり,Railsに組み込んだり,して使うことを想定しています.

やること

Step1 : MechanizeからLoginページ取得
Step2 : Login処理
Step3 : 『利用状況確認』ページに移動
Step4 : 『利用状況確認』ページの内容取得
Step5 : HTMLをParseして『今月のデータ使用量(速報値)』を取得

Step1 : MechanizeからLoginページ取得

script.rb
# Mechanize instance生成
agent = Mechanize.new
agent.user_agent_alias = 'Linux Mozilla'

# LoginページのHTMLをGET
login_page = agent.get('https://www.so-net.ne.jp/retail/u/')

↓ login_page.bodyで取れるHTMLにあるLogin Formはこんな感じ(作成時現在)

Login.html
<!-- 省略 -->

<form name="Login" action="/retail/u/login?realm=/retail/retail_userweb" method="post">
  <table class="inputDataElem">
    <tr>
      <th>
        <label for="simNumber">ログインID<span class="pcCR mL">(半角数字)</span></label>
      </th>
      <td>
        <input type="text" name="IDToken1" class="inputTextL hidden" id="simNumber" maxlength="11" />
        <span class="spCR mL">(例:09011112222)</span>
      </td>
    </tr>
    <tr>
      <th>
        <label for="simPassword">パスワード</label>
      </th>
      <td>
        <input type="password" name="IDToken2" class="inputTextL hidden" id="simPassword" maxlength="16" />
        <span class="spCR mL"></span>
      </td>
    </tr>
  </table>

  <div class="entryElem">
    <label for="" class="submitEntry regular disabled">
      <input type="submit" value="決定" class="inner hidden" id="simSubmit" />
    </label>
  </div>

  <input type="hidden" name="IDButton" value="login" />
  <input type="hidden" name="IDToken0" value="" />
  <input type="hidden" name="goto" value="" />
  <input type="hidden" name="encoded" value="false" />
</form>

<!-- 省略 -->

Step2でこのFormに必要な情報をMechanizeからInputしてSubmitする.

Step2 : Login処理

script.rb
# Formに情報をInput
login_form = login_page.form_with(:name => 'Login')
login_form.IDToken1 = '090xxxxyyyy'
login_form.IDToken2 = 'password'

# Login Buttonを押してFormの内容をPOST
top_page = agent.submit(login_form)

これでLogin処理が完了.Webから操作するよりも素早くLogin処理が完了しているように見える.

Step3 : 『利用状況確認』ページに移動

Login後のTop Pageの『利用状況確認』ページへのLinkまわりはこんな感じ.

Top.html
<!-- 省略 -->
<ul class="main mainMenu">
  <li class="block">
    <form name="userUsageActionForm" method="post" action="/retail/u/userUsage/">
      <div>
        <input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="8a0e887a8ffdeb7db5a69d1a4662af89">
      </div>
      <label for="menuUseCondition" class="outer">
        <input type="submit" name="index" value="ご利用状況確認" id="menuUseCondition" class="inner">
      </label>
    </form>
  </li>
</ul>
<!-- 省略 -->

『利用状況確認』のLinkボタンは内部ではFormになっていて,HiddenのParameterをPOSTしている模様.
このPOSTをMechanizeから発行することでページ移動する.

script.rb
# UsageのFormを取得してPOST
usage_form = top_page.form_with(:name => 'userUsageActionForm')
usage_page = agent.submit(usage_form)

Step4 : 『利用状況確認』ページの内容取得

↓ ページ移動後の利用状況確認ページのHTMLはこんな感じ.
(生データはなぜか<dd>の中に大量のスペースやTabが入っていたので整形しています)

Usage.html
<!-- 省略 -->
<dl class="useConditionDisplay">
  <dt>今月のデータ使用量(速報値)</dt>
  <dd>67MB</dd>
  <dt>本日のデータ使用量(速報値)</dt>
  <dd>6MB</dd>
  <dt>昨日のデータ使用量</dt>
  <dd>10MB</dd>
  <dt class="end">一昨日のデータ使用量</dt>
  <dd class="end">51MB</dd>
</dl>
<!-- 省略 -->

あとはこれをParseして"67"とかの情報を取り出してあげればOK.

Step5 : HTMLをParseして『今月のデータ使用量(速報値)』を取得

Mechanizeのsearch関数でXPATHが使えるので,これを使ってHTMLをParseする.

script.rb
usage_list = usage_page.search('//dl[@class="useConditionDisplay"]')
month_used_current_mb = usage_list.search('dd')[0].text.to_i

puts month_used_current_mb # 今月の使用量(速報値)

まとめ

  • So-netのサーバ側のErrorに対応するError Handleがない
  • Login Fail時のError Handleがない
  • So-netページのID名とかの内部仕様が変わったら破綻する

のような課題はあるものの,一応当初の目的の機能は実装できました.
GCP上のRailsに入れて,cronで定期的に情報取得→移動機に通知,という運用ができています.

///---

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away