2009-08-17 4 views
2

Ich bin in der Lage, RSS mit PHP zu analysieren - Was ich suche, ist in der Lage, nur den aktualisierten Inhalt zu erhalten, und nichts zu tun, wenn es keine neue Aktualisierung der RSS gibt .Nur lesen, wenn die XML-Daten aktualisiert werden

Zum Beispiel habe ich diese RSS File, und wenn es keinen neuen Inhalt gibt, passiert nichts, aber wenn es einen neuen Inhalt gibt, möchte ich meinen Benutzern das neueste RSS-Update senden, und nicht erneut senden, was sie bereits haben. Ich analysiere und sende nur den Titel und den Link.

Ich benutze Cronjob, um jede Stunde nach Updates zu überprüfen. Meine Frage ist, wie kann ich feststellen, dass der Feed jetzt aktualisiert und nicht der gleiche wie der letzte ist? Hier ist die PHP file, die ich benutze, um den RSS zu lesen. Schreibe ich den letzten Inhalt in Datei und vergleiche sie oder gibt es eine andere Möglichkeit zu bestimmen, dass sich der Inhalt nun von dem letzten unterscheidet?

Update: Ich musste diesen Beitrag wieder auferstehen lassen, weil ich immer noch versuche, es zur Arbeit zu bringen. Obwohl ich ein paar Antworten akzeptiert habe, waren sie sehr schwer zu implementieren, zum Beispiel sah die Hashing-Option zunächst wie eine gute Idee aus, aber da Tausende von RSS geprüft würden, wäre es fast unmöglich, sie alle zu hacken.

Wieder hat jemand HTTP Cache vorgeschlagen - ich konnte keine einfache Demo finden, also bin ich praktisch festgefahren.

Jeder weitere Vorschlag würde sehr geschätzt werden.

+0

Nehmen Sie Informationen aus dem Feed und senden diese an Benutzer oder leiten Sie den Feed selbst weiter? Im letzteren Fall sollten die Benutzer entscheiden, wann sie den Feed erneut lesen möchten. Es wäre nicht sinnvoll, etwas anderes zu tun. – mcandre

+0

Ich nehme nur den Titel und den Link und sende sie an die Benutzer aus. Also, ich möchte den gleichen Titel nicht noch einmal senden. Was ich will ist, wenn es keinen neuen Inhalt gibt, nichts tun, aber wenn es ein neues Update gibt, parse es und sende das Update. –

Antwort

5

Sie Hashes für diesen nutzen könnten, auf zwei Arten:

  1. Aktualisierung zu erleichtern - Wenn ein Update anfordern, hash Sie das gesamte Futter und das Ergebnis mit dem Hash aus der letzten Zeit vergleichen - wenn sie Identisch, Sie wissen, dass sich der Feed nicht geändert hat und vor dem Parsen anhalten kann.
  2. Um Änderungen zu identifizieren - Beim Parsen, hash jedes Element und vergleichen Sie es mit den Hashes von früheren Läufen gespeichert. Wenn es einem entspricht, wissen Sie, dass Sie es schon einmal gesehen haben.

Wenn das betreffende Futtermittel guids für seine Produkte bietet könnten Sie diesen Prozess verfeinern guid <> Hash-Paare speichern. Dies würde den Vergleich beschleunigen, da Sie nur Elemente mit bekannten früheren Versionen vergleichen würden, anstatt mit allen vorherigen Elementen zu vergleichen.

Sie benötigen immer noch einen Ablauf-/Bereinigungsmechanismus, um die Anzahl gespeicherter Hashes in Grenzen zu halten. Da Sie jedoch nur relativ kurze Strings speichern (abhängig vom gewählten Hash-Algorithmus), sollten Sie in der Lage sein, einen ziemlich großen Wert zu halten Rückstand, bevor Leistungsprobleme auftreten.

+0

ist es eigentlich schneller, nicht Hash zu verwenden, sondern Pakete von Bytes zu vergleichen .... (zum Hashing lesen Sie die Gesamtheit der beiden Dateien, egal was, und aktiv den Hash-Algorithmus - das Lesen der ganzen Datei dauert sicherlich mehr als Lesen so viel wie nötig, und der Has-Algorithmus ist sicherlich mehr als nur Bytes zu vergleichen). – Letterman

+0

@Itay: Sicher, Hashing wird seinen Tribut fordern, aber es geht darum, die vorherigen Einträge zu speichern und mit denen zu vergleichen. Um den Byte-Vergleich durchzuführen, müssen Sie den gesamten Feed und die gesamten Feed-Elemente in der Datenbank speichern, was je nach Feed eine beträchtliche Menge an Daten sein kann. Das Schreiben und Lesen würde auch Zeit brauchen, aber vor allem die Anzahl der Einträge verringern, die man mit einer bestimmten Menge an Speicherplatz halten kann. –

