-
Notifications
You must be signed in to change notification settings - Fork 0
/
trainseeker.py
executable file
·138 lines (115 loc) · 4.81 KB
/
trainseeker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import datetime
from datetime import datetime, timedelta
import time
import re
import selenium.webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from var_dump import var_dump
CONF = {
"url": "http://www.trocdestrains.com/recherche-billet-train.html",
}
month = ["janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre" ]
week = [ 'lundi', 'mar', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche']
def valid_date(s):
try:
date = datetime.strptime(s, "%d-%m-%Y")
if date < datetime.today() - timedelta(days=1):
msg = "%s is in the past!" % date.strftime("%d/%m/%y")
argparser.error(msg)
return date
except ValueError:
msg = "Not a valid date: '{0}'. Format: dd-mm-yyyy.".format(s)
argparser.error(msg)
def valid_hour(s):
hour = int(s)
if hour >= 0 and hour <= 24:
return hour
else:
msg = "Not a valid hour: '%s'. Valid hours: 0 to 24." % s
argparser.error(msg)
argparser = argparse.ArgumentParser()
argparser.add_argument('-d', '--departure', help='Departure city', required=True)
argparser.add_argument('-a', '--arrival', help='Destination city', required=True)
argparser.add_argument('-t', '--date', required=True, help='Date of departure. Format: dd-mm-yyyy', type=valid_date)
argparser.add_argument('-h1', '--min', help='minimim hour of departure.', type=valid_hour)
argparser.add_argument('-h2', '--max', help='maximum hour of departure.', type=valid_hour)
args = argparser.parse_args()
if args.min is None:
args.min = 0;
if args.max is None:
args.max = 24;
print "Recherche billet: %s => %s le %s %d %s entre %dh et %dh" %(args.departure, args.arrival, week[args.date.weekday()], args.date.day, month[args.date.month - 1], args.min, args.max)
#init webdriver
options = selenium.webdriver.chrome.options.Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
driver = selenium.webdriver.Chrome(executable_path="/usr/bin/chromedriver", chrome_options=options)
#enter travel infos
driver.get(CONF['url'])
depart_elt = driver.find_element_by_id('ville_dep')
depart_elt.clear()
depart_elt.send_keys(args.departure)
arrival_elt = driver.find_element_by_id('ville_arr')
arrival_elt.clear()
arrival_elt.send_keys(args.arrival)
#day
select = Select(driver.find_element_by_name('L_jour_dep'))
select.select_by_visible_text(str(args.date.day).zfill(2))
#month
select = Select(driver.find_element_by_name('L_mois_annee_dep'))
month_str = "%s %s" % (month[args.date.month - 1] , args.date.year)
select.select_by_visible_text(month_str)
#hour
select = Select(driver.find_element_by_name('L_h_deb_r'))
select.select_by_visible_text('%sh' % str(args.min).zfill(2))
select = Select(driver.find_element_by_name('L_h_fin_r'))
select.select_by_visible_text('%sh' % str(args.max).zfill(2))
#search it !
driver.find_element_by_name('choix_rech_billet').click()
#wait for results
msg_xpath = "//div[@id='msg_rech_billets']//span"
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, msg_xpath))
)
msg = driver.find_element_by_xpath(msg_xpath).text
print msg
match = re.match(r"^([0-9]+) billets? trouv", msg)
if match is not None:
nb_tickets = int(match.group(1))
if nb_tickets > 0:
tickets = driver.find_elements_by_xpath("//div[@class='liste-billets']//div[1]//span[@class='billet arrondi-10']")
#loop on tickets
tickets_infos = []
for billet_idx, ticket in enumerate(tickets, start=1):
if billet_idx > nb_tickets:
break
print "Billet %d" % billet_idx
#stations, time
steps = []
stations = ticket.find_elements_by_xpath(".//span[@class='col-gares']//span")
for idx, station in enumerate(stations, start=1):
if station.text != ' ':
time = ticket.find_element_by_xpath(".//span[@class='col-heures']//span[%d]" % idx)
station_info = {'station': station.text, 'time': time.text}
steps.append(station_info)
#price
price_text = ticket.find_element_by_xpath(".//span[@class='col-date']//span[@class='prix']").text
match = re.match(r"^([0-9]+\.?[0-9]+) . par place$", price_text)
price = float(match.group(1))
#var_dump(price)
ticket_infos = {'steps': steps, 'price': price}
pretty_msg = ' '
#var_dump(ticket_infos)
for idx, steps in enumerate(ticket_infos['steps'], start=1):
pretty_msg += " %s: %s" % (steps['time'], steps['station'])
if idx < len(ticket_infos['steps']):
pretty_msg += " =>"
print pretty_msg + " %0.2fEUR" % price
tickets_infos.append(ticket_infos)