Cách tốt nhất để phân tích các nguồn cấp RSS / Atom bằng PHP [đã đóng]


135

Tôi hiện đang sử dụng Magpie RSS nhưng đôi khi nó bị đổ khi nguồn cấp dữ liệu RSS hoặc Atom không được hình thành tốt. Có bất kỳ tùy chọn nào khác để phân tích nguồn cấp dữ liệu RSS và Atom bằng PHP không?


1
Có một vấn đề với yêu cầu này, hầu hết các trình đọc Nguồn cấp dữ liệu đang sử dụng các trình đọc XML lõi của php và nếu XML không được Định dạng tốt theo yêu cầu của các tiêu chuẩn XML, thì bạn sẽ có thể nhìn vào các trình đọc không sử dụng trình đọc XML và sử dụng Trình đọc văn bản tuy nhiên tải trên máy chủ sẽ tăng đáng kể. Tôi biết điều này đã được trả lời Tôi chỉ khiến mọi người nhận thức được những hạn chế của việc sử dụng trình đọc nguồn cấp dữ liệu XML
Barkermn01

1
Không bao giờ thử phân tích cú pháp XML không hợp lệ. Đổ lỗi cho nguồn.
Lothar

Câu trả lời:


28


189
Tôi không thích "câu trả lời" như vậy, đưa ra liên kết mà không có bất kỳ bình luận nào. Có vẻ như bạn google nó và liên kết đến một vài kết quả hàng đầu. Đặc biệt là vì người hỏi có một số kinh nghiệm RSS và cần một trình phân tích cú pháp tốt hơn .
duality_

3
Trong trường hợp ai đó cần một lời khuyên nhỏ, RSS cuối cùng là dễ nhất trong số ba danh sách trên. Chỉ có 1 tệp để "yêu cầu" và có thể tìm nạp RSS trong vòng 5 dòng, với đầu ra mảng khá.
Raptor


Tôi đã sử dụng hai trong số chúng và LastRss dường như không đủ tốt để cung cấp một trình trợ giúp đầy đủ chức năng và SimplePie hơi phức tạp. Tôi muốn thử một số người khác nhưng bình luận cho những lib đó là tốt hơn để mọi người hiểu, không chỉ liên kết.
noob

169

Tôi đã luôn sử dụng các hàm SimpleXML được tích hợp sẵn trong PHP để phân tích các tài liệu XML. Đây là một trong số ít các trình phân tích cú pháp chung có cấu trúc trực quan, giúp dễ dàng xây dựng một lớp có ý nghĩa cho một cái gì đó cụ thể như nguồn cấp dữ liệu RSS. Ngoài ra, nó sẽ phát hiện các cảnh báo và lỗi XML và khi tìm thấy bất kỳ thứ gì bạn có thể chỉ cần chạy nguồn thông qua một cái gì đó như HTML Tidy (như ceejayoz đã đề cập) để dọn sạch và thử lại.

Hãy xem xét lớp đơn giản, rất đơn giản này bằng cách sử dụng 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
bạn có một thẻ kết thúc không có thẻ bắt đầu. ;)
Talvi Watia

130
Chà, tôi đã có một cái, nhưng nó đã bị ăn bởi bộ định dạng mã của SO vì nó không có dòng nào ở trên nó. Trên một lưu ý liên quan, bạn đã không bắt đầu câu của bạn bằng một chữ in hoa. ;)
Brian Cline

4
Vui lòng đổi $feed_uri = $feed_or_url;thành $feed_uri = $file_or_url;... khác, cảm ơn bạn vì mã này! Nó hoạt động rất tốt!
Tim

5
Lưu ý rằng mặc dù giải pháp này rất tuyệt, nhưng nó sẽ chỉ phân tích các nguồn cấp RSS ở dạng hiện tại. Nguồn cấp dữ liệu nguyên tử sẽ không được phân tích cú pháp do lược đồ khác nhau của chúng.
András Szepesházi

9
Lưu ý rằng eregi_replacebây giờ không được chấp nhận và đã được thay thế bằng preg_replacecũng như eregivới preg_match. Tài liệu có thể được tìm thấy ở đâyở đây tương ứng.
ITS Alaska

45

Với 4 dòng, tôi nhập rss vào một mảng.

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

Đối với một giải pháp phức tạp hơn

$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
Tôi chỉ thử nó. Nó không đưa ra một mảng
samayo

bạn có thể cho tôi nguồn cấp dữ liệu rss mà bạn đang sử dụng không?
PJunior

2
Trong trường hợp bạn đang tự hỏi. Có vẻ như anh ấy đang sử dụng nguồn cấp dữ liệu tumblr rss. Anytumblrsite.com/rss sẽ cung cấp cho bạn cùng một đầu ra.
andrewk

3
Đã sử dụng 4 dòng, đã làm rất tốt :) nhưng sau đó tôi viết lại dòng thứ 1: $feed = file_get_contents('http://yourdomains.com/feed.rss'); có thể ít chuyên sâu hơn tệp + implode
Guidouil

1
một dòng, $ feed = json_decode (json_encode (simplexml_load_file (' news.google.com/?output=rss' )), đúng);
hỏi_io

21

Tôi muốn giới thiệu kịch bản đơn giản để phân tích 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++;
}

Giải pháp rõ ràng và đơn giản! Hoạt động độc đáo.
John T

13

Nếu nguồn cấp dữ liệu không phải là XML được định dạng tốt, bạn phải từ chối nó, không có ngoại lệ. Bạn có quyền gọi người tạo thức ăn là bozo .

Nếu không, bạn sẽ mở đường để làm rối tung HTML.


3
+1, bạn không nên cố gắng làm việc xung quanh bất kỳ XML nào không được định dạng tốt. Chúng tôi đã có những trải nghiệm tồi tệ với họ, tin tôi đi, đó là nỗi đau lớn :(
Helen Neely

35
Tuy nhiên, các lập trình viên không được chọn đối tác kinh doanh và phải phân tích những gì họ được đưa ra.
Edmond Meinfelder

2
Điều gì xảy ra nếu bạn đang xây dựng một trình đọc nguồn cấp dữ liệu RSS / Atom phổ quát? Nếu bất kỳ tệp xml không đúng định dạng nào có thể "làm rối" HTML của bạn, Bozo là ai? ;) Hãy tự do trong những gì bạn nhận được.
yPhil

6

Thư viện HTML Tidy có thể sửa một số tệp XML không đúng định dạng. Chạy các nguồn cấp dữ liệu của bạn thông qua đó trước khi chuyển chúng cho trình phân tích cú pháp có thể giúp ích.


2

Tôi sử dụng SimplePie để phân tích nguồn cấp dữ liệu Google Reader và nó hoạt động khá tốt và có một bộ tính năng hợp lý.

Tất nhiên, tôi đã không thử nghiệm nó với các nguồn cấp RSS / Atom không được định dạng tốt vì vậy tôi không biết nó đối phó với những nguồn đó như thế nào, tôi cho rằng Google tuân thủ khá chuẩn! :)


1

Cá nhân tôi sử dụng BNC Advanced Feed Parser- tôi thích hệ thống mẫu rất dễ sử dụng



-2

Một trình phân tích cú pháp miễn phí tuyệt vời khác - http://bncscripts.com/free-php-rss-parser/ Nó rất nhẹ (chỉ 3kb) và dễ sử dụng!


Không thể nói "tuyệt vời" của nó bằng cách sử dụng gzinflate và base64_decode, thường bị vô hiệu hóa để bảo mật.
hỏi_io

đó là một liên kết chết cho các porpuses tiếp thị.
SEO Sagive
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.