PHP file_get_contents funktioniert erst nach 10 Minuten

M

Mr. Snoot

Gast
Hio,

ich habe ein Script, um den Preis bei Geizhals zu einem Artikel auszulesen.

Der GH-Quelltext mit dem Preis sieht so aus:
HTML:
<nobr>xx,xx</nobr>

Mein Script zum Auslesen so:
PHP:
  $url = "http://geizhals.at/deutschland/a123456.html";
  $fp = file_get_contents($url);
  if (ereg("nobr\>([0-9]+,..)\<", $fp, $regs))
  {
    $preis = $regs[1];
  }

Das ganze funktioniert an sich, aber nicht beim ersten Mal. D.h. wenn ich das Script aufrufe, bekomme ich beim ersten Mal (oder wenn ich es direkt danach noch einmal probiere) irgendwann ein timeout-Error.

Wenn ich dann aber ~10 Minuten warte, läuft das Script problemlos durch.

Woran kann das liegen? Ich hab das jetzt über die letzten 2-3 Wochen jedesmal beim Ausführen des Scriptes erlebt.
 
Ich vermute stark, dass es nicht an PHP liegt. Die Wahrscheinlichkeit eines Fehlers in einer etablierten PHP-Funktion ist mittlerweile äußerst gering.

Zur genaueren Bestimmungen folgendes sicherstellen:
- Verhalten bei anderen Remote-URLs/-Domains
- Verhalten bei lokalen Requests
 
Zuletzt bearbeitet:
Ist das nur mit Geizhals oder auch wenn du andere Seiten aufrufst? Evtl. ein DNS-Problem?
Ansonsten könntest du auch mal alternative Methoden versuchen wie z.B. über die Curl-Erweiterung von PHP oder fsockopen.
 
Ich habs jetzt mal bei ein paar anderen Seiten probiert, und überall funktioniert es.


Ich hab auch einige Cronjobs mit diesem Script die einmal am Tag laufen, und da hab ich bisher keine Aussetzer entdeckt. In der Arbeit hab ich dasselbe Problem.

Ich hab das Script jetzt einmal gestartet, bevor ich diesen Beitrag hier schrieb, und es kam ein Timeout. Und einmal nach dem Abschicken, und es lief. So als ob die Seite zunächst einmal abgerufen werden müsste; aber es geht ja direkt beim zweiten Mal auch nicht, sondern erst, wenn man wartet :confused_alt:
 
Dann empfehle ich eine nähere Untersuchung mit Wireshark.
Interessant ist, welche Protokolle (DNS, TCP, HTTP) wie und vor allem wann genutzt werden. Somit sollte sich das Problem näher eingrenzen lassen.
 
Aber das Script läuft doch auf einem Webserver; da hilft es nichts, meinen Netzwerkverkehr zu protokollieren!?
 
Richtig ist: die Ausführung des Packetcaptures ist natürlich auf dem Problemsystem erforderlich.
Wenn Du Shellzugriff auf den Server hast, dann bietet sich tcpdump an. Falls nicht, erschwert dies die Diagnose.

Man kann nun annehmen, dass Seiten wie Geizhals.at Mechanismen verwenden, um das maschinelle Auslesen zu verhindern oder zu erschweren. Das heißt: man KÖNNTE die Erkennung eines Nicht-Browsers durch den User-Agent realisieren oder via eines fehlenden Referrers.
 
Aber das erklärt doch nicht, warum es nur beim ersten Mal nicht geht aber 10 Minuten später oder via Cronjob anstandslos.
 
Bitte sei doch nicht so begriffsstutzig - weder klären noch lösen Packetcaptures ein Problem. Es sind Diagnosemittel - sie geben Anhaltspunkte, die bei der weiteren Ursachensuche und -findung ausschlaggebend sein können.

Ich geb Dir mal ein Szenario:

- Geizhals-Webserver hat Mechanismen zur Abwehr automatischen Auslesens (Cookie/User-Agent-basiert vielleicht?)
- Deine Requests (DNS, TCP-Verbindungsaufbau, HTTP-Anfrage) an den Webserver gehen problemlos raus (sowas sieht man dann im Packetdump)
- Geizhals-Webserver beantwortet Deine Anfrage nicht oder nur mit hoher Verzögerung (um das Auslesen durch Bots zu erschweren)
- Timeout des PHP-Scripts (weil PHP noch auf Response des Zielservers wartet)

