Trenitalia e Viaggiatreno: come implementare un servizio “fai da te” per avere le informazioni dello stato di un treno via SMS

Da quando sono diventato un pendolare (per lavoro), ho iniziato a (ri)frequentare assiduamente le stazioni ferroviarie e i treni di Trenitalia.

station.

Dopo un paio di settimane passate sui treni, mi sono accorto di un servizio interessante: il sito Viaggiatreno: il sito contiene le informazioni sui treni (informazioni in tempo reale sullo stato di un treno come ritardo o anticipo, ora prevista di arrivo e fermate già effettuate).

Esigenza

Dopo aver provato il disagio di un treno soppresso (e quindi essermi svegliato un’ora prima per stare un’ora ad aspettare in stazione), mi sono reso conto di poter, perlomeno, arginare il problema se si fosse presentato in futuro; conoscere lo stato del treno direttamente sul telefonino mi permetterebbe, la mattina, di poter scegliere un mezzo alternativo senza recarmi in stazione nel caso in cui il treno sia in ritardo o soppresso. Oppure, se il treno è in anticipo, di accelerare i tempi.

Soluzioni esistenti

  • Potrei controllare il sito Viaggiatreno accedendo il computer, connettendomi a Internet e andando sul sito Viaggiatreno. Contro: il tempo richiesto è troppo (~ 5 minuti. E la mattina anche 5 minuti sono preziosissimi).
  • Potrei installare su iPhone l’applicazione ProntoTreno, un’applicazione che fornisce lo stato di tutti i treni in tempo reale. Contro: il mio access point WIFI non è sempre attivo; non ho a disposizione la connessione 3G. Inoltre, se dovessi cambiare telefono per passare ad un telefono senza WIFI/3G, questa soluzione non è più applicabile.

L’idea

Il mezzo da utilizzare è sicuramente il mobile. L’incognita era semplicemente trovare il modo per raggiungere i telefoni, ed è stato individuato negli SMS, supportati da tutti i telefoni.

L’altro fattore da tenere in considerazione è: come ottenere i dati da Viaggiatreno? Il sito utilizza Flash, ed estrarre informazioni testuali e puntuali da Flash penso sia infattibile. La soluzione è presto trovata: fortunatamente, Viaggiatreno offre anche una versione mobile, realizzata in (X)HTML, per la gioia dei parser.

La realizzazione

