You are not logged in.

  • Login

1

Sunday, November 21st 2010, 6:32pm

DOMDocument hat probleme mit website. Exception?

Hallo,

Source code

1
2
3
4
$doc = new DOMDocument();
echo "+++++ DOMDocument generated<br>";
$doc->loadHTMLFile("http://www.faz.net/d/ts/link.aspx?key=navi_Aktuell_Feuilleton_TVRadioprogramm&lnk=http%3a%2f%2ftv.faz.net%2f");
echo "feddisch";


bei unter anderem dieser URL hat DOMDocument Probleme: Fehler ist, dass der Code einfach nicht mehr ausgeführt wird und den Browser aufhängt oder dieser manchmal wenigstens durch einen Timeout aussteigt.

Mein Anliegen ist jetzt noch nicht einmal, unbedingt diese Seite geparsed zu bekommen, sondern eher einen Weg zu finden, der mir sagt: Fehler -> mache anders weiter.

Ich hab' es mit try-catch und or-die versucht, hat aber keine auswirkungen.

kennt das problem jemand?

grüße,

ehw

2

Sunday, November 21st 2010, 6:38pm

Also ich würde empfehlen die Datei in einem eigenen Schritt herunterzuladen.
Dann kannst du dort ein Timeout angeben und bei den zwei getrennten Schritten kann es eigentlich nicht zu einem Fatal Error kommen.
Somit muss dein try/catch auch funktionieren.

Sollten dich übrigens die ganzen Parser Warnungen in den Logfiles stören hier noch zwei Einstellungen die ich beim DOMDocument parsen immer verwende

PHP Quellcode

1
2
3
// hide all the ugly DOMDocument warnings
libxml_clear_errors();
libxml_use_internal_errors(true);

3

Sunday, November 21st 2010, 7:40pm

das scheint so auch erstmal nicht eindeutig zu funktionieren:

Ertmal: Wie äußert sich denn ein Fatal Error? Wie kann ich denn einen Timeout angeben?

Ich mache das jetzt so:

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
$url = "http://www.faz.net/d/ts/link.aspx?key=navi_Aktuell_Feuilleton_TVRadioprogramm&lnk=http%3a%2f%2ftv.faz.net%2f";
 
$doc = new DOMDocument();
echo "+++++ DOMDocument generated<br>";
try {
    $html = file_get_contents($url);
    echo "+++++ file loaded<br>";
} catch (Exception $e) {
    echo "fehler";
}
 
@$doc->loadHTML($html);
echo "feddisch";


habe dabei aber immer noch sporadisch das selbe fehlerbild und zar noch vor dem file_get_contents.

vg

ehw

4

Tuesday, November 23rd 2010, 6:19pm

dem file_get_contents musst du noch den timeout Parameter übergeben.
Hier mal ein komplettes Beispiel mit xpath

PHP Quellcode

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
<?php
 
$url = "http://www.easy-coding.de";
 
$start = microtime(true);
 
$context = stream_context_create(array(
	'http' => array('timeout' => 1)
));
$text = @file_get_contents($url, 0, $context)."";
 
echo "download finished after ".(microtime(true) - $start).", got ".strlen($text)." bytes<br/>"; flush();
 
$doc = null;
if($text) {
	libxml_clear_errors();
	libxml_use_internal_errors(true);
 
	$doc = new DOMDocument();
	if(@$doc->loadHTML($text)) {
		$xpath = new DOMXPath($doc);
		$query = '//meta';
		$entries = $xpath->query($query);
		foreach ($entries as $entry) {
			echo "Found {$entry->previousSibling->previousSibling->nodeValue}," ." by {$entry->previousSibling->nodeValue}\n";
		}
		echo "parsing success!<br/>";
	} else {
		echo "parsing failure!<br/>";
	}
}
echo "finished parsing after ".(microtime(true) - $start)."<br/>"; flush();


Quoted

download finished after 0.39660382270813, got 60394 bytes
Found , by Coder Forum für C++, Java, PHP, ... Found Coder Forum für C++, Java, PHP, ..., by Found , by Found , by Found , by Found , by Found , by Found , by parsing success!
finished parsing after 0.40362882614136

5

Wednesday, November 24th 2010, 6:48pm

Jau,