+0

@Itay - Sie können den alten Inhalt einmal hashen, sodass Sie nur den neuen Inhalt hashen müssen. Wenn es viel Inhalt ist, speichern Sie den alten Inhalt erneut, Sie lesen nur den alten Hash. – orip

0

Ihre Kunden werden immer nach Ihren Feed-Daten fragen, so dass Sie nicht unbedingt steuern können, wenn sie fragen. Ich glaube nicht, dass die meisten Feed-Reader HTTP-Cache-Control-/Expires-Header befolgen, so dass Sie sich nicht darauf verlassen können, die HTTP-Spezifikation zu verwenden und das HTTP-Caching zu nutzen.

Ich denke, Ihre beste Wette ist, nur Ihre letzte Antwort zwischenzuspeichern und alle nachfolgenden Anfragen aus dem Cache zu senden - den Cache entsprechend aktualisieren, wenn Änderungen vorgenommen werden. Effektiv bedeutet dies, dass Ihre Kosten, um auf jeden Client und seine veralteten Daten zu antworten, ziemlich nahe bei 0 liegen, wenn Sie es einfach aus Memcache oder dem Dateisystem ziehen.

+0

Vielen Dank Cody für Ihren Kommentar - aber unser System soll Informationen an den Client senden, wenn es ein Update gibt. Infact, es ist ein SMS-System und sollte nur neueste Informationen senden und nicht die letzte Info –

+0

@Cody Supporting HTTP bedingte GET ist immer eine gute Idee. Haben Sie einen Hinweis darauf, dass Ihr Anspruch von Kunden nicht respektiert wird? –

1

Aufgrund der Vielfalt der RSS gibt es keine einfache Lösung für das Problem, das Sie aufgeworfen haben. Das Hauptproblem ist, wie man die Eindeutigkeit des rss Artikels bestimmt. Es kann guid sein, Zeit oder Inhalt selbst veröffentlichen, aber es ist vielleicht schwierig, das automatisch zu erkennen.

Sobald Sie die Eindeutigkeitskriterien kennen, können Sie alle "alten" Elemente beibehalten und sie mit den neuesten vergleichen, die Sie erhalten.

HTTP-Cache-Kontrolle und Expires-Header könnte als eine Optimierung für die Websites verwendet werden, die dies unterstützen, aber leider einige nicht.

+0

Danke Genndy, deine Antwort hat mir eine Idee gegeben. Ich werde jetzt die Titel in eine Datei schreiben und sie mit neuen Inhalten vergleichen, wenn der Cronjob ausgeführt wird. Wenn sie neu in der alten Liste erscheinen, werde ich das abschicken. Das bedeutet, dass ich die ganze Liste jede Woche löschen muss, um zu verhindern, dass sie auf dem Server außer Kontrolle gerät. Zumindest ist das die einzige Option, die ich jetzt habe. –

+0

Dies funktioniert nur, wenn Sie sicher sind, dass der Titel des Elements eindeutig ist. Im Allgemeinen können Sie Feeds leicht finden, wenn dies nicht der Fall ist. –

+0

GUID/UUID wäre ein besserer Vergleichskandidat, es soll global (probabilistisch) einzigartig sein. –

1

@ Henrik Lösung richtig ist, aber es könnte am einfachsten, Sie mit einem Beispiel der Hashing-Daten zu liefern:

// hash the three channel variables 
$hash = sha1($channel_title . $channel_link . $channel_desc); 

// here you should check the currently stored database hashed 
// value against current hash value to see if any channel variables 
// have recently changed 
if ($database_hash != $hash) { 
    // you need to update the channel data in your database 
    // including the new hash value 
} 

for ($i = 0; $i < 3; $i++) { 

    // hash the item values 
    $hash = $item_title . $item_link . $item_description 

    // here you should check the currently stored database hashed 
    // value against all item hash values to see if any item variables 
    // have recently changed 
    if ($database_hash != $hash) { 
     // you need to update the item data in your database 
     // including the new hash value 
    } 

} 

Auch, wenn Sie eine schnelle Überprüfung tun wollen, um zu bestimmen, ob irgendwelche Daten in dem Die XML-Datei hat sich verändert, Sie könnten das XML als String hashen. Sie sollten diesen Wert speichern und bei jedem Cronjob überprüfen, ob der Wert sich geändert hat (dies weist darauf hin, dass sich einige Daten in der XML-Datei geändert haben).

$overall_hash = sha1($xmlDoc->saveXML());