Per la realizzazione del servizio abbiamo bisogno di:

  • Un server Linux attivo e connesso a Internet durante il lasso di tempo in cui vogliamo essere avvisati via SMS. Inoltre, il server Linux deve avere installato crontab, l’interprete python e alcuni pacchetti python che vedremo più avanti.
  • Un servizio per mandare SMS gratuitamente: io mi appoggio a virgilio.it, che mi permette di ricevere via sms tutte le email ricevute all’indirizzo indirizzo@sms.tin.it [per i più impazienti: in questo modo per ricevere SMS è sufficiente mandare una mail]. Se invece non potete usare virgilio.it, vi raccomando di utilizzare MoioSMS per l’invio gratuito di SMS.
  • Un account GMail da cui mandare la mail del punto sopra (se siete degli smanettoni, non avete bisogno di questo e potrete usare il vostro SMTP, a patto di sostituirlo nel codice).
  • Un telefono mobile abilitato alla ricezione di SMS e attivo (ovviamente!)
  • Il numero del treno di nostro interesse: per conoscere il numero del treno, è sufficiente andare su TreniItalia, immettere partenza e arrivo e annotarsi il numero del treno. Il numero del treno è unico e non cambia.
  • Lo script python seguente, che ho scritto in Python utilizzando le librerie python-mechanize e python-beautifulsoup (installatele seguendo la guida per la vostra distribuzione. Per Ubuntu/Debian ho usato apt-get install python-mechanize python-beautifulsoup). Il codice è ancora immaturo, ma funziona (vedi screenshot):
    #! /usr/bin/python
    
    import BeautifulSoup
    import mechanize
    import smtplib
    import time
    import datetime
    from email.MIMEMultipart import MIMEMultipart
    from email.MIMEBase import MIMEBase
    from email.MIMEText import MIMEText
    from email import Encoders
    import os
    import sys
    
    gmail_user = "gmail username"
    gmail_pwd = "gmail pass"
    
    def mail(to, subject, text):
        msg = MIMEMultipart()
    
        msg['From'] = gmail_user
        msg['To'] = to
        msg['Subject'] = subject
    
        msg.attach(MIMEText(text))
    
        mailServer = smtplib.SMTP("smtp.gmail.com", 587)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(gmail_user, gmail_pwd)
        mailServer.sendmail(gmail_user, to, msg.as_string())
        mailServer.close()
    
    numtreno = sys.argv[1]
    stazione = sys.argv[2]
    
    tobeparsed = mechanize.urlopen(str(str('https://mobile.viaggiatreno.it/viaggiatreno/mobile/scheda?numeroTreno=') + str(numtreno) + str('&tipoRicerca=numero&lang=IT')))
    f = BeautifulSoup.BeautifulSoup(tobeparsed)
    f = f.prettify()
    f = f[f.find('<!-- SITUAZIONE -->'):]
    f = f[:f.find('</div>')]
    s1 = f[f.find('<strong>')+len('<strong>'):f.find('<br />')]
    s2 = f[f.rfind('-->')+len('-->'):f.find('</strong>')]
    s1 = s1.replace('&#039;',"'")
    s1 = s1.split()
    s2 = s2.split()
    tobeparsed = mechanize.urlopen(str(str('https://mobile.viaggiatreno.it/viaggiatreno/mobile/scheda?dettaglio=visualizza&numeroTreno=') + str(numtreno) + str('&tipoRicerca=numero&lang=IT')))
    f = BeautifulSoup.BeautifulSoup(tobeparsed)
    f = f.prettify()
    f = f[f.find(stazione):]
    f = f[:f.find("</div>")]
    arr1 = f[f.find('<p>')+len('<p>'):f.find('<br />')]
    or1 = f[f.find('<strong>')+len('<strong>'):f.find('</strong>')]
    arr = f[f.rfind('<p>'):f.rfind('</p>')]
    arr2 = arr[arr.find('<p>')+len('<p>'):arr.find('<br />')]
    or2 = arr[arr.find('<strong>')+len('<strong>'):arr.find('</strong>')]
    arr1 = arr1.split()
    or1 = or1.split()
    arr2 = arr2.split()
    or2 = or2.split()
    arr1.extend(or1)
    arr2.extend(or2)
    
    L = [s1, s2, arr2]
    for i in xrange(len(L)):
        L[i] = ' '.join(L[i])
    message = '\n'.join(L)
    
    mail("indirizzo@sms.tin.it",
    sys.argv[1],
    message,
    )
    

    Il codice estrae le informazioni di interesse da Viaggiatreno mobile (come detto, per fare il parsing occore usare il sito in versione mobile) come lo stato corrente del treno (posizione ed eventuali minuti di ritardo o anticipo) e l’orario di arrivo previsto e manda queste informazioni all’indirizzo mail “speciale” che gira il messaggio al mio numero di cellulare via SMS [per l’invio della mail il servizio usa GMail]. Come detto, potreste usare MoioSMS (via pipe o python import) semplicemente sostituiendo la parte di invio della mail.

Come si utilizza?

  • Lo script accetta due parametri da command-line: il numero di treno a cui siete interessati e la stazione di cui volete conoscere l’orario di arrivo stimato (es. “LECCO MAGGIANICO”).
  • Modificate, nello script le variabili gmail_user e gmail_password con le credenziali del vostro account GMail che useremo per spedire la mail verso l’indirizzo speciale che girerà le mail in SMS. Sempre nel codice, sostituite appunto indirizzo@sms.tin.it con il vostro indirizzo “speciale” che tramuta il messaggio e-mail in SMS.
  • Usando crontab, inserite una entry del tipo:
    08 07 * * 1-5 python /home/mbologna/parser.py 5033 “LECCO MAGGIANICO”
    Per avere un aggiornamento via SMS alle 07:08 di tutti i giorni feriali del treno 5033 specificando che deve fornirci l’orario di arrivo previsto alla stazione di “LECCO MAGGIANICO”.

Risultati

La mattina, prima di recarmi in stazione, controllo sul mio telefono e automaticamente ricevo 3 SMS gratuiti diversi contenenti lo stato del treno man mano che si avvicina alla stazione in cui io salgo sul treno. In questo modo, ancora prima di uscire di casa, posso sapere se il treno è in ritardo o se è stato soppresso.

Qui accanto, la testimonianza di 2 degli SMS che ricevo quotidianamente.

Sviluppi futuri

  • Miglioramento del codice di download/parsing
  • Integrazione con MoioSMS

Curiosità

Creative Commons License photo credit: xsilviax L.

9 thoughts on “Trenitalia e Viaggiatreno: come implementare un servizio “fai da te” per avere le informazioni dello stato di un treno via SMS”

Leave a Reply

Your email address will not be published. Required fields are marked *