Melhor maneira de analisar feeds RSS / Atom com PHP [fechado]


135

Atualmente, estou usando o Magpie RSS, mas às vezes cai quando o feed RSS ou Atom não está bem formado. Existem outras opções para analisar feeds RSS e Atom com PHP?


1
Há um problema com essa solicitação: a maioria dos leitores de feeds está usando os principais leitores XML do php e, se o XML não for bem formatado, conforme exigido pelos padrões XML, ele cairá sobre você. Leitor de texto, no entanto, a carga no servidor aumentará drasticamente. Eu sei que isto é respondida eu estou apenas fazendo as pessoas conscientes das desvantagens do uso de leitores de feeds XML
Barkermn01

1
Nunca tente analisar XML inválido. Culpe a fonte.
Lothar

Respostas:


28


189
Não gosto dessas "respostas", fornecendo links sem nenhum comentário. Parece que você pesquisou no Google e fez o link para alguns dos principais resultados. Especialmente porque o solicitante possui alguma experiência em RSS e precisa de um analisador melhor .
duality_

3
Caso alguém precise de um conselho, o Last RSS é o mais fácil entre os três listados acima. Apenas 1 arquivo para "exigir" e pode buscar o RSS dentro de 5 linhas, com uma saída de matriz decente.
Raptor


Eu usei dois deles e o LastRss parece não ser suficiente, fornecendo um auxiliar totalmente funcional e o SimplePie é um pouco complicado demais. Eu gostaria de tentar alguns outros, mas os comentários a essas bibliotecas são melhores para as pessoas entenderem, não apenas links.
Noob

169

Eu sempre usei as funções SimpleXML embutidas no PHP para analisar documentos XML. É um dos poucos analisadores genéricos por aí que possui uma estrutura intuitiva, o que torna extremamente fácil criar uma classe significativa para algo específico, como um feed RSS. Além disso, ele detectará avisos e erros XML e, ao encontrar algum, você pode simplesmente executar o código-fonte através de algo como HTML Tidy (como ceejayoz mencionado) para limpá-lo e tentar novamente.

Considere esta classe simples e muito grosseira usando o 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
você tem uma tag final sem tag inicial. ;)
Talvi Watia

130
Bem, eu tinha um, mas estava sendo consumido pelo formatador de código da SO, uma vez que não tinha uma linha vazia acima dele. Em uma nota relacionada, você não iniciou sua frase com uma letra maiúscula. ;)
Brian Cline

4
Altere $feed_uri = $feed_or_url;para $feed_uri = $file_or_url;... diferente disso, obrigado por este código! Isso funciona muito bem!
Tim

5
Observe que, embora essa solução seja ótima, ela analisará apenas os feeds RSS em sua forma atual. Os feeds Atom não serão analisados ​​devido ao esquema diferente.
András Szepesházi

9
Note que eregi_replaceagora é obsoleto e foi substituído preg_replace, bem como eregicom preg_match. As documentações podem ser encontradas aqui e aqui, respectivamente.
ITS Alaska

45

Com 4 linhas, importo um rss para uma matriz.

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

Para uma solução mais complexa

$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
Eu apenas tentei. Ele não fornece uma matriz
samayo

você pode me dar o feed RSS que você está usando?
precisa saber é o seguinte

2
Caso você esteja se perguntando. Parece que ele está usando um feed RSS do Tumblr. Anytumblrsite.com/rss daria a mesma saída.
andrewk

3
Usou as 4 linhas, fez um ótimo trabalho :) mas então eu reescrevi a 1ª linha: $feed = file_get_contents('http://yourdomains.com/feed.rss'); pode ser menos intensa do arquivo + implode
Guidouil

1
uma linha, $ feed = json_decode (json_encode (simplexml_load_file (' news.google.com/?output=rss' )), true);
asked_io

21

Gostaria de introduzir um script simples para analisar o 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++;
}

Solução clara e simples! Funciona bem.
John T

13

Se o feed não for XML bem formado, você deve rejeitá-lo, sem exceções. Você tem o direito de chamar o criador de feeds de bozo .

Caso contrário, você está preparando uma maneira de mexer com o resultado do HTML.


3
+1, você não deve tentar contornar qualquer XML que não esteja bem formado. Tivemos experiências ruins com eles, confie em mim, foi uma grande dor :(
Helen Neely

35
No entanto, os programadores não conseguem escolher parceiros de negócios e precisam analisar o que recebem.
Edmond Meinfelder

2
E se você estiver construindo um leitor universal de feeds RSS / Atom? Se qualquer arquivo xml mal formado pode "bagunçar" seu HTML, quem é o Bozo? ;) Seja liberal no que você recebe.
usar o seguinte comando

6

A biblioteca HTML Tidy pode corrigir alguns arquivos XML malformados. A execução de seus feeds antes de transmiti-los ao analisador pode ajudar.


2

Eu uso o SimplePie para analisar um feed do Google Reader e funciona muito bem e possui um conjunto de recursos decente.

Obviamente, eu não testei com feeds RSS / Atom não bem formados, então não sei como ele lida com eles, presumo que o Google seja razoavelmente compatível com os padrões! :)


1

Pessoalmente, uso o BNC Advanced Feed Parser - eu gosto do sistema de modelos que é muito fácil de usar



Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.