Hallo Leute,
Danke nochmals für Deine Mühe. Ich habe mir das jetzt davon genommen und eingebaut, was ich brauchen konnte - und bisher keine missratenen Zeichen entdecken können!
Ich mach da auch immer noch Gehübungen mit der DOMDocument-Klassensammlung. Alles ist mir noch nicht klar. Vorhin ist mir durch die Unstabilitäten der SR-Online-Seite noch eine Merkwürdigkeit mit der Auswertung der XPath-Queries untergekommen. Leider nutzen die nicht immer dieselben Überschriften. Mal H1 und mal H2. Und der Bereich "<div></div>" hinter der eigentlichen Teaser-Meldung ist auch nicht immer vorhanden. Und da blieb dann der Teaser leer, obwohl das Query dafür vorhanden war und augenscheinlich zum vorhandenen XPath passte. Hier deshalb nochmal eine Guck- und Nachdenklösung, die einfach per Copy & Paste eine sinnvolle Ausgabe ergeben sollte.
Ich suche noch nach einer anderen Möglichkeit, aus einem eindeutigen XPath wieder eine $node zu machen. Aber das geht vermutlich nur über die Elementliste, die man per query() erhält.
<?php
header('Content-Type: text/html; CharSet="utf-8">');
$_errors = array();
function handleError($errno, $errstr, $errfile, $errline, array $errcontext)
{
global $_errors;
$_errors[] = array('errno' => $errno, 'errstr' => $errstr,
'errfile' => $errfile, 'errline' => $errline);
}
function get_links($node = NULL)
{
if ($node === NULL) return false;
$_links = array();
$__linklist = $node->getElementsByTagName('a');
if ($__linklist->length > 0)
{
foreach ($__linklist as $key => $__link)
{
if ($__link->hasAttribute('href'))
{
$_links[$key]['href'] = $__link->getAttribute('href');
$_links[$key]['linktext'] = $__link->textContent;
}
}
}
return $_links;
}
function get_nodepathes($node, $link = '')
{
$output = "[$link]: \r\n";
$_elements = $node->getElementsByTagName('*');
foreach ($_elements as $key => $element)
{
$output .= $element->getNodePath() . "\r\n";
}
return $output . "\r\n";
}
$scheme = 'http://';
$domain = 'www.sr-online.de';
$url = $scheme . $domain . '/sronline/nachrichten/hoerfunknachrichten/hoerfunknachrichten_aktuell100.html';
$page = file_get_contents($url);
$meta = '<?xml encoding="UTF-8" ?'.'>' . "\r\n";
$dom = new DOMDocument('1.0', 'utf-8');
$dom->encoding = 'utf-8';
$dom->validateOnParse = true;
$dom->strictErrorChecking = true ;
$dom->preserveWhiteSpace = true;
set_error_handler('handleError', E_WARNING);
$dom->loadHTML($meta . $page);
restore_error_handler();
$node = $dom->getElementById('mitte_text');
$_links = get_links($node);
$output = '';
foreach ($_links as $key => $link)
{
$container = file_get_contents($scheme.$domain.$link['href']);
set_error_handler('handleError', E_WARNING);
$dom->loadHTML($meta . $container);
restore_error_handler();
$node = $dom->getElementById('mitte_text');
$nodexpath = $node->getNodePath();
$output .= get_nodepathes($node, $link['href']);
$xpath = new DOMXpath($dom);
$elements = $xpath->query($nodexpath .'/h1');
if ($elements->length > 0 ) $_links[$key]['heading_1'] = $elements->item(0)->textContent;
$elements = $xpath->query($nodexpath .'/div[1]');
if ($elements->length > 0 ) $_links[$key]['heading_2'] = $elements->item(0)->textContent;
$elements = $xpath->query($nodexpath .'/div[2]');
if ($elements->length > 0 ) $_links[$key]['teaser'] = $elements->item(0)->textContent;
}
file_put_contents('sr-online.' . date('Ymd_His') . '.txt', htmlspecialchars(print_r($_links, 1)));
?>
<?php echo $meta; ?>
<!DOCTYPE HTML>
<html lang="de">
<head>
<title>SR-Online</title>
</head>
<body>
<pre>
<?php
echo htmlspecialchars($output);
echo htmlspecialchars(print_r($_links, 1));
?>
</pre>
</body>
</html>
Ich habe die Auskommentierten Versuche drin gelassen, damit man sehen kann, wie ich es außerdem noch versucht habe.
Da in $node->textContent auch derjenige Textcontent der untergeordenten Nodes enthalten ist, wenn es solche gibt, benutze ich hier immer die übergeordneten.
Man könnte wegen der Rückwandlung von Entities nun noch versuchen, die Einstellung
$dom->substituteEntities = true;
ausprobieren. Mir sind aber bisher noch keine Entities wieder untergekommen. Ich müsste dafür also extra nochmal ein Testdokument bauen.
Bei der Ausgabe müsste man dann allerdings wieder dran denken, htmlspecialchars() zu verwenden, was man ja eigentlich sowieso lieber selber machen sollte und sich nicht darauf verlassen sollte, dass SR-Online schon fertig vorgekautes Material liefert. Wenn Du dir die $_errors ausgeben lässt, wirst Du nömlich feststellen, dass sie in den Links das Ampen (&) vergessen haben. Das merkt der DOM-Parser.
Tschüss
TS