Washington Mutual OFX Downloads Scraper
Join the DZone community and get the full member experience.
Join For FreeI put this together to automaticaally download my bank statements from WaMu, soon to be JP Morgan Chase.
class WamuRobot < OnlineAccountRobot
BASE_URL = "https://online.wamu.com/Servicing/Servicing.aspx"
def initialize(username, password, opts={})
super(opts)
agent.keep_alive = false
page = request { agent.get "https://online.wamu.com/IdentityManagement/Logon.aspx" }
form = page.form('frmLogin')
form['txtUserID'] = username
form['password'] = Encryption.decrypt(password)
form['chkRememberMe'] = 'off'
page = request { agent.submit form }
if page.uri.to_s.match("https://online.wamu.com/banking/offers")
page = request { agent.get "https://online.wamu.com/Servicing/Servicing.aspx?targetPage=AccountSummary" }
end
if page.uri.to_s == "https://online.wamu.com/Servicing/Servicing.aspx?targetPage=AccountSummary"
process_summary(page)
elsif page.body.match(/your entry is not valid/)
raise InvalidLoginError.new("Login invalid")
else
raise unknown_page(page)
end
end
def download(acct_number, from=nil, to=Date.today)
from ||= to - 30.days
index = acct_index(acct_number)
page = request { agent.get "#{BASE_URL}?targetPage=TransactionDownload&accountIndex=#{index}" }
form = page.form('__aspnetForm')
form["_ctl3:txtFromDate"] = from.strftime('%m/%d/%Y')
form["_ctl3:txtToDate"] = to.strftime('%m/%d/%Y')
form["_ctl3:softwareFormatDropDownList"] = "OFX"
page = request { form.click_button }
if page.body.match(/Verify transactions to download/)
output = request { page.form('__aspnetForm').click_button }
else
raise unknown_page(page)
end
if output.is_a?(WWW::Mechanize::File) && output.body.match(/DATA:OFXSGML/)
return output.body
else
if output.body.match(/No Transactions available/)
raise DataNotAvailableError.new("No transactions during that time period")
else
raise unknown_page(output)
end
end
end
def process_summary(doc)
table = doc.search("//table[@id='depositSummaryRptr']")
(table/"tr").search("a[href*='accountIndex']").each do |a|
link = a.attributes['href'].to_s.match(/accountIndex=(\d+)/)
text = a.parent.inner_text.strip.match(/(\d+)/)
accounts[text[1]] = link[1]
end
end
def acct_index(number)
last_four = number.to_s.match(/.*(\d{4})$/)[1]
accounts[last_four]
end
#protected
def request(time=2)
retryable(:on => StandardError, :times => 2) do
sleep time
yield
end
end
def agent
@agent ||= WWW::Mechanize.new {|a| a.log = logger }
end
# private
def accounts
@accounts ||= {}
end
end
Download
Opinions expressed by DZone contributors are their own.
Comments