Möglichkeit, um Inhalt von <td>-Tag aus HTML-Code auszulesen?

Gifty43

Erfahrenes Mitglied
Hello Folks

Nach langer Abwesenheit melde ich mich wieder mal hier im Forum.

Benötige wieder mal Hilfe - diesmal geht es darum, eine HTML-Seite einzulesen und den Wert eines <td>-Tags zu bestimmen. In der Vergangenheit habe ich dies schon mit einem Online-Telefonbuch gemacht. D.h. man gibt eine Rufnummer in einem Script ein und dieses sucht sich den Namen der Person aus dem Telefonbuch. Dieses Script arbeitete mit der Snoopy.class.php. Damals sah es dann ungefähr so aus:

HTML-Code der Seite:
HTML:
.....
<table>
<td class="name">Paul</td>
<td class="adresse">Blablubbstrasse 66</td>
<td>....

Mein Script um den Namen auszulesen:
PHP:
<?
include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->fetch(http://pinkeseiten.ch/?number=0190123456);
$GrabStart = '<td class="name">';
$GrabEnd = '</td><td class="adresse">';
$GrabData = eregi("$GrabStart(.*)$GrabEnd", $snoopy->results, $output1);
$output = $output1[1];
echo $output;

Heisst soviel wie: Alles zwischen <td class="name"> und </td><td class="adresse"> wird in die Variable $output geschrieben. War einfach, weil es nur ein <td>-Tag mit der class="name" gegeben hat.


Doch nun, beim neuesten Projekt gibt es aber mehrere Tags, welche keine Klasse haben... Aber am besten zeige ich dies euch gleich am aktuellen Beispiel.

Ich möchte von dieser Seite den Dollarkurs auslesen. In der linken oberen Ecke unter "Dolar Americano", die Zeile: "Ventanillo", und Spalte: "Compra". Wenn man sich den HTML-Code anschaut, sieht das nun so aus:
HTML:
....
<tr bgcolor="#EEEEEE" >
        <td>
                        
         Ventanilla
        </td>
        <td align="right" width="44">
         12.8300 
        </td>
        <td align="right" width="44">
         13.2800 
        </td>
       </tr>
....

Also kann ich nun nicht mehr das gleiche Prinzip benutzen - da die <td>-Tags keine eindeutige Klasse haben.

Nun musste ich mich natürlich schlau machen und mich nach einer anderen Möglichkeit umsehen. Habe dann auch prompt eine gefunden: Mit Javascript - also genau die Sprache, mit der ich nicht so richtig vertraut bin. Deshalb wende ich mich nun an euch!

Ich habe mal folgendes Test-Script gebastelt:

PHP:
<?
include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->fetch("http://banamex.com.mx/esp/finanzas/index.html");
echo $snoopy->results;
?>
<script type="text/javascript">
Wertcurtest = document.getElementsByTagName("td")[20].firstChild.data;
alert("Test: " + Wertcurtest + " Dollares");
</script>

Und tatsächlich hat die Javascript-Variable "Wertcurtest" den aktuellen Kurswert (momentan: 12.8300).

So, doch nun wie weiter? Ziel ist es schlussendlich, diesen Wert in eine MySQL-Datenbank zu schreiben. Doch: PHP=Serverseitig, JavaScript=Clientseitig.
Mit AJAX könnte man den ermittelten Wert theoretisch wieder zurückgeben, richtig? Nur, sollte ich AJAX benutzen?
Schliesslich ist bei diesem Script keine Benutzeraktivität notwendig und von daher wäre es mir am liebsten, wenn keine clientseitige Verarbeitung stattfinden würde. Sprich: Ich alles mit PHP lösen kann.
Deshalb die folgenden 2 Fragen an euch:

1. Gibt es in irgendeine Möglichkeit, die JS-Funktion getElementsByTagName auch in PHP umzusetzen?
2. Welche Lösung würdet ihr mir empfehlen?

Vielen Dank für eure Hilfe!

Schönes Wochenende und Gruss
 
Zuletzt bearbeitet:
Moin,

1. Gibt es in irgendeine Möglichkeit, die JS-Funktion getElementsByTagName auch in PHP umzusetzen?

DOMDocument kennt die Methode getElementsByTagName()

Sofern diese Datei dort gültiges XML ist, könntest du sie in ein DOMDocument "importieren"...und dann wie in JS darauf zugreifen.


Falls nicht, könnte folgendes gehen(kenne dies Snoopy-Dingens allerdings nicht)

wenn du
Code:
$GrabStart = '<td';
$GrabEnd = '</td>';
...verwendest, müsste dir das einen Array mit allen <td> liefern, wo du dann das gewünschte herauspicken könntest.
Das ist allerdings nur geraten, aber probieren kostet ja nichts.:-)
 
