アーカイブ
モバイルSuicaの履歴をtwitterに流したかった
xtunnelのためにスクレイピングの勉強をしていて、Mechanize+hpricotからMechanize+nokogiriの組み合わせに乗り換えようと色々と使ってみている中でできた物のひとつ。
昔しゃお先生がやっていたのを俺もやりたくて3ヶ月ぐらい前に作ったけど、mobilesuica.comのおサイフケータイ使用履歴は1日一度早朝に更新される仕様に変更されたらしくボツになった。
結局idやcssなどの手がかりが無くて手動で要素を取り出す事になり、nokogiriはHTMLタグを除去するのにしか使わなかった
MobileSuica.rb
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'rubygems'
require 'nokogiri'
require 'mechanize'
require 'kconv'
module MobileSuica
def MobileSuica.get(user,pass)
agent = WWW::Mechanize.new
agent.user_agent_alias = 'Windows IE 7'
page = agent.get('http://www.mobilesuica.com/iq/ir/SuicaDisp.aspx?returnId=SFRCMMEPC03')
login_form = page.forms_with(:name => 'form1').first
login_form.fields_with(:name => 'MailAddress').first.value = user
login_form.fields_with(:name => 'Password').first.value = pass
page = login_form.click_button
return page.body.toutf8.split(/<tr>/).delete_if{|tr|
!(tr =~ /¥/m)
}.map{|tr|
tr.gsub(/\n/,"").split(/\r/)[0..5].map{|line| # 月日,種別,利用場所,種別,利用場所,残額
Nokogiri(line).inner_text.chomp.strip.gsub(/[\t ]/,"")
}
}
end
end
mobilesuicaのユーザ名、パスワードで履歴を2次元配列として取り出せる。
require 'MobileSuica'月日、種別、利用場所、種別、利用場所、残額の順になる
MobileSuica.get("user", "pass")
01/30
入
川崎
出
横浜
5,110
01/30
入
相鉄横浜
窓出
川崎
5,320
履歴のうち最新の駅名をtwitterに投稿する。-dつけて起動するとdaemonになる
tweet-mobilesuica.rb
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'rubygems'
require 'webrick'
require 'twitter'
require 'MobileSuica'
def start(conf)
loop do
begin
first = MobileSuica.get(conf["suica_user"], conf["suica_pass"]).first
rescue
first = nil
end
if first != nil
last = first if !last
if first != last # 1回前に取得した履歴と比較
puts first
puts '-'*10
if first[1] == '入' && first[3] == '出' # 降車履歴の時
message = first[4].chomp.strip+"なう (suica)"
if !(message =~ /#{conf["ngwords"]}/)
if conf["nopost"] != true
httpAuth = Twitter::HTTPAuth.new(conf["twitter_user"], conf["twitter_pass"])
tw = Twitter::Base.new(httpAuth)
tw.update(message) # twitter post
end
puts message
end
end
last = first
end
end
sleep 60*60*1.5 # 1時間半待つ
end
end
conf = YAML::load open File.dirname(__FILE__)+'/config.yaml'
if ARGV[0] == '-d'
WEBrick::Daemon.start {
start(conf)
}
else
start(conf)
end
設定ファイル。自宅の駅名などはngwordsに入れておく
config.yaml
# config.yaml
# mobilesuica.com user/pass
suica_user : 'username@docomo.ne.jp'
suica_pass : '12345678'
# twitter user/pass
twitter_user : 'shokai'
twitter_pass : 'password'
# postしない駅名を正規表現で
ngwords : "(東京|横浜)"
# for debug
#nopost : "true"
MT3.2からWordPress2.6に移行した時の不具合をWWW::Mechanizeで修正
今年の春にSFCで動かしていたMovableType3.2が調子悪くなって、さくらに置いたWordPressに移行したわけだけど(さくらレンタルサーバ+wordpressにしてみた)
その時に過去ページのいくつかが見えなくなる不具合があった。んで今朝からそれを解消するスクリプトを動かしている。今1000件目あたり。昼過ぎには完了するはず。
どういう不具合かというと、wordpressにログインしていない人がアクセスしたページは404ステータスになる。apacheが吐く404ではなくwordpressが吐く404で、「エラー 404 – 見つかりませんでした」と出る。ログインしていると普通に記事を見る事が出来る。
このせいで、俺は見れているのにURLを送ると「記事がないですよ」とみんなに言われて、原因を特定するのに時間がかかった。
そしてその修正方法だが、単に個別記事編集画面で「保存」を押すだけでその記事は復活した。なぜだかわからない。
さくらのコントロールパネルからMySQLのテーブルを見ても、どのテーブルが悪さしているのかよく分からなかったのでRubyのWWW::Mechanizeを使って全ページ「保存」ボタンを押しなおす事にした。
WWW::Mechanizeはログインフォームにパスワードを入れたり、UserAgentを偽装してwebページにアクセスしたりできる非常に有用なモジュール。Perlでは使った事あったけどRubyでは今回が初。
参考
- Ruby Scraping – Mechanize
- Greenbear Diary – RubyでHTMLとWebを操作するためのライブラリ、HpricotとWWW::Mechanize , HikiReload
- RubyのMechanizeのよくある質問 – きたももんががきたん。
必要なものをインストール
sudo gem install mechanize hpricot
普通にwp-login.phpからログインしてdashboardへ行き、cookieを持った状態で各記事個別ページへ移動して保存ボタンを押していく。記事個別ページが連番で助かった。あと自分のサーバをいじめたくないのでsleepは長めにしてある
shokai-blogfix.rb として保存
#!/usr/bin/env ruby
require ’rubygems’
require ’kconv’
require ’mechanize’
require ’pp’
user = ”username”
pass = ”password”
puts ’start’
agent = WWW::Mechanize.new
page = agent.get(“http://shokai.org/blog/wp-login.php”)
login_form = page.forms_with(“loginform”).first
login_form.log = user
login_form.pwd = pass
dashboard = agent.submit(login_form)
puts ”login: ” + dashboard.title
# 各ページ処理
for i in 1..1558
sleep 10
begin
page = agent.get(“http://shokai.org/blog/wp-admin/post.php?action=edit&post=#{i}”)
post_form = page.forms_with(“post”).first
page = agent.submit(post_form)
puts i.to_s+”success!” if page.body =~ /投稿が更新されました/
rescue
puts i.to_s+”error”
end
end
puts ’–finished–’
パスワードなどは適宜変更。
URLもハードコーディングしている。1回しか使わないスクリプトだし

最近のコメント