#!/usr/bin/python # Licensed under the Apache License, Version 2.0 # http://www.apache.org/licenses/LICENSE-2.0 # A script to pull all SPG Points data and output it to a CSV file """ Stuff to implement: 1) Open the pipe-delimited file and pump out summary information """ import time import datetime import re import requests import sys from bs4 import BeautifulSoup from bs4 import SoupStrainer def cleansoup(soup): #Helper function to get rid of scripts, style, lists, and the header [[tree.extract() for tree in soup(elem)] for elem in ('script','style','ul')] return soup def getpoints(user, pwd): #Authentication Station wooo wooooooo urltop = 'https://www.starwoodhotels.com/preferredguest/account/sign_in.html' path = '/account/index.html' payload = {'successPath': path, 'login': user, 'password': pwd} s = requests.session() r = s.post(urltop, data=payload) if r.status_code != 302: print "Failed! :( Check your username and password" sys.exit(0) print "Login was successful" #Initialize some fun variables urlroot = 'https://www.starwoodhotels.com/preferredguest/account/starpoints/index.html?bcount=' itemlist = [] tuplelist = [] file = open("spgpoints "+str(datetime.date.today())+".txt", mode='w+') #Iterate through each of the pages and pull the proper data for i in range(20): q = s.get(urlroot + str(16*i)) nothing = re.findall(r"Currently, your account doesn't have any activity", q.text) if nothing: tuplelist.sort(reverse=True, key=lambda q: time.strptime(q[2],"%m/%d/%Y")) print "No more data to grab. We've got", len(tuplelist), "items!" for t in tuplelist: file.write(str(t[0])+'|'+ str(t[1])+'|'+ str(t[2])+'|'+ str(t[3])+'\n') file.close() print "They should be in the spgpoints "+str(datetime.date.today())+".txt file, which is pipe-delimited." sys.exit(0) soup = cleansoup(BeautifulSoup(q.text, "html.parser", parse_only=SoupStrainer('body'))) #Finds everything with an even or odd class, but this includes the stupid inilineBookingRow class which kills the data #It works right now with the filter, but it's sloooooow even = soup.find_all('td', 'even') odd = soup.find_all('td', 'odd') crap = u'\n\n\n\n\n\n\n\nCheck in\n\n\n\nCheck out\n\n\n\n\n\n\nRooms\n\n1\n2\n3\n4\n5\n6\n7\n8\n9\n\n\n\nAdults Per Room\n\n1\n2\n3\n4\n\n\n\n\n\n\n\n\n\n\n\nClose\n\n\n\n\n\n\n' for m in even: if m.text.decode('utf-8') != crap: itemlist.append(m.text.decode('utf-8')) for n in odd: if n.text.decode('utf-8') != crap: itemlist.append(n.text.decode('utf-8')) #Now that we've got all the data, we can throw it into tuples and clean them up a bit #OH GOD IT'S SO UGLY HIDE IT FROM THE TOWNSPEOPLE while len(itemlist) > 0: tuplelist.append((str(itemlist.pop(0)), #Earn/Redeem str(itemlist.pop(0)), #Points str(itemlist.pop(0)), #Date Posted ((((str(itemlist.pop(0)).replace('\n','')) #Description, which needs cleaning .replace('Book Now','')) .replace('Add to favorites',''))) .replace(' ','|').strip())) #Print a status while this is looping so the users don't freak out print "Got page #", i+1 def main(): args = sys.argv[1:] if len(args) != 2: print "Try that again like this: spgpoints.py [username] [password]"; sys.exit(1) getpoints(args[0],args[1]) if __name__ == '__main__': main()