from splinter import Browser from collections import OrderedDict import sys import time import os.path #------------------------------------- #-----Start of function _printnow----- #------------------------------------- def _printnow(printinput): print printinput sys.stdout.flush() #----------------------------------- #-----End of function _printnow----- #----------------------------------- #------------------------------------------ #-----Start of function _searchexpedia----- #------------------------------------------ #Function to search expedia; Returns the price of the flight def _searchexpedia( browser, origin, destination, xorigin, xdestination, departuredate, returndate, xdate ): #Make dates ready for expedia exp_departuredate = departuredate.replace('-','.') exp_returndate = returndate.replace('-','.') exp_xdate = xdate.replace('-','.') #Check if price container exists (a succesful search has already taken place). If not: go to the right URL to search Expedia if not browser.is_element_not_present_by_id('type3TotalPrice0'): #Enter information for return flight in search screen (No need to change date) browser.find_by_id('inpDepartureLocations2')[0].fill(xorigin) browser.find_by_id('inpArrivalLocations2')[0].fill(xdestination) #Submit search form oldurl = browser.url while browser.url == oldurl: browser.find_by_id('flightSubmitLink')[0].click() time.sleep(0.5) else: #Searching Expedia browser.visit('http://www.expedia.de/Fluege') #TODO Check if radio exists browser.choose('TripType', 'Multicity') #Enter information for first flight in search screen browser.fill('FrAirport', origin) browser.fill('FromDate', exp_departuredate) browser.fill('ToAirport', destination) #Enter information for return flight in search screen browser.fill('FrAirport2', destination) browser.fill('Date2', exp_returndate) browser.fill('ToAirport2', origin) #Enter information for return flight in search screen browser.fill('FrAirport3', xorigin) browser.fill('Date3', exp_xdate) browser.fill('ToAirport3', xdestination) #Submit search form browser.find_by_id('F-searchButtonExt1').click() #Check if price container exists if browser.is_element_not_present_by_id('type3TotalPrice0'): #Check if no flights were found or wether there is another type of error if browser.is_element_not_present_by_id('divFlightResultErrTitle'): _printnow("Unknown Error. Check screenshot.") timestamp = str(time.time()) browser.driver.save_screenshot(os.path.join('screenshots', xorigin + "-" + xdestination + "_" + timestamp + '.png')) retrytoggle = "yes" return -2 else: _printnow("No flights found for " + xorigin + "-" + xdestination) return 0 else: #Find price-text in webpage price = browser.find_by_id('type3TotalPrice0').text _printnow("Lowest price for " + xorigin + "-" + xdestination + ": " + price) #Return price without Euro character return price[1:].replace('.' , '') #---------------------------------------- #-----End of Function _searchexpedia----- #---------------------------------------- #------------------------------------------ #-----Start of function _searchmomondo----- #------------------------------------------ #Function to search expedia; Returns the price of the flight def _searchmomondo( browser, firstoutg, firstinc, secondoutg, secondinc, thirdoutg, thirdinc, firstdate, seconddate, thirddate ): browser.visit("http://www.momondo.nl/multicity/?Search=true&TripType=multi&SegNo=3&SO0=" + firstoutg + "&SD0=" + firstinc + "&SDP0=" + firstdate + "&SO1=" + secondoutg + "&SD1=" + secondinc + "&SDP1=" + seconddate + "&SO2=" + thirdoutg + "&SD2=" + thirdinc + "&SDP2=" + thirddate + "&AD=1&TK=ECO&NA=false") while not browser.is_text_present("Zoektocht compleet"): time.sleep(1) if browser.find_by_id('flight-tickets-sortbar-cheapest').visible: price = browser.find_by_id("flight-tickets-sortbar-cheapest").text.split("EUR")[0][11:].strip() _printnow("Found price: " + price + " for route: " + firstoutg + "-" + firstinc + " " + secondoutg + "-" + secondinc + " " + thirdoutg + "-" + thirdinc) return price.replace('.' , '') elif browser.is_text_present("Oeps!"): _printnow("No flights found for route: " + firstoutg + "-" + firstinc + " " + secondoutg + "-" + secondinc + " " + thirdoutg + "-" + thirdinc) return 0 else: _printnow("Unknown error. Check screenshot.") #TODO: screenshot maken return -1 #---------------------------------------- #-----End of Function _searchmomondo----- #---------------------------------------- #------------------------------------------------ #-----Start of Function _generateairportlist----- #----------------------------------------------- def _generateairportlist(countriesfilefilename): #Read the file to a list countries = [] with open(countriesfilefilename) as countriesfile: countries = countriesfile.readlines() #Remove \n from each entry in the list countries = [x.rstrip('\n') for x in countries] #Read APs from file, match against countries list and store IATA-codes in 'airport'-list (except entries without IATA code) airports = [] for airportline in open("airports.dat"): #check if country is in country list. If so, add airport of that list to airport list if any(airportline.split(",")[3][1:-1] in x for x in countries): if not len(airportline.split(",")[4][1:-1]) < 3: #add airport IATA-codes to airports - list airports.append(airportline.split(",")[4][1:-1]) #Read routes from file, match against airport-list and store routes in routes-list (removing duplicates) routes = [] for routeline in open("routes.dat"): airport_a = routeline.split(",")[2] airport_b = routeline.split(",")[4] route = airport_a + "-" + airport_b if any(airport_a in x for x in airports) and any(airport_b in x for x in airports): #check if the route already exists in the list or the reverse route exists, if not: add to list if not any(route in x for x in routes) and not any(airport_b + "-" + airport_a in y for y in routes): routes.append(route) #Tell user how many routes will be searched amount_routes = len(routes) _printnow("Found " + str(amount_routes) + " routes for 3X...") return routes #---------------------------------------------- #-----End of Function _generateairportlist----- #---------------------------------------------- #---------------------------------------- #-----Start of Function _filebackup------ #---------------------------------------- def _filebackup(namebackupfile, listofroutes): backupfile = open(namebackupfile, "wb") for item in listofroutes: backupfile.write(item + "\n") backupfile.close() _printnow("Backed progress up to session file...") #Offer user a menu and ask what she/he wants to do ans=True _printnow("\n\nFirst of all: this program is not very foolproof. I did not build in any safeguards to warn people who are using it wrongly. Therefore it is very important that you follow all instructions EXACTLY as given. The smallest typo can make the program crash or malfunction. However, it's also possible that the program crashes without you (the user) making a mistake. If so: please screenshot the error in order for me to solve in future versions. With all this mind: Let's get started with finding some X's!") print (""" Options: [1]Start a new 3X search session [2]Start a new 1X search session [3]Continue a previous search session """) ans = raw_input("What would you like to do? (Type the number of the option)") #[1] Start new 3X search session if ans == "1": print("\nStarting a new session...") type = '3X' #Set Origin, destination and dates baseflightorigin = raw_input('Enter the 3-letter IATA-code of the airport you want to depart from (eg. CDG):') baseflightdestination = raw_input('Enter the 3-letter IATA-code of the airport you want to fly to (eg. JFK):') depdate = raw_input('Enter the date of the outgoing flight in dd-mm-yy format: ') retdate = raw_input('Enter the date of the incoming flight in dd-mm-yy format (Must be AFTER outgoing flight!): ') xdate = raw_input('Enter the date of the 3X in dd-mm-yy format (Must be AFTER incoming flight!): ') #Ask user for name of the file in which a list of countries is stored which he/she wants to search for 3Xs countriesfilefilename = raw_input('Enter the name of a file containing a list of the countries you want to search:') _printnow("Generating list of routes based on " + countriesfilefilename + " file...") routeslist = _generateairportlist(countriesfilefilename) #Set the path for the backup-file based on airports and dates backupfilename = os.path.join('sessions', "3X_" + baseflightorigin + "-" + baseflightdestination + "_" + depdate + "_" + retdate + "_" + xdate + '.bu') #[3] Continue a previous 3X search session elif ans == "3": sessionfilename = raw_input("\nPlease provide the name of the session file. Check the session directory and just copy-paste the name here (including the .bu extension): ") backupfilename = os.path.join('sessions', sessionfilename) if not os.path.isfile(backupfilename): _printnow("File does not exist. Aborting...") sys.exit() else: if sessionfilename[:-3].split("_")[0] == '3X': type = '3X' baseflightorigin = sessionfilename[:-3].split("_")[1].split("-")[0] baseflightdestination = sessionfilename[:-3].split("_")[1].split("-")[1] depdate = sessionfilename[:-3].split("_")[2] retdate = sessionfilename[:-3].split("_")[3] xdate = sessionfilename[:-3].split("_")[4] #Read the file to a list countries = [] with open(backupfilename) as backupfile: routeslist = backupfile.readlines() #Remove \n from each entry in the list routeslist = [x.rstrip('\n') for x in routeslist] elif sessionfilename[:-3].split("_")[0] == '1X': type = '1X' baseflightorigin = sessionfilename[:-3].split("_")[1].split("-")[0] baseflightdestination = sessionfilename[:-3].split("_")[1].split("-")[1] depdate = sessionfilename[:-3].split("_")[2] retdate = sessionfilename[:-3].split("_")[3] xdate = sessionfilename[:-3].split("_")[4] #Read the file to a list countries = [] with open(backupfilename) as backupfile: routeslist = backupfile.readlines() #Remove \n from each entry in the list routeslist = [x.rstrip('\n') for x in routeslist] #[2] Start new 1X search session elif ans == "2": print("\nStarting a new 1X search session...") type = '1X' #Set Origin, destination and dates baseflightorigin = raw_input('Enter the 3-letter IATA-code of the airport you want to depart from (eg. CDG):') baseflightdestination = raw_input('Enter the 3-letter IATA-code of the airport you want to fly to (eg. JFK):') xdate = raw_input('Enter the date of the 1X flight in dd-mm-yy format: ') depdate = raw_input('Enter the date of the outgoing flight in dd-mm-yy format: ') retdate = raw_input('Enter the date of the incoming flight in dd-mm-yy format (Must be AFTER outgoing flight!): ') #Ask user for name of the file in which a list of countries is stored which he/she wants to search for 3Xs countriesfilefilename = raw_input('Enter the name of a file containing a list of the countries you want to search:') _printnow("Generating list of routes based on " + countriesfilefilename + " file...") routeslist = _generateairportlist(countriesfilefilename) #Set the path for the backup-file based on airports and dates backupfilename = os.path.join('sessions', "1X_" + baseflightorigin + "-" + baseflightdestination + "_" + depdate + "_" + retdate + "_" + xdate + '.bu') elif ans != "": print("\nNot a Valid Choice. Aborting...") sys.exit() #Create a new browser instance _printnow("Starting browser...") browser = Browser() #Create a backup file is (if not existing already) if not os.path.isfile(backupfilename): _printnow('creating backup file in ' + backupfilename) backupfile = open(backupfilename, "wb") backupfile.close() #Set a toggle variable which helps to determine wether to retry the same route (once) when encountering an error retrytoggle = "no" #Let's do some searching! Loop through routes! for i in range(len(routeslist)): if not "," in routeslist[i]: _printnow("Searching route " + str(i) + " of " + str(len(routeslist))) #If Looking for a 3X TODO: Merge this with "if looking for 1X" if type == "3X": #resultprice = _searchexpedia( browser, baseflightorigin , baseflightdestination, routeslist[i].split("-")[0] , routeslist[i].split("-")[1], depdate, retdate, xdate ) resultprice = _searchmomondo( browser, baseflightorigin, baseflightdestination, baseflightdestination, baseflightorigin, routeslist[i].split("-")[0], routeslist[i].split("-")[1], depdate, retdate, xdate ) #If Unknown error and only tried once before: Run the same route again if retrytoggle == "yes": printow("Retrying...") i = i -1 retrytoggle = "no" else: routeslist[i] += ',' + str(resultprice) #Write progress to file after every fifth X-check if i % 5 == 0: _filebackup(backupfilename, routeslist) #If looking for a 1X... elif type == "1X": resultprice = _searchmomondo( browser, routeslist[i].split("-")[0], routeslist[i].split("-")[1], baseflightorigin , baseflightdestination, baseflightdestination, baseflightorigin, xdate, depdate, retdate ) routeslist[i] += ',' + str(resultprice) #Write progress to file after every fifth X-check if i % 5 == 0: _filebackup(backupfilename, routeslist) if int(resultprice) < origfare: #do something to store backupfilename[:-3] + "_" + routeslist[i] + "_" + str(resultprice) browser.quit()
Run
Reset
Share
Import
Link
Embed
Language▼
English
中文
Python Fiddle
Python Cloud IDE
Follow @python_fiddle
Browser Version Not Supported
Due to Python Fiddle's reliance on advanced JavaScript techniques, older browsers might have problems running it correctly. Please download the latest version of your favourite browser.
Chrome 10+
Firefox 4+
Safari 5+
IE 10+
Let me try anyway!
url:
Go
Python Snippet
Stackoverflow Question