# Bahn RIS aulesen



## dennis-sauer (14. Januar 2011)

Hallo zusammen,

ich möchte gerne folgendes versuchen:

Bahn.de/ris bietet Informationen zu einem Bahnhof zur aktuellen Betriebslage. Ich möchte mir jetzt gern eine kleine lokale Startseite erstellen mit Infos und Links für mich und mir die aktuelle Betriebslage an meinem Bahnhof anzeigen lassen. 

Habe ich eine Möglichkeit dies auszulesen und bei mir aufzubereiten?

Ich habe schon etwas in einem anderen Forum gefunden: http://www.ip-symcon.de/forum/f53/class-abfahrtstafeln-bahn-de-auslesen-10416/

Bin aber ehrlich: Ich komme damit nicht klar. Curl habe ich nicht. Ich nutze Zuhause lokal EASYPHP. Hab mir mal die Infos aus dem Forum herausgeholt doch bei mir wird nur der Quelltext im Browser angezeigt.

Vielleicht hat jemand noch eine andere Idee... Das wär super!

Danke im Voraus

Dennis


----------



## Flex (14. Januar 2011)

cURL brauchst du nicht, es wird ja direkt eine alternative Methode ohne cURL beschrieben. 
Wenn du im Browser nur den Quelltext siehst, funktioniert dein EasyPHP Paket nicht richtig und du hast es vermutlich falsch installiert.


----------



## saftmeister (14. Januar 2011)

Wie rufst du denn die Seite lokal auf?


----------



## dennis-sauer (14. Januar 2011)

Hallo,

danke erstmal für eure Antworten. Ich rufe sie per localhost/startseite/ris.php auf...

Ja die Alternative habe ich gesehen, muss zugeben so richtig blick ich nicht durch.

1. Ich habe die Seite class.bahn.php erstellt mit dem dort angegebenen Quelltext

2. Ich habe eine Seite Namens index.php erstellt

ursprünglich mit dem Quelltext


```
require_once("class.bahn.php"); // Klasse einbinden 

// Neue Instanz 
//Parameter 1 ist der Bahnhof oder die Haltestelle 
//(es muss kein Bahnhof sein, Bushaltestelle gehen auch) 
// Parameter 2 ist die Art der Tafel: "Abfahrt" oder "Ankunft" 
$bahn=new bahn("Hannover Hbf","abfahrt"); 


// Hier werden Verkehrsmittel ausgeschlossen 
/* 
$bahn->TypeBUS(false); 
$bahn->TypeTRAM(false); 
$bahn->TypeICE(false); 
$bahn->TypeIC(false); 
$bahn->TypeRE(false); 
$bahn->TypeSBAHN(false); 
$bahn->TypeUBAHN(false); 
$bahn->TypeFAEHRE(false); 
*/ 

// Hier werden Datum und Zeit gesetzt. 
// Werden die nicht gesetzt wird die/das aktuelle Zeit/Datum genommen 
/* 
$bahn->datum("17.5.2010"); 
$bahn->zeit("1:00"); 
*/ 

// Jetzt das Ergebniss holen! 
$abfragestatus=$bahn->fetch(); 
if($abfragestatus){ 
        // Array mit den Informationen ausgeben: 
    print_r($bahn->timetable); 
}
```

da ich aber Curl nicht nutze habe ich den Quelltext:


```
require_once("class.bahn.php"); // Klasse einbinden 

$bahn=new bahn("München Hbf","abfahrt"); 

// Hier wird gesagt das KEIN Curl genutzt wird! 
$bahn->fetchMethodCURL(false);  

// Jetzt wirds interessant: 
// Nachdem alle Parameter wie gewünscht getzt sind 
// holt man sich die Anfrageurl für bahn.de: 
$url = $bahn->buildQueryURL(); 
// Diese Url kann man nun in den WWW_Reader füttern 
// und die Daten per RegVar verarbeiten.
```

Ich muss zugeben wo ich das jetzt eintausche in den Quelltext MIT Curl ist mir nicht ganz klar.

Und dann ist dort noch was mit Regvar angegeben 

Grüße 

Dennis


----------



## saftmeister (14. Januar 2011)

Wegen dem Quellcode: Auch auf die Gefahr hin, das ich mich lächerlich mache, du rufst die Seite genauso auf oder setzt du auch noch ein http:// davor?


----------



