def downloadaccount(b, params): """Main function Args - b - webdriver browser params - dict of settings: name - account name username - login username password - login password, if not given, use getpass to get it. lastcheck - last seen transacation for this account, can stop checking a little after this date seenids - list of last few seen transactions, to avoid dups """ if "password" not in params: params["password"] = getpass.getpass("XXXX Password for %s: " % (params["username"])) params.setdefault("name", "XXXX") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) b.get("https://www.example.com/") """Login, get transactions, balances, images""" """Array of dicts, each with account name, subaccount name, balance, current date""" balances = [{"account": params["name"], "subaccount": account, "balance": balance, "date": datetime.date.today()}] """Array of dicts, each with id, date, account, subaccount, desc, amount id should be YYYY-MM-DD-account-subaccount-uniqueid Account unique fields should start with attr_ """ transactions = [] """dict of filenames (referenced in transactions as 'file' to base64 encoded png data""" files = {} return { "transactions": transactions, "balances": balances, "files": files }
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("Fidelity Password for %s: " % (params["username"])) params.setdefault("name", "Fidelity") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) b.get("https://www.fidelity.com/") common.loadcookies(b, params.get("cookies",[])) if b.find_elements_by_link_text("Log In"): b.find_element_by_link_text("Log In").click() elif b.find_element_by_link_text("LOG IN"): b.find_element_by_link_text("LOG IN").click() b.find_element_by_id("userId-input").send_keys(params["username"]) b.find_element_by_id("password").send_keys(params["password"] + Keys.ENTER) balances = [] for account in [x.text for x in b.find_elements_by_xpath("//table[@class='datatable-component']//tr") if '$' in x.text and "total" not in x.text.lower()]: balances.append({"account": params["name"], "subaccount": account.split("\n")[0], "balance": account.split("\n")[-1], "date": datetime.date.today()}) try: b.find_element_by_link_text("LOG OUT").click() except: pass return { "balances": balances }
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("Wells Fargo Password for %s: " % (params["username"])) params.setdefault("name", "WellsFargo") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) b.get("https://www.wellsfargo.com/") common.loadcookies(b, params.get("cookies",[])) b.find_element_by_id("userid").send_keys(params["username"]) b.find_element_by_id("password").send_keys(params["password"]) b.find_element_by_id("btnSignon").click() if b.find_elements_by_name("Decline"): b.find_element_by_name("Decline") while not b.find_elements_by_class_name("account"): time.sleep(1) transactions = [] balances = [] for i in range(len(b.find_elements_by_class_name("account"))): account = b.find_elements_by_class_name("account")[i].text b.find_elements_by_class_name("account")[i].click() if not b.find_elements_by_class_name("availableBalanceTotalAmount"): try: balance = "-" + b.find_elements_by_tag_name("table")[2].find_elements_by_tag_name("tr")[2].text.split("$")[1] balances.append({"account": params["name"], "subaccount": account, "balance": balance, "date": datetime.date.today()}) except: pass continue balance = b.find_element_by_class_name("availableBalanceTotalAmount").text balances.append({"account": params["name"], "subaccount": account, "balance": balance, "date": datetime.date.today()}) for row in b.find_elements_by_xpath("//table[@id='DDATransactionTable']/tbody/tr"): if row.text[0].isalpha(): continue trans = { "account": params["name"], "subaccount": account} trans["date"] = datetime.datetime.strptime(row.text.split()[0],"%m/%d/%y").date() trans["desc"] = row.find_element_by_class_name("text").text trans["amount"] = row.find_elements_by_class_name("amount")[0].text.strip() if not trans["amount"]: trans["amount"] = "-"+row.find_elements_by_class_name("amount")[1].text.strip() trans["id"] = "%s-%s-%s-%s" % (trans["date"], trans["account"], trans["subaccount"], hashlib.sha1(trans["desc"]).hexdigest()) if trans["date"] < params["lastcheck"]: break if trans["id"] in params["seenids"]: continue transactions.append(trans) b.find_element_by_link_text("Account Summary").click() b.find_element_by_link_text("Sign Off").click() return {"transactions": transactions, "balances": balances}
def downloadaccount(b, params): params["lastcheck"] = common.parsedate(params.get("lastcheck", "2000-01-01")) params.setdefault("seenids", []) params.setdefault("name", "Cash") if params.get("username") and not params.get("password"): params["password"] = getpass.getpass("Password for %s at %s: " % (params["username"], params["url"])) request = urllib2.Request(params["url"]) if params.get("username") and params.get("password"): request.add_header("Authorization", "Basic %s" % base64.encodestring('%s:%s' % (params["username"], params["password"])).replace('\n', '')) f = urllib2.urlopen(request) transactions = [] for entry in csv.reader(f): trans = {} for i in range(len(cols)): trans[cols[i]] = entry[i] if common.parsedate(trans["date"]) < params["lastcheck"]: continue trans["id"] = "%s-%s-%s" % (trans["date"], params["name"], hashlib.sha1(str(entry)).hexdigest()) trans["account"] = params["name"] trans["subaccount"] = "" if trans["id"] in params["seenids"]: continue transactions.append(trans) return {"transactions": transactions}
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("FECU Password for %s: " % (params["username"])) params.setdefault("name", "FECU") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) b.get("https://www.fefcu.org/cgi-bin/mcw000.cgi?MCWSTART") common.loadcookies(b, params.get("cookies",[])) b.find_element_by_name("HBUSERNAME").send_keys(params["username"]) b.find_element_by_name("MCWSUBMIT").click() b.switch_to_frame(b.find_element_by_tag_name("iframe").get_attribute("id")) b.find_element_by_name("PASSWORD").send_keys(params["password"]) b.find_element_by_tag_name("button").click() # Check for security questions... if b.find_elements_by_id("MCWSUBMIT"): b.find_element_by_id("MCWSUBMIT").click() b.find_element_by_id("MCWSUBMITCANCEL").click() b.find_element_by_link_text("here").click() # Get balances tables = ["mainShare", "mainLoan"] balances = [] while not b.find_elements_by_id(tables[0]): time.sleep(1) for tableid in tables: for row in b.find_element_by_id(tableid).find_elements_by_class_name("standardrow"): data = [x.text for x in row.find_elements_by_tag_name("td")] if len(data) < 3: continue acct = data[1].rstrip("Skip-A-Pay").strip() balance = data[-1] # Look for interest rate to determine if it's a loan. if [x for x in data if "%" in x]: balance = "-" + balance balances.append({"account": params["name"], "subaccount": acct, "balance": balance, "date": datetime.date.today()}) b.find_element_by_link_text("Exit").click() return {"balances": balances}
def downloadaccount(b, params): """Main function Args - b - webdriver browser params - dict of settings: name - account name username - login username password - login password, if not given, use getpass to get it. lastcheck - last seen transacation for this account, can stop checking a little after this date seenids - list of last few seen transactions, to avoid dups """ if "password" not in params: params["password"] = getpass.getpass("UESP Password for %s: " % (params["username"])) params.setdefault("name", "UESP") params.setdefault("seenids", []) params.setdefault("lastcheck", datetime.date(2000, 1, 1)) if type(params["lastcheck"]) in [str, unicode]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) b.get("https://login.uesp.org/") common.loadcookies(b, params.get("cookies", [])) b.find_element_by_id("ctl00_ctl00_Content_Content_userNameTextBox").send_keys(params["username"]) b.find_element_by_id("ctl00_ctl00_Content_Content_loginButton").click() b.find_element_by_id("ctl00_ctl00_Content_Content_txtPassword").send_keys(params["password"]) b.find_element_by_id("ctl00_ctl00_Content_Content_btnContinue").click() balances = [] for child in b.find_elements_by_class_name("groupOutlines"): balances.append( { "account": params["name"], "subaccount": child.text.split("\n")[0].split(":", 1)[1].strip(), "balance": child.text.split("\n")[2].split(":", 1)[1].strip(), "date": datetime.date.today(), } ) b.find_element_by_id("ctl00_ctl00_Content_btnLogout").click() return {"balances": balances}
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("Janus Password for %s: " % (params["username"])) params.setdefault("name", "Janus") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) #b.get("https://www.janus.com/") b.get("https://ww4.janus.com/Janus/Retail/AccountSummary?wt.svl=AccountBalance_nav") common.loadcookies(b, params.get("cookies",[])) if b.find_elements_by_id("selimg4"): b.find_element_by_id("selimg4").click() b.find_element_by_link_text("Log in to My Account").click() if b.find_elements_by_id("top-nav-item4"): b.find_element_by_id("top-nav-item4").click() b.find_element_by_link_text("Log in to My Account").click() b.find_element_by_id("ssn").send_keys(params["username"] + Keys.TAB + params["password"] + Keys.ENTER) balances = [] inaccounts = False name = "" for line in b.find_element_by_id("nonretirementAccountdata").text.split("\n"): if inaccounts: if not name: name = line else: balances.append({"account": params["name"], "subaccount": name, "balance": line, "date": datetime.date.today()}) name = "" if line == "Current Balance": inaccounts = True if "Total" in line: break b.find_element_by_name("logout").click() return { "balances": balances }
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("Vanguard Password for %s: " % (params["username"])) params.setdefault("name", "vanguard") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) b.get("https://personal.vanguard.com/us/home?fromPage=portal") common.loadcookies(b, params.get("cookies",[])) b.find_element_by_id("USER").send_keys(params["username"] + Keys.ENTER) while not b.find_elements_by_id("LoginForm:PASSWORD"): if b.find_elements_by_class_name("summaryTable"): question_text = b.find_element_by_class_name("summaryTable").text.lower() for question, answer in params.get("security_questions", {}).iteritems(): if question.lower() in question_text: b.find_element_by_name("ANSWER").send_keys(answer + Keys.ENTER) del params["security_questions"][question] break else: time.sleep(1) b.find_element_by_id("LoginForm:PASSWORD").send_keys(params["password"] + Keys.ENTER) balances = [] accounts = b.find_elements_by_xpath("//tbody[@id='contentForm:whatIHaveTabBox:balanceForm:dcTabletbody0']/tr") # First and last two rows are not used for acct in accounts[2:-2]: balances.append({"account": params["name"], "subaccount": " ".join(acct.text.split()[:-1]), "balance": acct.text.split()[-1], "date": datetime.date.today()}) if b.find_elements_by_link_text("LOG OFF"): b.find_element_by_link_text("LOG OFF").click() return { "balances": balances }
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("Citi Credit Cards Password for %s: " % (params["username"])) params.setdefault("name", "citicards") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) b.get("https://creditcards.citi.com/") common.loadcookies(b, params.get("cookies",[])) if b.find_elements_by_id("id"): b.find_element_by_id("id").send_keys(params["username"]) elif b.find_elements_by_id("cA-cardsUseridMasked"): b.find_element_by_id("cA-cardsUseridMasked").send_keys(params["username"]) if b.find_elements_by_id("pw"): b.find_element_by_id("pw").send_keys(params["password"]) elif b.find_elements_by_name("PASSWORD"): b.find_element_by_name("PASSWORD").send_keys(params["password"]) if b.find_elements_by_class_name("login-submit"): b.find_element_by_class_name("login-submit").click() elif b.find_element_by_class_name("cA-cardsLoginSubmit"): b.find_element_by_class_name("cA-cardsLoginSubmit").click() for loop in range(10): time.sleep(1) cards = [x.text for x in b.find_elements_by_class_name("cA-spf-cardArtHeader") if x.find_elements_by_tag_name("a")] if cards: break transactions = [] balances = [] for card in cards: for loop in range(5): if b.find_elements_by_link_text(card): break time.sleep(2) else: raise Exception("Couldn't find card %s" % (card)) while True: try: b.find_element_by_link_text(card).click() break except: b.execute_script("document.body.scrollTop=document.body.scrollTop+40;") time.sleep(4) while b.find_elements_by_id("cmlink_NoClosedAccountOverlay"): b.find_element_by_link_text("Cancel and Continue to Account Details").click() time.sleep(1) if b.find_elements_by_class_name("cT-labelItem")and "Current Balance" in b.find_elements_by_class_name("cT-labelItem")[0].text: balance = b.find_elements_by_class_name("cT-valueItem")[0].text.replace(" ","") if balance != "$0.00": balances.append({"account": params["name"], "subaccount": cardname(card), "balance": -int(balance.replace("$","").replace(".","").replace(",","")), "date": datetime.date.today()}) for page in range(6): if page: common.scrolluntilclick(b,b.find_elements_by_class_name("ui-selectmenu")[-1]) b.execute_script("document.body.scrollTop=document.body.scrollTop+40;") if not b.find_elements_by_id("filterDropDown-menu-option-%s" % (page)): break common.scrolluntilclick(b,b.find_element_by_id("filterDropDown-menu-option-%s" % (page))) time.sleep(4) skipped = 0 for entry in b.find_elements_by_class_name("purchase"): for loop in range(20): try: entry.find_element_by_class_name("cM-maximizeButton").click() break except: b.execute_script("document.body.scrollTop=document.body.scrollTop+40;") if entry.find_elements_by_class_name("cM-minimizeButton"): break else: print "ERROR" trans = {"account": params["name"], "subaccount": cardname(card)} parsetransaction(trans, entry.text.split("\n")) details = b.find_element_by_id(entry.get_attribute("id").replace("-","Ext-")) for i in range(len(details.find_elements_by_class_name("cT-labelItem"))): trans["attr_"+details.find_elements_by_class_name("cT-labelItem")[i].text] = details.find_elements_by_class_name("cT-valueItem")[i].text trans["id"] = "%s-%s-%s-%s" % (trans["date"], trans["account"], trans["subaccount"], trans.get("attr_Reference Number",hashlib.sha1(trans["desc"]).hexdigest())) if trans["date"] < params["lastcheck"]: skipped += 1 continue if trans["id"] in params["seenids"]: skipped += 1 continue if trans["id"] in [x["id"] for x in transactions]: trans["id"] += "-" + str(abs(trans["amount"])) transactions.append(trans) if len(transactions) == 5: if len([x for x in transactions if "attr_Merchant Category" in x]) == 0: print "Warning, not enough Merchant Categories found!!!" raise Exception("No merchant categories found!") if skipped > 3: break b.back() time.sleep(1) b.execute_script("document.body.scrollTop=0;") if b.find_elements_by_class_name("signOffBtn"): common.scrolluntilclick(b,b.find_element_by_class_name("signOffBtn")) elif b.find_elements_by_link_text("Sign Off"): common.scrolluntilclick(b,b.find_element_by_link_text("Sign Off")) time.sleep(2) if not transactions or not balances: print "!!! citicards - No balances or transactions found !!!" return {"transactions": transactions, "balances": balances}
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("GAP Password for %s: " % (params["username"])) params.setdefault("name", "GAP") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) subaccount = "GapCard" b.get("https://www3.onlinecreditcenter6.com/consumergen2/login.do?subActionId=1000&clientId=gap&accountType=generic") common.loadcookies(b, params.get("cookies",[])) b.find_element_by_name("userId").send_keys(params["username"]) b.find_element_by_id("btn_login").click() if b.find_elements_by_name("challengeAnswer1"): question_text = b.find_element_by_tag_name("tbody").text for question, answer in params.get("security_questions", {}).iteritems(): if question.lower() in question_text: b.find_element_by_name("challengeAnswer1").send_keys(answer) b.find_element_by_id("btn_secure_Login").click() del params["security_questions"][question] break b.find_element_by_name("password").send_keys(params["password"]) b.find_element_by_id("btn_secure_Login").click() # Get balance while not b.find_elements_by_id("currentBalance"): time.sleep(1) balance = "-" + b.find_element_by_id("currentBalance").text balances = [{"account": params["name"], "subaccount": subaccount, "balance": balance, "date": datetime.date.today()}] # Go to transaction history b.find_element_by_partial_link_text("View Prior Activity").click() time.sleep(2) transactions = [] for loop in range(2): if loop: Select(b.find_element_by_name("billingCombo")).select_by_index(loop) b.find_element_by_link_text("View").click() time.sleep(4) trans = {} if not b.find_elements_by_id("transactionDetailsTable"): continue for row in b.find_element_by_id("transactionDetailsTable").find_elements_by_tag_name("tr"): data = [x.text for x in row.find_elements_by_tag_name("td")] if not data[0]: trans["attr_Items"] = data[2] continue trans = { "account": params["name"], "subaccount": subaccount, "date": datetime.datetime.strptime(data[0], "%m/%d/%Y").date(), "desc": data[2], "amount": data[3], "category": "Shopping", "subcategory": "Clothing" } if data[4] != "CR": trans["amount"] = "-" + trans["amount"] trans["id"] = "%s-%s-%s-%s" % (trans["date"], params["name"], subaccount, hashlib.sha1(trans["desc"]).hexdigest()) if trans["id"] in params["seenids"]: continue transactions.append(trans) b.find_element_by_link_text("Logout").click() time.sleep(2) return {"transactions": transactions, "balances": balances}
def downloadaccount(b, params): # By default, we'll get all transactions since 2000! params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params.setdefault("enddate",datetime.date(2050,1,1)) params["lastcheck"] -= datetime.timedelta(days=4) params.setdefault("seenids",[]) params.setdefault("name","BofA") if not params.get("password"): params["password"] = getpass.getpass("BofA Password for %s: " % (params["username"])) b.get("https://www.bankofamerica.com/") common.loadcookies(b, params.get("cookies",[])) if b.find_elements_by_id("onlineId1"): b.find_element_by_id("onlineId1").send_keys(params["username"]) b.find_element_by_id("passcode1").send_keys(params["password"] + Keys.ENTER) else: if not b.find_elements_by_id("id"): if b.find_elements_by_name("olb-sign-in"): b.find_element_by_name("olb-sign-in").click() if b.find_elements_by_link_text("Continue to Online Banking"): b.find_element_by_link_text("Continue to Online Banking").click() b.find_element_by_id("enterID-input").send_keys(params["username"] + Keys.ENTER) else: b.find_element_by_id("id").send_keys(params["username"]) if b.find_elements_by_id("stateselect"): Select(b.find_element_by_id("stateselect")).select_by_value(params["state"]) if b.find_elements_by_link_text("Sign In"): b.find_element_by_link_text("Sign In").click() if b.find_elements_by_id("hp-sign-in-btn"): b.find_element_by_id("hp-sign-in-btn").click() if b.find_elements_by_id("top-button"): b.find_element_by_id("top-button").click() while not b.find_elements_by_id("tlpvt-passcode-input"): if b.find_elements_by_id("VerifyCompForm"): question_text = b.find_element_by_id("VerifyCompForm").text.lower() for question, answer in params.get("security_questions", {}).iteritems(): if question.lower() in question_text: b.find_element_by_id("tlpvt-challenge-answer").send_keys(answer + Keys.ENTER) del params["security_questions"][question] break time.sleep(2) b.find_element_by_id("tlpvt-passcode-input").send_keys(params["password"]) b.find_element_by_name("confirm-sitekey-submit").click() if b.find_elements_by_id("VerifyCompForm"): if b.find_elements_by_id("yes-recognize"): b.find_element_by_id("yes-recognize").click() question_text = b.find_element_by_id("VerifyCompForm").text.lower() for question, answer in params.get("security_questions", {}).iteritems(): if question.lower() in question_text: b.find_element_by_id("tlpvt-challenge-answer").send_keys(answer + Keys.ENTER) del params["security_questions"][question] break time.sleep(2) # Wait for user to continue to main screen while not b.find_elements_by_class_name("AccountName"): if b.find_elements_by_link_text("Continue to Online Banking"): b.find_element_by_link_text("Continue to Online Banking").click() time.sleep(1) if b.find_elements_by_name("no_thanks"): b.find_element_by_name("no_thanks").click() if b.find_elements_by_partial_link_text("close"): b.find_element_by_partial_link_text("close").click() accounts = [] for a in b.find_elements_by_class_name("AccountName"): if a.text not in accounts: accounts.append(a.text) newtransactions = [] balances = [] files = {} for acct in accounts: b.find_element_by_link_text(acct).click() time.sleep(2) if acct[-4:].isdigit(): acct = acct[:-7] while True: for loop in range(len(b.find_elements_by_class_name("record"))): if loop > len(b.find_elements_by_class_name("record")): continue record = b.find_elements_by_class_name("record")[loop] transaction = {"account": params["name"], "subaccount": acct} date = record.find_element_by_class_name("date-action").find_elements_by_tag_name("span")[-1].text m = datematch.match(date) if not m: continue transaction["date"] = datetime.datetime.strptime(date,"%m/%d/%Y").date() if transaction["date"] > params["enddate"]: continue if transaction["date"] < params["lastcheck"]: break transaction["desc"] = record.find_element_by_class_name("description").find_elements_by_tag_name("span")[2].text.replace("\n","") transaction["amount"] = record.find_element_by_class_name("amount").text transaction["id"] = generateid(transaction) if transaction["id"] in params["seenids"]: continue showdetail(record, b) for line in b.find_elements_by_class_name("record-detail")[-1].text.replace(":\n",": ").split("\n"): if ":" in line: transaction["attr_" + line.split(":")[0].strip()] = line.split(":")[1].strip() record_detail = b.find_elements_by_class_name("record-detail")[-1] if record_detail.find_elements_by_tag_name("img") and ("deposit slip" not in record_detail.text.lower() or transaction["desc"] == "Counter Credit"): image = record_detail.find_elements_by_tag_name("img") if image: b.get(image[0].get_attribute("src")) time.sleep(2.0) checkfn = transaction["id"] + ".png" files[checkfn] = b.get_screenshot_as_base64() b.back() time.sleep(1.0) transaction["file"] = checkfn newtransactions.append(transaction) continue newtransactions.append(transaction) if record_detail.find_elements_by_tag_name("img") and "deposit slip" in record_detail.text.lower(): for checkid in range(len(record_detail.find_elements_by_name("credit_check_thumbnail"))): subtrans = {"account": params["name"], "subaccount": acct, "parents": [transaction["id"]], "date": transaction["date"], "desc": "BofA Check Deposit", "id": "%s-%s" % (transaction["id"], checkid) } subtrans["amount"] = record_detail.find_elements_by_name("credit_check_thumbnail")[checkid].text if common.scrolluntilclick(b,record_detail.find_elements_by_name("credit_check_thumbnail")[checkid]): b.get(record_detail.find_element_by_tag_name("img").get_attribute("src")) time.sleep(1.0) checkfn = subtrans["id"] + ".png" files[checkfn] = b.get_screenshot_as_base64() b.back() time.sleep(1.0) subtrans["file"] = checkfn newtransactions.append(subtrans) transaction.setdefault("children",[]).append(subtrans["id"]) record = b.find_elements_by_class_name("record")[loop] showdetail(record, b) record_detail = b.find_elements_by_class_name("record-detail")[-1] else: break if b.find_elements_by_link_text("Previous"): b.find_element_by_link_text("Previous").click() time.sleep(2) else: break balance = b.find_element_by_class_name("TL_NPI_Amt").text balances.append({"account": params["name"], "subaccount": acct, "balance": balance, "date": datetime.date.today()}) if b.find_elements_by_link_text("Accounts Overview"): b.find_element_by_link_text("Accounts Overview").click() else: b.execute_script("fsdgoto('accountsoverview')") if b.find_elements_by_link_text("Sign Off"): b.find_element_by_link_text("Sign Off").click() time.sleep(0.5) return {"transactions": newtransactions, "balances": balances, "files": files}
balance = b.find_element_by_class_name("TL_NPI_Amt").text balances.append({"account": params["name"], "subaccount": acct, "balance": balance, "date": datetime.date.today()}) if b.find_elements_by_link_text("Accounts Overview"): b.find_element_by_link_text("Accounts Overview").click() else: b.execute_script("fsdgoto('accountsoverview')") if b.find_elements_by_link_text("Sign Off"): b.find_element_by_link_text("Sign Off").click() time.sleep(0.5) return {"transactions": newtransactions, "balances": balances, "files": files} if __name__ == "__main__": if len(sys.argv) < 2: sys.exit(1) params = { "state": "CA" } params["username"] = sys.argv[1] params["lastcheck"] = datetime.date.today()-datetime.timedelta(days=int(os.getenv("DAYSBACK") or 14)) if os.getenv("ENDDATE"): params["enddate"] = common.parsedate(os.getenv("ENDDATE")) if os.getenv("STARTDATE"): params["lastcheck"] = common.parsedate(os.getenv("STARTDATE")) params["seenids"] = [] params["cookies"] = json.load(open("cookies.json")) if os.path.exists("cookies.json") else [] b = webdriver.Chrome() data = downloadaccount(b, params) common.savecookies(b) b.quit() json.dump(data, open("bofa.json","w"), indent=2, default=str)
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("Chase Password for %s: " % (params["username"])) params.setdefault("name", "Chase") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) b.get("https://www.chase.com/") common.loadcookies(b, params.get("cookies",[])) b.find_element_by_id("usr_name_home").send_keys(params["username"]) b.find_element_by_id("usr_password_home").send_keys(params["password"]) b.find_elements_by_class_name("loginBtn")[-1].click() if b.find_elements_by_class_name("chaseui-modal"): b.find_element_by_class_name("chaseui-modal").click() if b.find_elements_by_id("show_go_to_my_accounts_img"): b.find_element_by_id("show_go_to_my_accounts_img").click() while not b.find_elements_by_partial_link_text("See activity"): time.sleep(1) common.scrolluntilclick(b, b.find_element_by_partial_link_text("See activity")) while not b.find_elements_by_class_name("first"): time.sleep(2) balance = b.find_elements_by_class_name("first")[-1].text.split()[-1] if balance.startswith("-"): balance = balance.lstrip("-") else: balance = "-" + balance # Remove this common.savecookies(b) account = "Visa" balances = [{"account": params["name"], "subaccount": account, "balance": balance, "date": datetime.date.today()}] [common.scrolluntilclick(b,x) for x in b.find_elements_by_class_name("expander") if "closed" in x.get_attribute("class")] alltext = b.find_element_by_id("Posted").text + "\n" cats = [] if b.find_elements_by_name("categoryLabel0"): for catloop in range(1000): cats.append(Select(b.find_element_by_name("categoryLabel%i" % (catloop))).value) if b.find_elements_by_class_name("chaseui-modalclose"): b.find_element_by_class_name("chaseui-modalclose").click() b.execute_script("document.body.scrollTop=document.body.scrollTop+80;") for stmt in [ "LAST_STATEMENT", "TWO_STATEMENTS_PRIOR", "THREE_STATEMENTS_PRIOR" ]: if len(Select(b.find_element_by_id("StatementPeriodQuick")).options) > 1: for loop in range(10): try: Select(b.find_element_by_id("StatementPeriodQuick")).select_by_value(stmt) break except: b.execute_script("document.body.scrollTop=document.body.scrollTop+20;") else: raise Exception("Couldn't select statememt period") time.sleep(2) [common.scrolluntilclick(b,x) for x in b.find_elements_by_class_name("expander") if "closed" in x.get_attribute("class")] alltext += b.find_element_by_id("Posted").text + "\n" common.scrolluntilclick(b,b.find_element_by_partial_link_text("Log Off")) #b.find_element_by_partial_link_text("Log Off").click() transactions = [] trans = {} for line in alltext.split("\n"): if line.strip().endswith("Print"): line = line.replace("Print","").strip() if not line: continue if line.startswith("Trans Date"): continue if "Tag purchases with Jot" in alltext: # Business accounts if re.match("\d\d/\d\d/\d\d\d\d",line.split()[0]): trans = {"account": params["name"], "subaccount": account, "amount": 0} trans["date"] = datetime.datetime.strptime(line.split()[0],"%m/%d/%Y").date() trans["desc"] = line.split(" ",3)[3] elif line == "Print" or line.startswith("Memo50") or line.startswith("MiscellaneousAuto RelatedClothingComputer"): continue elif line.lstrip().startswith("$"): trans["amount"] = "-" + line.strip() elif line.startswith("Tag purchases with"): trans["id"] = "%s-%s-%s-%s" % (trans["date"], trans["account"], trans["subaccount"], hashlib.sha1(trans["desc"]).hexdigest()) transactions.append(trans) elif "desc" in trans: trans["desc"] += " " + line continue if re.match("\d\d/\d\d/\d\d\d\d",line.split()[0]): trans = {"account": params["name"], "subaccount": account} trans["date"] = datetime.datetime.strptime(line.split()[0],"%m/%d/%Y").date() trans["attr_Post Date"] = line.split()[1] trans["attr_Type"] = line.split()[2] trans["desc"] = " ".join(line.split()[3:-1]) trans["amount"] = line.split()[-1] if trans["amount"].startswith("-"): trans["amount"] = trans["amount"].lstrip("-") else: trans["amount"] = "-" + trans["amount"] trans["attr_Details"] = "" trans["id"] = "%s-%s-%s-%s" % (trans["date"], trans["account"], trans["subaccount"], hashlib.sha1(trans["desc"]).hexdigest()) if trans["date"] < params["lastcheck"]: break if trans["id"] in params["seenids"]: trans = {} continue transactions.append(trans) elif trans: trans["attr_Details"] += " " + line.strip() return { "transactions": transactions, "balances": balances }
def downloadaccount(b, params): if "password" not in params: params["password"] = getpass.getpass("PayPal Password for %s: " % (params["username"])) params.setdefault("name", "PayPal") params.setdefault("seenids",[]) params.setdefault("lastcheck",datetime.date(2000,1,1)) if type(params["lastcheck"]) in [ str, unicode ]: params["lastcheck"] = common.parsedate(params["lastcheck"]) params["lastcheck"] -= datetime.timedelta(days=4) subaccount = "PayPal" b.get("https://www.paypal.com/us/cgi-bin/webscr?cmd=_login-submit") #These break logging in for this site #common.loadcookies(b, params.get("cookies",[])) while not b.find_elements_by_id("login_email"): time.sleep(1) if b.find_element_by_id("login_email").text != params["username"]: b.find_element_by_id("login_email").send_keys(params["username"]) b.find_element_by_id("login_password").send_keys(params["password"]) if b.find_elements_by_class_name("primary"): b.find_element_by_class_name("primary").click() if b.find_elements_by_name("submit.x"): b.find_element_by_name("submit.x").click() balance = b.find_element_by_class_name("balanceNumeral").text.replace("Available","").strip() balances = [{"account": params["name"], "subaccount": subaccount, "balance": balance, "date": datetime.date.today()}] b.find_element_by_link_text("Activity").click() # Go to transaction history transactions = [] time.sleep(2) for row in range(len(b.find_elements_by_class_name("activityRow"))): time.sleep(2) b.find_elements_by_class_name("activityRow")[row].click() if b.find_elements_by_id("transactionDetails"): data = b.find_element_by_id("transactionDetails").text elif b.find_elements_by_id("xptContentContainer"): data = b.find_element_by_id("xptContentContainer").text data = data.split("\n") for i in range(len(data)): line = data[i] try: date = datetime.datetime.strptime(" ".join(line.strip().split()[:3]), "%b %d, %Y").date() except ValueError: pass if line.strip().endswith("Name:"): desc = data[i+1].replace("(The recipient of this payment is Verified)").strip() if line.strip() == "Net amount:": amount = data[i+1].rstrip(" USD") trans = { "account": params["name"], "subaccount": subaccount, "date": date, "desc": desc, "amount": amount } trans["id"] = "%s-%s-%s-%s" % (trans["date"], params["name"], subaccount, hashlib.sha1(trans["desc"]).hexdigest()) if trans["date"] < params["lastcheck"]: break if trans["id"] in params["seenids"]: continue transactions.append(trans) b.back() time.sleep(2) if b.find_elements_by_link_text("Log Out"): b.find_element_by_link_text("Log Out").click() if b.find_elements_by_class_name("logout"): b.find_element_by_class_name("logout").click() time.sleep(2) return {"transactions": transactions, "balances": balances}