Hey Sven

Vielen Dank für deine Vorschläge.

Der
PHP:
$GrabStart = '<td align="right" width="44">';
$GrabEnd = '</td>';

Doch er gibt im Array $output1 nur 1 Element aus - und zwar den Quellcode ab dem ersten <td align="right" width="44"> bis zum letzten </td> - somit habe ich den Quelltext der halben Seite und kann wieder nicht damit arbeiten. :(

Anyway, der Vorschlag war echt gut und ich dachte auch der würde en! Jedoch ist dieses Snoopy anscheinend nicht so schlau wie den Snoopy den ich kenne. ;)

Ich werde deinen ersten Vorschlag mal probieren und sehen ob es so funktioniert. Die Seite ist zwar kein XML-Dokument aber mal sehen...

Schönen Sonntag!

Lieber Gruss
 
Einfache String-Funktionen reichen manchmal auch:
PHP:
<?PHP
$a = array();
$s = "foo <td> bar </td><td> anything </td> else";

do
{
	// Verwerfen vom "precending"
	$s = strstr($s, "<td>");

	// Alle "child" und "descendant" aufnehmen
	$a[] = strstr($s, "</td>", true);
	
	// Alle "following" nehmen
	$s = strstr($s, "</td>");
} while ($s != "");
?>
<pre><?PHP var_dump($a); ?></pre>
Benötigt PHP 5.3.0 oder höher.
 
Zuletzt bearbeitet:
Hey Zodiac

Besten Dank für deinen Input. Scheint mir logisch und habe ich auch gleich versucht umzusetzen. ;)

PHP:
<?
include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->fetch("http://banamex.com.mx/esp/finanzas/index.html");
 
$a = array();
$s = $snoopy->results;
 
// Verwerfen vom vorherigen
$s = strstr($s, '<td align="right" width="44">');
 
while ($s != "")
{
    // Alle Child und descendant aufnehmen
    $a[] = strstr($s, "</td>", true);
    
    // Zur nächsten Fundstelle springen
    $s = strstr($s, "</td>");
    $s = strstr($s, "<td>");
}
 
var_dump($a);
?>

Es erscheint jedoch folgender Fehler:
Code:
Warning: Wrong parameter count for strstr() in /home/www/.../getrates.php on line 15
und das ca. 80-mal. (Für jeden Durchgang)

Wenn ich ein "echo $s;" vor der Schleife einbaue, sehe ich, dass der erste strstr() funktioniert. Heisst, er gibt den Quellcode ab <td align="right" width="44"> aus.

Frage: Hast du tatsächlich gemeint, es benötigt die PHP-Version 5.3.0 und nicht etwa 4.3.0? Wenn ich mich nämlich auf php.net umsehe, ist die neueste Version die 5.2.9!? Jedenfalls ist die 4.3.11 auf dem Server installiert.

Oder mach ich jetzt generell eine falsche Überlegung?


EDIT (13:31h):

Habe es gerade auch noch mit deinem neuen (13:11 Uhr) Script versucht.

PHP:
<?
include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->fetch("http://banamex.com.mx/esp/finanzas/index.html"); 

$a = array();
$s = $snoopy->results;

do
{
    // Verwerfen vom "precending"
    $s = strstr($s, '<td align="right" width="44">');

    // Alle "child" und "descendant" aufnehmen
    $a[] = strstr($s, "</td>", true);
    
    // Alle "following" nehmen
    $s = strstr($s, "</td>");
} while ($s != "");

var_dump($a);

?>

Jedoch der gleiche Fehler...


EDIT (13:35h):

OK, habe nun auf php.net im Manual von strstr() gesehen, dass der Parameter "Before_needle" - also dieses "true" - nur ab PHP 5.3.0 verfügbar ist. Von daher ist diese Lösung für mich auch unbrauchbar. :(

Danke trotzdem für deine Hilfe!


EDIT (13:45h):

Habe noch eine Möglichkeit gefunden:
PHP:
<?
include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->fetch("http://banamex.com.mx/esp/finanzas/index.html");

$a = array();
$s = $snoopy->results;

// Verwerfen vom "precending"
$s = strstr($s, '<td align="right" width="44">');

$rest = substr($s, 40, 7);

echo $rest;

?>

Jedoch weiss ich nicht, wie zuverlässig diese Lösung mit substr() ist! Nicht wirklich oder?:-)

Gibt es noch eine andere Lösung?
 
Zuletzt bearbeitet:
Zurück