DOMDocument hat probleme mit website. Exception?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • DOMDocument hat probleme mit website. Exception?

    Hallo,

    Quellcode

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

    Quellcode

    1. // hide all the ugly DOMDocument warnings
    2. libxml_clear_errors();
    3. libxml_use_internal_errors(true);
  • 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:

    Quellcode

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


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

    vg

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

    Quellcode

    1. <?php
    2. $url = "http://www.easy-coding.de";
    3. $start = microtime(true);
    4. $context = stream_context_create(array(
    5. 'http' => array('timeout' => 1)
    6. ));
    7. $text = @file_get_contents($url, 0, $context)."";
    8. echo "download finished after ".(microtime(true) - $start).", got ".strlen($text)." bytes<br/>"; flush();
    9. $doc = null;
    10. if($text) {
    11. libxml_clear_errors();
    12. libxml_use_internal_errors(true);
    13. $doc = new DOMDocument();
    14. if(@$doc->loadHTML($text)) {
    15. $xpath = new DOMXPath($doc);
    16. $query = '//meta';
    17. $entries = $xpath->query($query);
    18. foreach ($entries as $entry) {
    19. echo "Found {$entry->previousSibling->previousSibling->nodeValue}," ." by {$entry->previousSibling->nodeValue}\n";
    20. }
    21. echo "parsing success!<br/>";
    22. } else {
    23. echo "parsing failure!<br/>";
    24. }
    25. }
    26. echo "finished parsing after ".(microtime(true) - $start)."<br/>"; flush();
    Alles anzeigen


    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
  • 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
    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
  • $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?
  • Entferne das @ vor dem file_get_contents bitte, damit Fehlermeldungen nicht mehr unterdrückt werden.


    Ändert leider nichts.

    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.

    Quellcode

    1. // Fetch the URL's contents
    2. $start = microtime(true);
    3. $this->log("++++getting file<br>");
    4. $contents = file_get_contents($url, 0, $context);
    5. $this->log("download finished after ".(microtime(true)-$start).", got ".strlen($contents)." bytes<br/>"); // echot und flusht
    6. $doc = null;
    7. // Check for empties
    8. if (!empty($contents))
    9. {
    Alles anzeigen


    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