## dennis-sauer (14. Januar 2011)

Hallo,

sorry, ja klar setze ich noch ein http:// davor... sorry! Hatte ich vergessen

Ich denke eher der Fehler liegt an mir. Die zweite Variante ohne Curl sieht irgendwie wenig aus und dann noch das mit der Regvar, davon hab ich zugegebenermaßen noch nie etwas gehört.


----------



## saftmeister (14. Januar 2011)

Jetzt lösen wir erst mal dein Quell-Text-Problem: Hast du die PHP-Tags vor und hinter dem Code eingefügt?

Also so in etwa:


```
<?php

// hier ein bisschen Kommentar
echo "Und eine Ausgabe";

$a = 5; // Variablen erstellen und mit Werten füllen...

?>
```


----------



## dennis-sauer (14. Januar 2011)

Hallo,

ist glaub ich einfach, wenn ich mal das darstelle was ich real und aktuell habe:


```
<?

require_once("class.bahn.php"); // Klasse einbinden 

$bahn=new bahn("München Hbf","abfahrt"); 

// Hier wird gesagt das KEIN Curl genutzt wird! 
$bahn->fetchMethodCURL(false);  

// Jetzt wirds interessant: 
// Nachdem alle Parameter wie gewünscht getzt sind 
// holt man sich die Anfrageurl für bahn.de: 
$url = $bahn->buildQueryURL(); 
// Diese Url kann man nun in den WWW_Reader füttern 
// und die Daten per RegVar verarbeiten.  


    //Ab hier nichts mehr ändern
    $object = IPS_GetObject($IPS_SELF);
    $parentID = $object['ParentID'];


// Hier werden Verkehrsmittel ausgeschlossen
/*
$bahn->TypeBUS(false);
$bahn->TypeTRAM(false);
$bahn->TypeICE(false);
$bahn->TypeIC(false);
$bahn->TypeRE(false);
$bahn->TypeSBAHN(false);
$bahn->TypeUBAHN(false);
$bahn->TypeFAEHRE(false);
*/

// Hier werden Datum und Zeit gesetzt.
// Werden die nicht gesetzt wird die/das aktuelle Zeit/Datum genommen
/*
$bahn->datum("14.01.2011");
$bahn->zeit("15:00");
*/

// Jetzt das Ergebniss holen!
$abfragestatus=$bahn->fetch();
if($abfragestatus){
        // Array mit den Informationen ausgeben:
    print_r($bahn->timetable);
    AnzeigeAufbereiten($bahn,"Abfahrt München",$parentID);
}

// zweite Anzeigentafel
$bahn=new bahn("Lehrte","ankunft");
$abfragestatus=$bahn->fetch();
if($abfragestatus){
        // Array mit den Informationen ausgeben:
    print_r($bahn->timetable);
    AnzeigeAufbereiten($bahn,"Ankunft München",$parentID);
}

// anzeige aufbereiten in eine html box
function AnzeigeAufbereiten($bahn, $name,$parentID)
{
    $VARIABLEN_TEXT=$name;

    // Anzeige aufbereiten
    $str = "<table width='90%' align='center'>"; // Farbe anpassen oder style entfernen
    $str .= "<tr><td></td><td><b>Zug</b></td><td><b>Zeit</b></td><td><b>Richtung</b></td><td><b>Gleis</b></td><td><b>Aktuelles</b></td></tr>";

    $pos = 0;
    for($i=3; $i<=sizeof($bahn->timetable); $i++)
    {
        //$eintrag = explode(";", $bahn->timetable[$i]);
        $caller = $bahn->timetable[$i]["type"];
        switch($caller) {
           case "SBAHN":
              $eintrag[0] = "<img src=/user/bahn/sbahn_24x24.gif>";
              break;
           case "BUS":
              $eintrag[0] = "<img src=/user/bahn/bus_24x24.gif>";
              break;
           case "RE":
              $eintrag[0] = "<img src=/user/bahn/re_24x24.gif>";
              break;
           case "ICE":
              $eintrag[0] = "<img src=/user/bahn/ice_24x24.gif>";
              break;
           case "TRAM":
              $eintrag[0] = "<img src=/user/bahn/tram_24x24.gif>";
              break;
            default:
               $eintrag[0] = "";
               break;
        }
        $eintrag[1] = $bahn->timetable[$i]["train"];
        $eintrag[2] = $bahn->timetable[$i]["time"];
        $eintrag[3] = $bahn->timetable[$i]["route_ziel"];
        $eintrag[4] = $bahn->timetable[$i]["platform"];
        $eintrag[5] = $bahn->timetable[$i]["ris"];

            $str .= "<tr>";
            foreach($eintrag as $data)
                $str .= '<td>'.$data.'</td>';
            $str .= "</tr>";

            $pos++;

        if($pos >= 4)
            break;
    }
    $str .= "</table>";

    $vid = CreateVariableByName($parentID, $VARIABLEN_TEXT, 3);
    IPS_SetIcon($vid, "Distance");
    IPS_SetVariableCustomProfile($vid, "~HTMLBox");
    SetValue($vid, $str);
}

function CreateVariableByName($id, $name, $type)
{
    global $IPS_SELF;
    $vid = @IPS_GetVariableIDByName($name, $id);
    if($vid === false)
    {
        $vid = IPS_CreateVariable($type);
        IPS_SetParent($vid, $id);
        IPS_SetName($vid, $name);
        IPS_SetInfo($vid, "this variable was created by script #$IPS_SELF");
    }
    return $vid;
}

?>
```

