Il modo migliore per analizzare i feed RSS / Atom con PHP [chiuso]


135

Attualmente sto usando Magpie RSS ma a volte cade quando il feed RSS o Atom non è ben formato. Esistono altre opzioni per l'analisi dei feed RSS e Atom con PHP?


1
C'è un problema con questa richiesta che la maggior parte dei lettori di feed sta utilizzando i lettori XML di base di php e se l'XML non è ben formattato come richiesto dagli standard XML, cadrà su quelli che non usano i lettori XML e usano un Lettore di testo, tuttavia, il carico sul server aumenterà notevolmente. So che questa è una risposta, sto solo rendendo le persone consapevoli degli svantaggi dell'utilizzo dei lettori di feed XML
Barkermn01,

1
Non tentare mai di analizzare XML non valido. Dai la colpa alla fonte.
Lothar,

Risposte:


28

Le altre tue opzioni includono:



189
Non mi piacciono queste "risposte", fornendo link senza commenti. Sembra che tu lo google e link ad alcuni dei migliori risultati. Soprattutto perché il richiedente ha una certa esperienza RSS e ha bisogno di un parser migliore .
dualità_

3
Nel caso in cui qualcuno abbia bisogno di qualche consiglio, Last RSS è il più semplice tra i tre sopra elencati. Solo 1 file da "richiedere" e può recuperare l'RSS in 5 righe, con un output di array decente.
Raptor,


Ne ho usati due e LastRss non sembra abbastanza buono per fornire un supporto completamente funzionale e SimplePie è un po 'troppo complicato. Vorrei provare alcuni altri, ma i commenti a quelle librerie sono migliori per le persone a capire, non solo i collegamenti.
noob,

169

Ho sempre usato le funzioni SimpleXML integrate in PHP per analizzare documenti XML. È uno dei pochi parser generici là fuori che ha una struttura intuitiva, il che rende estremamente facile costruire una classe significativa per qualcosa di specifico come un feed RSS. Inoltre, rileverà avvisi ed errori XML e, trovandone uno, potresti semplicemente eseguire il sorgente attraverso qualcosa come HTML Tidy (come ceejayoz citato) per ripulirlo e riprovare.

Considera questa classe molto approssimativa e semplice usando SimpleXML:

class BlogPost
{
    var $date;
    var $ts;
    var $link;

    var $title;
    var $text;
}

class BlogFeed
{
    var $posts = array();

    function __construct($file_or_url)
    {
        $file_or_url = $this->resolveFile($file_or_url);
        if (!($x = simplexml_load_file($file_or_url)))
            return;

        foreach ($x->channel->item as $item)
        {
            $post = new BlogPost();
            $post->date  = (string) $item->pubDate;
            $post->ts    = strtotime($item->pubDate);
            $post->link  = (string) $item->link;
            $post->title = (string) $item->title;
            $post->text  = (string) $item->description;

            // Create summary as a shortened body and remove images, 
            // extraneous line breaks, etc.
            $post->summary = $this->summarizeText($post->text);

            $this->posts[] = $post;
        }
    }

    private function resolveFile($file_or_url) {
        if (!preg_match('|^https?:|', $file_or_url))
            $feed_uri = $_SERVER['DOCUMENT_ROOT'] .'/shared/xml/'. $file_or_url;
        else
            $feed_uri = $file_or_url;

        return $feed_uri;
    }

    private function summarizeText($summary) {
        $summary = strip_tags($summary);

        // Truncate summary line to 100 characters
        $max_len = 100;
        if (strlen($summary) > $max_len)
            $summary = substr($summary, 0, $max_len) . '...';

        return $summary;
    }
}

2
hai un tag di fine senza tag di inizio. ;)
Talvi Watia,

130
Bene, ne avevo uno, ma era stato mangiato dal formattatore del codice SO poiché non aveva una linea vuota sopra di esso. In una nota correlata, non hai iniziato la frase con una lettera maiuscola. ;)
Brian Cline,

4
Per favore, cambia $feed_uri = $feed_or_url;in $feed_uri = $file_or_url;... a parte questo, grazie per questo codice! Funziona benissimo!
Tim

