RSS / Atom yayınlarını PHP ile ayrıştırmanın en iyi yolu [kapalı]


135

Şu anda Magpie RSS kullanıyorum, ancak RSS veya Atom beslemesi iyi biçimlendirilmediğinde bazen düşer. RSS ve Atom yayınlarını PHP ile ayrıştırmak için başka seçenekler var mı?


1
Çoğu Feed okuyucusunun php'nin temel XML okuyucularını kullandığı bu sorunla ilgili bir sorun vardır ve XML, XML standartlarının gerektirdiği şekilde İyi Biçimlendirilmemişse, XML okuyucuları kullanmayanlara bakabilir ve bir Ancak Text Reader sunucudaki yükü önemli ölçüde artıracaktır. Bunun cevaplandığını biliyorum, sadece insanları XML feed okuyucularını kullanmanın dezavantajlarından haberdar ediyorum
Barkermn01

1
Asla geçersiz XML'i ayrıştırmaya çalışmayın. Kaynağı suçla.
Lothar

Yanıtlar:


28

Diğer seçenekleriniz şunları içerir:



189
Bu tür "cevapları" sevmiyorum, yorum yapmadan bağlantılar veriyorum. Görünüşe göre google ve birkaç en iyi sonuca bağlantı verdiniz. Özellikle asker biraz RSS deneyimine sahip olduğundan ve daha iyi bir ayrıştırıcıya ihtiyaç duyduğundan .
duality_

3
Birinin biraz tavsiyeye ihtiyacı varsa, Son RSS yukarıda listelenen üç arasında en kolay olanıdır. Sadece 1 dosya "gerektirir" ve iyi bir dizi çıkışı ile 5 satır içinde RSS getirebilir.
Raptor


Ben ikisini kullandım ve LastRss tamamen işlevsel bir yardımcı sağlayan yeterince iyi görünmüyor ve SimplePie biraz fazla karmaşık. Ben başkalarını denemek istiyorum ama bu libs için yorumlar sadece bağlantıları değil, insanlar anlamak için daha iyidir.
noob

169

Ben her zaman XML belgelerini ayrıştırmak için PHP yerleşik SimpleXML fonksiyonları kullandım . Bu, sezgisel bir yapıya sahip birkaç jenerik ayrıştırıcıdan biridir, bu da RSS beslemesi gibi belirli bir şey için anlamlı bir sınıf oluşturmayı son derece kolaylaştırır. Ayrıca, XML uyarılarını ve hatalarını algılar ve herhangi bir bulduktan sonra kaynağı temizlemek ve tekrar denemek için HTML Tidy (ceejayoz'un belirttiği gibi) gibi bir şeyle çalıştırabilirsiniz.

SimpleXML kullanarak bu çok kaba ve basit sınıfı düşünün:

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
başlangıç ​​etiketi olmayan bir bitiş etiketiniz var. ;)
Talvi Watia

130
Bir tane vardı, ama üstünde boş bir satır olmadığı için SO'nun kod biçimlendiricisi tarafından yeniliyordu. İlgili bir notta, cümlenize büyük harfle başlamadınız. ;)
Brian Cline

4
Lütfen değiştirin $feed_uri = $feed_or_url;için $feed_uri = $file_or_url;bundan daha başka ... bu kod için teşekkür ederim! Harika çalışıyor!
Tim

5
Bu çözüm harika olsa da, RSS akışlarını yalnızca geçerli formunda ayrıştıracağını unutmayın. Atom özet akışları, farklı şemaları nedeniyle ayrıştırılmaz.
András Szepesházi

9
Not eregi_replaceartık desteklenmiyor, ile değiştirilmiştir preg_replaceyanı sıra eregiile preg_match. Dokümanları sırasıyla burada ve burada bulabilirsiniz .
ITS Alaska

45

4 satır ile bir diziye bir rss almak.

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

Daha karmaşık bir çözüm için

$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
Sadece denedim. Bir dizi vermez
samayo

u u kullandığınız rss yem verebilir?
PJunior

2
Merak ediyorsanız. Görünüşe göre bir tumblr rss özet akışı kullanıyor. Anytumblrsite.com/rss size aynı çıktıyı verir.
andrewk

3
4 satır kullanılır, harika bir iş yaptı :) ama sonra 1 satır yeniden yazdı: $feed = file_get_contents('http://yourdomains.com/feed.rss'); dosya + implode daha az yoğun olabilir
Guidouil

1
bir satır, $ feed = json_decode (json_encode (simplexml_load_file (' news.google.com/?output=rss' )), true);
asked_io

21

RSS ayrıştırmak için basit komut dosyası tanıtmak istiyorum:

$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++;
}

Açık ve basit bir çözüm! Güzel çalışıyor.
John T

13

Feed iyi biçimlendirilmiş XML değilse, bunu reddetmeniz gerekir, istisna yok. Feed yaratıcısına bozo deme hakkına sahipsiniz .

Aksi takdirde, HTML'nin karıştığı karışıklığı kaldırırsınız.


3
+1, iyi biçimlendirilmemiş herhangi bir XML üzerinde çalışmaya çalışmamalısınız. Onlarla kötü deneyimler yaşadık, güven bana, büyük
acıydı

35
Ancak, programcılar iş ortaklarını seçemez ve verilenleri ayrıştırmak zorunda kalmazlar.
Edmond Meinfelder

2
Evrensel bir RSS / Atom özet akışı okuyucusu oluşturuyorsanız ne olacak? Herhangi bir hatalı biçimlendirilmiş xml dosyası HTML'nizi "bozabilir" ise, Bozo kimdir? ;) Aldığınız şeyde liberal olun.
yPhil

6

HTML Düzenli kitaplığı, hatalı biçimlendirilmiş bazı XML dosyalarını düzeltebilir. Özet akışlarınızı ayrıştırıcıya aktarmadan önce yayınlamanız yardımcı olabilir.


2

Kullandığım SimplePieBir Google Reader özet akışını ayrıştırmak ve oldukça iyi çalışıyor ve iyi bir özellik kümesi var.

Tabii ki, iyi biçimlendirilmemiş RSS / Atom yayınları ile test etmedim, bu yüzden bunlarla nasıl başa çıkacağını bilmiyorum, Google'ın oldukça standartlara uygun olduğunu varsayıyorum! :)


1

Şahsen BNC Gelişmiş Besleme Ayrıştırıcısını kullanıyorum, kullanımı çok kolay olan şablon sistemini seviyorum



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.