und die class.bahn.php Datei


```
<? 
class bahn{ 
    var $_BASEURL="http://reiseauskunft.bahn.de/bin/bhftafel.exe/dn?"; 
    var $_PARAMS=array(); 
    var $timetable=array(); 
    var $bahnhof=false; 
    var $_FETCHMETHOD; 
    function bahn($bahnhof=null,$type="abfahrt"){ 
       $type=strtolower($type); 
     
     
       if(!$bahnhof) 
          $bahnhof="München HBF"; 
        $this->_init($bahnhof); 
        $this->fetchMethodCURL(true); 
        $this->boardType($type); 
         
        //$this->_query(); 
    } 

    function TypeBUS($state=true){$this->_PARAMS['GUIREQProduct_5'] = ($state) ? "on" : false;} 
    function TypeICE($state=true){$this->_PARAMS['GUIREQProduct_0'] = ($state) ? "on" : false;} 
    function TypeIC($state=true){$this->_PARAMS['GUIREQProduct_1'] = ($state) ? "on" : false;} 
    function TypeRE ($state=true){$this->_PARAMS['GUIREQProduct_3'] = ($state) ? "on" : false;} // NV genannt 
    function TypeSBAHN ($state=true){$this->_PARAMS['GUIREQProduct_4'] = ($state) ? "on" : false;}  
    function TypeFAEHRE ($state=true){$this->_PARAMS['GUIREQProduct_6'] = ($state) ? "on" : false;}   // UBAHN 
    function TypeTRAM ($state=true){$this->_PARAMS['GUIREQProduct_8'] = ($state) ? "on" : false;}   // Strassenbahn 
    function TypeUBAHN ($state=true){$this->_PARAMS['GUIREQProduct_7'] = ($state) ? "on" : false;}   // UBAHN 



    function boardType($type){ 
        if($type=="ankunft") 
            $this->_PARAMS['boardType']="arr"; 
        else 
            $this->_PARAMS['boardType']="dep"; 

    } 

    function datum($datum){ 
        $this->_PARAMS['date']=$datum; 
    } 
     
    function zeit($zeit){ 
        $this->_PARAMS['time']=$zeit; 

    } 

    /** 
     * 
     **/ 
    function fetch($html=null){ 
       if($html){ 
          return $this->_parse($html); 
       }else if($this->_FETCHMETHOD=="CURL"){ 
            return $this->_queryCurl(); 
        } 
    } 


    function _queryCurl(){ 
        $this->buildQueryURL(); 
        $result=$this->_call(); 
        return $this->_parse($result); 
    } 

    function buildQueryURL(){ 
       $fields_string=""; 
        foreach($this->_PARAMS as $key=>$value){ 
           if($value) 
                $fields_string .= $key.'='.urlencode($value).'&'; 
        }; 
        rtrim($fields_string,'&'); 

        $this->_URL=$this->_BASEURL.$fields_string; 
        return $this->_URL; 
    } 

    function _parse($data){ 
        $dom = new DOMDocument(); 
        @$dom->loadHTML($data); 
         
        $select=$dom->getElementById("rplc0"); 
        if($select->tagName=="select"){ 
            $options=$select->getElementsByTagName("option"); 
            foreach($options AS $op){ 
                echo utf8_decode($op->getAttribute("value")."-".$op->nodeValue)."n"; 
            } 
            return false; 
        }else{ 
           $this->bahnhof=utf8_decode($select->getAttribute("value")); 
            $this->_process_dom($dom); 
            return true; 
        } 
    } 

    function _process_dom($dom){ 
            $test=$dom->getElementById("sqResult")->getElementsByTagName("tr"); 
            $data=array(); 
            foreach($test as $k=>$t){ 
                $tds=$t->getElementsByTagName("td"); 
                foreach($tds AS $td){ 
                   $dtype=$td->getAttribute("class"); 
                    switch($dtype){ 
                        case 'train': 
                            if($a=$td->getElementsByTagName("a")->item(0)){ 
                                $data[$k]['train']=str_replace(" ","",$a->nodeValue); 
                                if($img=$a->getElementsByTagName("img")->item(0)){ 
                                    if (preg_match('%/([a-z]*)_%', $img->getAttribute("src"), $regs)) { 
                                       switch($regs[1]){ 
                                          case 'EC': 
                                             $data[$k]['type']="IC"; 
                                          break; 
                                            default: 
                                                $data[$k]['type']=strtoupper($regs[1]); 
                                            break; 
                                        } 
                                    } 
                                } 
                            } 
                             
                        break; 
                        case 'route': 
                           if($span=@$td->getElementsByTagName("span")->item(0)){ 
                              $data[$k]['route_ziel']=$span->nodeValue; 
                            } 

                            preg_match_all('/(.*)s*([0-9:]{5})/', $td->nodeValue, $result, PREG_PATTERN_ORDER); 
                            $tmp=array(); 
                            foreach($result[1] AS $rk=>$rv){ 
                                $tmp[$result[2][$rk]]=utf8_decode(trim(html_entity_decode(str_replace("n","",$rv)))); 
                            } 
                            $data[$k]['route']=$tmp; 
                            //print_r($tmp); 
                            /* 

                            $data[$k]['route']=explode("-",$td->nodeValue); 
                            foreach($data[$k]['route'] AS $dk=>$dv) 
                               $data[$k]['route'][$dk]=utf8_decode(trim(html_entity_decode(str_replace("n","",$dv)))); 
                            */ 
                        break; 
                        case 'time': 
                        case 'platform': 
                        case 'ris': 
                           $data[$k][$dtype]=$td->nodeValue; 
                        break; 


                    } 
                    //echo "n"; 
                } 
            } 

            foreach($data AS $d){ 
                if(array_key_exists("train",$d)){ 
                   foreach($d AS $dk=>$dv) 
                      if(!is_array($dv)) 
                          $d[$dk]=ltrim(str_replace("n","",utf8_decode(trim(html_entity_decode($dv)))),"-"); 
                    $d['route_start']=$this->bahnhof; 
                    $this->timetable[]=$d; 
             } 
            } 
    } 

    function fetchMethodCURL($state){ 
        if($state){ 
            $this->_FETCHMETHOD="CURL"; 
        }else{ 
            $this->_FETCHMETHOD="OTHER"; 
        } 
    } 


    function _call(){ 
        $this->_CH = curl_init(); 
        curl_setopt($this->_CH,CURLOPT_RETURNTRANSFER,true); 
        curl_setopt($this->_CH,CURLOPT_URL,$this->_URL); 
        $result = curl_exec($this->_CH); 
        curl_close($this->_CH); 
        return $result; 
    } 

    function _init($bahnhof){ 
        $this->_PARAMS=array( 
            'country'=>'DEU', 
            'rt'=>1, 
            'GUIREQProduct_0'=>'on',    // ICE 
            'GUIREQProduct_1'=>'on',   // Intercity- und Eurocityzüge 
            'GUIREQProduct_2'=>'on',   // Interregio- und Schnellzüge 
            'GUIREQProduct_3'=>'on',   // Nahverkehr, sonstige Züge 
            'GUIREQProduct_4'=>'on',    // S-Bahn 
            'GUIREQProduct_5'=>'on',    // BUS 
            'GUIREQProduct_6'=>'on',    // Schiffe 
            'GUIREQProduct_7'=>'on', // U-Bahn 
            'GUIREQProduct_8'=>'on', // Strassenbahn 
            'REQ0JourneyStopsSID'=>'', 
            'REQTrain_name'=>'', 
            'REQTrain_name_filterSelf'=>'1', 
            'advancedProductMode'=>'', 
            'boardType'=>'dep', // dep oder arr 
            'date'=>date("d.m.Y"), 
            'input'=>$bahnhof, 
            'start'=>'Suchen', 
            'time'=>date("H:i") 
        ); 


    } 

} 

?>
```