5
Nota che, sebbene questa soluzione sia eccezionale, analizzerà solo i feed RSS nella sua forma attuale. I feed Atom non verranno analizzati a causa del loro schema diverso.
András Szepesházi,

9
Si noti che eregi_replaceora è obsoleto ed è stato sostituito con preg_replacee eregicon preg_match. La documentazione può essere trovata qui e qui rispettivamente.
ITS Alaska

45

Con 4 righe, importare un rss in un array.

$feed = implode(file('http://yourdomains.com/feed.rss'));
$xml = simplexml_load_string($feed);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

Per una soluzione più complessa

$feed = new DOMDocument();
 $feed->load('file.rss');
 $json = array();
 $json['title'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
 $json['description'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
 $json['link'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('link')->item(0)->firstChild->nodeValue;
 $items = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('item');

 $json['item'] = array();
 $i = 0;

 foreach($items as $key => $item) {
 $title = $item->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
 $description = $item->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
 $pubDate = $item->getElementsByTagName('pubDate')->item(0)->firstChild->nodeValue;
 $guid = $item->getElementsByTagName('guid')->item(0)->firstChild->nodeValue;

 $json['item'][$key]['title'] = $title;
 $json['item'][$key]['description'] = $description;
 $json['item'][$key]['pubdate'] = $pubDate;
 $json['item'][$key]['guid'] = $guid; 
 }

echo json_encode($json);

2
L'ho appena provato. Non dà un array
samayo

puoi darmi il feed rss che stai usando?
PJunior il

2
Nel caso ti stia chiedendo. Sembra che stia usando un feed tumblr rss. Anytumblrsite.com/rss ti darebbe lo stesso risultato.
Andrewk,

3
Ho usato le 4 righe, fatto un ottimo lavoro :) ma poi ho riscritto la prima riga: $feed = file_get_contents('http://yourdomains.com/feed.rss'); potrebbe essere meno intensivo di file + implode
Guidouil

1
una riga, $ feed = json_decode (json_encode (simplexml_load_file (' news.google.com/?output=rss' )), true);
ask_io

21

Vorrei introdurre un semplice script per analizzare RSS:

$i = 0; // counter
$url = "http://www.banki.ru/xml/news.rss"; // url to parse
$rss = simplexml_load_file($url); // XML parser

// RSS items loop

print '<h2><img style="vertical-align: middle;" src="'.$rss->channel->image->url.'" /> '.$rss->channel->title.'</h2>'; // channel title + img with src

foreach($rss->channel->item as $item) {
if ($i < 10) { // parse only 10 items
    print '<a href="'.$item->link.'">'.$item->title.'</a><br />';
}

$i++;
}

Soluzione chiara e semplice! Funziona bene.
John T,

13

Se il feed non è un XML ben formato, dovresti rifiutarlo, senza eccezioni. Hai il diritto di chiamare il creatore di feed un bozo .

Altrimenti stai aprendo la strada al caos in cui è finito HTML.


3
+1, non dovresti cercare di aggirare qualsiasi XML che non sia ben formato. Abbiamo avuto brutte esperienze con loro, credetemi, è stato un grande dolore :(
Helen Neely,

35
Tuttavia, i programmatori non possono scegliere i partner commerciali e devono analizzare ciò che viene loro dato.
Edmond Meinfelder,

2
Cosa succede se stai costruendo un lettore di feed RSS / Atom universale? Se un file XML mal formato può "pasticciare" il tuo HTML, chi è il Bozo? ;) Sii liberale in ciò che ricevi.
yPhil

6

La libreria HTML Tidy è in grado di riparare alcuni file XML non validi. Può essere utile eseguire i feed prima di passarli al parser.


2

Uso SimplePie per analizzare un feed di Google Reader e funziona abbastanza bene e ha un set di funzionalità decente.

Certo, non l'ho testato con feed RSS / Atom non ben formati, quindi non so come gestirli, suppongo che quelli di Google siano abbastanza conformi agli standard! :)


1

Personalmente uso BNC Advanced Feed Parser, mi piace il sistema di template che è molto facile da usare



Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.