danke dir erstmal. bringt aber alles nichts. zwar konnte ich so schonmal einige fehler abfangen, aber der eigentliche bleibt weiterhin bestehen. Und zwar geht das Skript (ein Maitenences-script, nichts für die Öffentlichleit) einige paar links durch und schreibt sich ggf. Informationen in eine DB.

Ich weiß, vielleicht ist php nicht das richtige für so eine Aktion, allerdings bleibt z.Zt. keine andere Möglichkeit.

Zu sehen ist das Fehlerbild unter
http://personalpress.kanubox.de/ssnooper.php

Nach etwa 320 Sekunden Laufzeit bricht das Skript ab. Ohne fehlermeldung oder sonstige info.

Da der Fehler zwar immer nach min 300 Sekunden auftritt, dachte ich erst an einen Timeout. Da der Abbruch aber immer bei dem

file_get_contents($url, 0, $context)

abbricht, denke ich nicht mehr an einen Timeout, zumal

ignore_user_abort(true);
set_time_limit(0);

gesetzt sind.

Ob über den Browser oder über einen Cronjob aufgerufen, macht keinen Unterschied im Verhalten.


Ich habe folgende Deiner Vorschläge umgesetzt:

Und zwar

1. Setze ich ein flush() nach den echos, um ein evtl. Überlaufen des Buffers zu vermeiden. Auch dachte ich 2. daran, dass evtl. der Errorbuffer von libxml überläuft, weshalb ich dein

libxml_clear_errors();
libxml_use_internal_errors(true);

umsetze.

3. Habe ich das timeout für file_get_contents aktiviert, was wie oben gesagt, zwar einige Fehler behoben hat, diesen speziellen jedoch noch nicht.

4. ich habe auch das $doc = null umgesetzt, warum machst du das?

Hat es einen Sinn, dass du dem file_get_contents-String einen leeren String mit ."" hinzufügst?


Die ErrorLog, die ich vom Provider zur Verfügung gestellt bekommen, bleiben leer.


Ich hoffe, du hast noch eine Idee.


Grüße,
ehw

6

Wednesday, November 24th 2010, 8:36pm

$doc=null mache ich nur um die Variable in dem Scope zu definieren. Unwichtig!
Die Konkatenation mit einem leeren String mache ich, damit $text immer einen String enthält - auch wenn file_get_contents fase oder null zurückliefert. Unwichtig!
Entferne das @ vor dem file_get_contents bitte, damit Fehlermeldungen nicht mehr unterdrückt werden.

Das Script bricht immer mit file_get_contents ab? Hast du danach eine Ausgabe, die nie kommt? Hast du dafür eine Ausgabe um festzustellen, wie lange er für den Funktionsaufruf von file_get_contents benötigt.
Hast du mal file_get_contents ganz alleine mit dem entsprechenden Parameter, der auch zum Abbruch führt, aufgerufen?

7

Thursday, November 25th 2010, 1:35pm

Quoted

Entferne das @ vor dem file_get_contents bitte, damit Fehlermeldungen nicht mehr unterdrückt werden.


Ändert leider nichts.

Quoted

Hast du danach eine Ausgabe, die nie kommt? Hast du dafür eine Ausgabe um festzustellen, wie lange er für den Funktionsaufruf von file_get_contents benötigt.


Meinst du soetwas: Das log wird in dem fall nicht mehr ausgeführt.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
// Fetch the URL's contents
		$start = microtime(true);
		$this->log("++++getting file<br>");
		
		$contents = file_get_contents($url, 0, $context);
		
		$this->log("download finished after ".(microtime(true)-$start).", got ".strlen($contents)." bytes<br/>"); // echot und flusht

		$doc = null;
		// Check for empties
		if (!empty($contents))
		{


Quoted

Hast du mal file_get_contents ganz alleine mit dem entsprechenden Parameter, der auch zum Abbruch führt, aufgerufen?


alleine führt es nicht zwingend zu dem fehlerbild.


Was sagst du denn dazu, dass es erst immer so min 300 sek braucht und dann s meist bei 320 sek den geist aufgibt?

Grüße,

ehw

8

Friday, November 26th 2010, 6:33pm

Leider eine unbefriedigende Antwort: Es liegt nicht an der Syntax, es liegt an der Serverkonfiguration. Auf anderem Server funktioniert's.

Social bookmarks