----------



## saftmeister (14. Januar 2011)

Ok, wenn der php.ini-Parameter short_open_tag auf false steht (derzeitig vermutlich der Fall), wird der PHP-Code nicht erkannt. Mach doch bitte aus dem <? ein <?php, dann sollte das schon mal funktionieren.


----------



## dennis-sauer (14. Januar 2011)

Ok das hatte ich total übersehen hat insofern weitergeholfen das ich nun eine Fehlermeldung bekomme. 

Index.php Zeile 19


```
$object = IPS_GetObject($IPS_SELF);
```

Fatal error: Call to undefined function IPS_GetObject() in C:\EasyPHP 3.0\www\ris_test\index.php on line 19


----------



## timestamp (14. Januar 2011)

Das bedeutet dass die Funktion nicht definiert ist. Sicher dass du sie richtig geschrieben hast?


----------



## saftmeister (14. Januar 2011)

Prima. Das bedeutet, PHP springt jetzt schon mal auf seinen Code an. Das bedeutet, dir fehlt ein weiteres Script, in dem die Funktion IPS_GetObject() definiert ist.

Wenn man Google danach fragt, bekommt man die Seite, von der du das Script hast bzw. seine Dokumentation: http://www.ip-symcon.de/service/dokumentation/befehlsreferenz/objektverwaltung/ips-getobject/

