Markus Möller: fopen liefert 403 bei manchen Wikipedia-Seiten

Hallo zusammen,

ich habe ein seltsames Problem, das ich mir nicht erklären kann. Wenn ich bestimmte URLs (z.B. Wikipedia-Seiten) per fopen öffnen möchte, bekomme ich ein 403-Fehler. Bei anderen Wikipedia-Seiten geht es.

fopen("http://de.wikipedia.org/wiki/Knielingen", "r");
Ist OK!

fopen("http://de.wikipedia.org/wiki/Handschwinge", "r");
Liefert <b>Fatal error</b>: Uncaught exception 'Exception' with message 'fopen(http://de.wikipedia.org/wiki/Handschwinge) [&lt;a href='function.fopen'&gt;function.fopen&lt;/a&gt;]: failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden

Kann mir jemand sagen, woran das liegt?

Vielen Dank und Gruß
Markus

  1. Hello,

    ich habe ein seltsames Problem, das ich mir nicht erklären kann. Wenn ich bestimmte URLs (z.B. Wikipedia-Seiten) per fopen öffnen möchte, bekomme ich ein 403-Fehler. Bei anderen Wikipedia-Seiten geht es.

    Aus dem folgenden Kontext heraus vermute ich mal, dass Du PHP 6 im Einsatz hast?

    fopen("http://de.wikipedia.org/wiki/Knielingen", "r");
    Ist OK!

    fopen("http://de.wikipedia.org/wiki/Handschwinge", "r");
    Liefert <b>Fatal error</b>: Uncaught exception 'Exception' with message 'fopen(http://de.wikipedia.org/wiki/Handschwinge) [&lt;a href='function.fopen'&gt;function.fopen&lt;/a&gt;]: failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden

    Ich kann das weder "zu Fuß" noch mit PHP 5.3 nachvollziehen.
    Ich bekomme einen Status 200 und den Content der Seite.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
  2. Nebst deinem Problem: warum rufst du Wikipedia-Seiten per fopen() auf?

    Wenn du den Inhalt weiternutzen möchtest, gibt es dafür vorgesehene Schnittstellen - einfach das Frontend belasten sieht die Wikimedia-Foundation nicht gerne. Zwar sind die Inhalte unter einer freien Lizenz, das heißt aber noch lange nicht, dass unnötiges Lasterzeugen OK ist.

    1. Lieber suit,

      einfach das Frontend belasten sieht die Wikimedia-Foundation nicht gerne.

      sie hat es konkret untersagt.

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. OK, ich gebe es zu. Mein Posting könnte so aussehen, als ob ich Wikipedia-Inhalte auslesen möchte. Dann würde ich natürlich die entsprechende API nehmen.

        Mein Anwendungsfall sieht ein wenig anders aus:
        Bei Links (egal wohin) soll der Seitentitel (also das, was zwischen <title></title> steht) angezeigt werden. Mir geht es also nicht um die Inhalte, sondern nur um die ersten Zeichen des HTML-Quellcodes. Und den bekomme ich nicht über die API.

        1. OK, ich gebe es zu. Mein Posting könnte so aussehen, als ob ich Wikipedia-Inhalte auslesen möchte. Dann würde ich natürlich die entsprechende API nehmen.

          Mein Anwendungsfall sieht ein wenig anders aus:
          Bei Links (egal wohin) soll der Seitentitel (also das, was zwischen <title></title> steht) angezeigt werden. Mir geht es also nicht um die Inhalte, sondern nur um die ersten Zeichen des HTML-Quellcodes. Und den bekomme ich nicht über die API.

          Und dafür belastest du den Wikimedia-Server indem du bzw. beim 2. Weltkrieg ein 400 kB großes Dokument abholst, obwohl du nur den Seitentitel brauchst?

          1. Und dafür belastest du den Wikimedia-Server indem du bzw. beim 2. Weltkrieg ein 400 kB großes Dokument abholst, obwohl du nur den Seitentitel brauchst?

            Schlimmer noch. Ich belaste sogar DEINEN Server, wenn du die verlinkte Seite bist ;-)

            Nein im Ernst. Ich hole natürlich nicht den kompletten Artikel, sondern nur die ersten Zeichen.

  3. Zunächst einmal danke für die Hilfe.

    Ich habe mittlerweile die Ursache gefunden. Wenn ich einen User-Agent mitsende, funktioniert es. Na, darauf muss man erst mal kommen.

    1. Hi!

      Ich habe mittlerweile die Ursache gefunden. Wenn ich einen User-Agent mitsende, funktioniert es. Na, darauf muss man erst mal kommen.

      Beschreib mal die Schritte, wie du darauf gekommen bist, denn selbst wenn ein ähnlich gelagertes Problem nicht die gleiche Usache haben sollte, kann man ihm ja auf die gleiche Weise beizukommen versuchen.

      Lo!

      1. Drauf gekommen bin ich darauf, indem ich noch mal meinen Kopf angestrengt habe. Da ist mir eingefallen, dass ich bei Wikipedia schon einmal so ein ähnliches Problem hatte, als ich die API genutzt habe.

        Damals habe ich sehr lange gesucht und bin dann in einer Mailing-Liste für Wikipedia-API-Entwickler fündig geworden. Ich denke, dass ich auch ein sehr spezielles Problem, wenn man Requests an Wikipedia stellt. Keine Ahnung, ob es bei anderen Seite auch vorkommt.

        Die Lösung war ja dann letztlich einfach. Einfach vor dem Request diese Zeile einfügen:

        ini_set("user_agent", "Twick.it");

        1. Hi!

          Damals habe ich sehr lange gesucht und bin dann in einer Mailing-Liste für Wikipedia-API-Entwickler fündig geworden. Ich denke, dass ich auch ein sehr spezielles Problem, wenn man Requests an Wikipedia stellt. Keine Ahnung, ob es bei anderen Seite auch vorkommt.

          Kommt es. Es ist also kein Wikipedia-spezifisches Phänomen. Obwohl der User-Agent kein Pflicht-Header ist, wollen manche Webserver ihn unbedingt haben. Was drin steht ist dann wieder egal.

          Ohne "Fremdlösungen" kann man das selbst herausfinden, indem man sich die HTTP-Header eines funktionierenden Requests vornimmt - die bekommt man mit Browser-Tools wie der livehttpheaders-Extension für den Firefox - und einen Request mit diesen Headern stellt. Schrittweise entfernt man nun Header-Zeilen und schaut, ob es noch funktioniert. Irgendwann bleibt dann neben dem absoluten Minimum (GET und Host) noch der User-Agent übrig.

          Die Lösung war ja dann letztlich einfach. Einfach vor dem Request diese Zeile einfügen:
          ini_set("user_agent", "Twick.it");

          So setzt man das generell, was für kleine Scripte kein Problem ist. Man kann auch über den Stream-Kontext gehen. Jede Fuktion, bei der man wahlweise Dateinamen oder URLs angeben kann, hat einen optionalen $context-Parameter. Weiterführende Informationen sind üblicherweise von jeder dieser Handbuchseiten verlinkt.

          Lo!