Du schlussfolgerst, es liegt an Deinem Server - insbesondere an PHP (obwohl dem vorerst nicht so ist).

Wireshark gibt Dir Gewissheit, wo das Problem wahrscheinlicher zu finden ist (Zielserver?) und wo nicht (eigener Webserver?).
 
Probiers doch mal mit curl, da kannst Du auch einen User Agent definieren und Dich als echten Browser ausgeben.
 
Du kannst auch mit header() in PHP den das Header-Feld "User-Agent" setzen - dafür muss man nun wirklich nicht gleich loslaufen und cURL nutzen.
 
Äh, wenn er header() nutzt kann er aber nur an seinen Aufrufer einen Header senden, er soll aber in dem Request an geizhals einen User-Agent-Header hinzufügen, das sind 2 paar Schuhe.
 
Da gebe ich Dir Recht - in diesem Szenario header() zu benutzen ist natürlich sinnlos. Meine Antwort war diesbezüglich vollkommen falsch und damit unqualifiziert.

Worauf ich hinauswollte: eine HTTP-Anfrage zu formulieren ist in PHP auch ohne Zusatzbibliothek möglich.
 
Die Header bei file_get_contents lassen sich mit der stream_context_create-Funktion überschreiben.

Ich würde erstmal aber versuchen inwiefern die DNS-Auflösung klappt. Dafür kann man die PHP-Funktion gethostbyname nutzen.
 
Also ich habs jetzt paar mal mit Wireshark probiert, aber seit dem ist das Problem nicht mehr aufgetreten. Vermutlich will sich die Verbindung zu GH nicht in die Karten schauen lassen. :rolleyes:

Werd mich wieder melden, wenn es mal geklappt hat mit dem nicht-klappen ;)
 
Na das ist doch nun schon äußerst ominös!

Wenn es mit aktiviertem Wireshark klappt, bezweifle ich nun noch mehr, dass es an der PHP-Implementierung liegt und würde PHP damit schon einmal mit hoher Wahrscheinlichkeit ausschließen.
 
So, hab's jetzt hinbekommen, schlau werd ich daraus aber nicht:

Fehler mit Timeout:
fehler.png

Alles OK:
ok.png


Von Geizhals seh ich da nirgends eine IP; die 80... ist vom Server auf dem das Script liegt, die 72... ist von Steam. Geizhals hat 213.229.61.37.

Im unteren Fenster scheint's zwar einen Fehler zu geben, aber der kommt immer.


Was sagt mir das nun?
 
Zuletzt bearbeitet:
Mr. Snoot schrieb:
Von Geizhals seh ich da nirgends eine IP; die 80... ist vom Server auf dem das Script liegt, die 72... ist von Steam. Geizhals hat 213.229.61.37.

wenn der Server die Anfrage an Geizhals stellt, müssen natürliche auch die Pakete auf dem Server analysiert werden und nicht auf deinem PC :rolleyes:
 
Noch ne Idee, was ich da tun könnte? Mittlerweile funktioniert es gar nicht mehr, file_get_contents liefert nach 60s einen timeout.

Laut HostEurope ist alles ok; ich selbst kann auf dem Server nichts installieren. Ist nur normaler Webspace.

Ich hab dort auch noch weiteren Webspace (andere Seite von mir), von der ich das Script ohne Probleme ausführen kann. Aber das hilft mir nicht weiter.


Von HostEurope hieß es nur, ich soll das Script prüfen oder ggf. den Autor fragen :freak: Was soll man bei
PHP:
<?php echo file_get_contents("http://..."); ?>
groß falsch machen, zumal es ja auf dem anderen Webspace klappt.
 
eventuell mal den HTTP-Aufruf manuell mit fsockopen implementieren?
Dann könnte man feststellen ob es generell an der TCP-Verbindung liegt oder dem HTTP-Teil
 
Zurück
Oben