Sprich, du brauchst das Packet, in dem dieser IPS-Kram liegt: http://www.ip-symcon.de/service/downloads/

Offensichtlich ist das aber nur mit einer Lizenz verwendbar.


----------



## dennis-sauer (16. Januar 2011)

Hallo zusammen,

sorry war übers Wochenende weg...

Danke erstmal für eure hilfreichen und schnellen Antworten. Hab mir das mal angeschaut, also 100 Euro dafür ausgeben lohnt ja nicht wirklich für meine Idee...

Gibt es vielleicht eine andere Möglichkeit, die auf der Bahn-Ris Seite angegebenen Daten "auszulesen" und bei mir anzuzeigen? 

Grüße


----------



## Flex (16. Januar 2011)

Google findet nix außer einigen Beiträgen, dass die Bahn es eben verpeilt hat beim letzten Redesign eine vernünftige API einzubinden... Von daher würde ich sagen, dass es da nicht mal eben so möglich ist.


----------



## saftmeister (16. Januar 2011)

Naja, du könntest das nachbauen, was die als PHP-Scripte kostenpflichtig zur Verfügung stellen.

Du hast da zwar keinen Quelltext, aber so schwer stelle ich mir das jetzt auch nicht vor.

Du brauchst erstmal nen PHP-HTTP-Client wie z.B. Snoopy. Dem musst du die URL 


```
http://reiseauskunft.bahn.de/bin/bhftafel.exe/dn?
```

übergeben, zusammen mit GET-Parametern. Dann bekommst du Results zurück, die vermutlich noch irgendwie aufbereitet werden müssen. So wie es für mich aussieht, müsste man den Result einfach an die Methode fetch() übergeben. Das ganze könnte ungefähr so aussehen:


```
<?php
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);

require "bahn.php";
require "Snoopy.class.php";

$bahn = new bahn("München Hbf");

$snoopy = new Snoopy();
$snoopy->fetchtext($bahn->buildQueryURL());

$fahrten = $bahn->fetch( $snoopy->results );

?>
<pre>
<?php
var_dump($fahrten);
?>
</pre>
```

Keine Garantie, dass das funktioniert ;-)

EDIT:

So funktioniert es besser:


```
<?php
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
 
require "bahn.php";
require "Snoopy.class.php";
 
$bahn = new bahn("München HBF");
 
$snoopy = new Snoopy();
$snoopy->fetch($bahn->buildQueryURL());

$results = $snoopy->results;
$bahn->fetch( $snoopy->results );
 
?>
<pre>
<?php
var_dump($bahn->timetable);
?>
</pre>
```


----------

