PHP로 RSS / Atom 피드를 파싱하는 가장 좋은 방법 [닫기]


135

나는 현재 사용하고 있습니다 Magpie RSS를 있지만 RSS 또는 Atom 피드가 제대로 구성되지 않으면 때때로 넘어집니다. PHP로 RSS 및 Atom 피드를 구문 분석하는 다른 옵션이 있습니까?


1
이 요청에는 한 가지 문제가 있습니다. 대부분의 피드 리더는 PHP의 핵심 XML 리더를 사용하고 있으며 XML이 XML 표준에 따라 형식이 적절하지 않은 경우 XML 리더를 사용하지 않고 XML 리더를 사용하는 것을 살펴볼 수 있습니다. 그러나 텍스트 리더기는 서버의 부하를 크게 증가시킵니다. 나는 이것이 사람들에게 XML 피드 리더 사용의 단점을 인식하게 만들고있다.
Barkermn01

1
유효하지 않은 XML을 구문 분석하지 마십시오. 소스를 비난하십시오.
Lothar

답변:


28

다른 옵션은 다음과 같습니다.



189
나는 "답변"이 마음에 들지 않고 의견이없는 링크를 제공합니다. 당신이 그것을 구글하고 몇 가지 최고의 결과에 연결 된 것 같습니다. 특히 asker는 RSS 경험이 있고 더 나은 파서가 필요하기 때문에 .
duality_

3
누군가 약간의 조언이 필요한 경우 Last RSS가 위에 나열된 세 가지 중에서 가장 쉽습니다. "필수"할 파일은 1 개 뿐이며, 적절한 배열 출력으로 5 줄 이내에 RSS를 가져올 수 있습니다.
랩터


나는 그중 두 가지를 사용했으며 LastRss는 완벽하게 기능하는 도우미를 제공하기에 충분하지 않은 것으로 보이며 SimplePie는 너무 복잡합니다. 나는 다른 사람들을 시도하고 싶지만 그 링크에 대한 의견은 사람들이 이해하는 것이 더 좋습니다.
noob

169

필자는 항상 PHP내장 된 SimpleXML 함수를 사용 하여 XML 문서를 구문 분석했습니다. 직관적 인 구조를 가진 몇 가지 일반적인 파서 중 하나이므로 RSS 피드와 같은 특정 클래스에 대한 의미있는 클래스를 매우 쉽게 만들 수 있습니다. 또한 XML 경고 및 오류를 감지하고 HTML dydy (ceejayoz가 언급했듯이)를 통해 소스를 실행하여 정리하고 다시 시도 할 수 있습니다.

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
시작 태그가없는 종료 태그가 있습니다. ;)
Talvi Watia

130
글쎄, 하나가 있었지만 빈 줄이 없기 때문에 SO의 코드 포맷터가 먹었습니다. 관련 메모에서 대문자로 문장을 시작하지 않았습니다. ;)
브라이언 클라인

4
변경하시기 바랍니다 $feed_uri = $feed_or_url;$feed_uri = $file_or_url;보다 ... 다른,이 코드에 대한 감사합니다! 잘 작동합니다!
Tim

5
이 솔루션은 훌륭하지만 현재 피드의 RSS 피드 만 구문 분석합니다. 서로 다른 스키마로 인해 Atom 피드가 구문 분석되지 않습니다.
András Szepesházi

9
참고 eregi_replace현재 사용되지 않으며 대체되었습니다 preg_replace뿐만 아니라 eregipreg_match. 여기여기에 각각 설명서가 있습니다 .
ITS Alaska

45

4 줄로 rss를 배열로 가져옵니다.

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

보다 복잡한 솔루션

$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
방금 시도했습니다. 배열을 제공하지 않습니다
samayo

사용중인 RSS 피드를 제공 할 수 있습니까?
PJunior

2
궁금한 경우. 그가 텀블러 RSS 피드를 사용하고있는 것 같습니다. Anytumblrsite.com/rss는 동일한 출력을 제공합니다.
andrewk

3
: 4 개 라인을 사용, 훌륭한 일을했다 :) 그러나 나는 1 라인을 재 작성 $feed = file_get_contents('http://yourdomains.com/feed.rss'); 파일 + 내파보다 집중적 수 있습니다
Guidouil을

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

21

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

명확하고 간단한 해결책! 잘 작동합니다.
John T

13

피드의 형식이 잘못된 XML 인 경우 예외없이 거부해야합니다. 피드 제작자 에게 bozo 를 호출 할 수 있습니다.

그렇지 않으면 HTML이 끝나는 것을 망칠 수 있습니다.


3
+1, 제대로 구성되지 않은 XML을 해결하려고 시도해서는 안됩니다. 우리는 그들과 함께 나쁜 경험을 했어, 그것은 큰 고통 :(이었다 날 믿어
헬렌 닐리

35
그러나 프로그래머는 비즈니스 파트너를 선택할 필요가 없으며 주어진 파트너를 파싱해야합니다.
에드몬드 Meinfelder

2
범용 RSS / Atom 피드 리더를 구축하는 경우 어떻게해야합니까? 잘못된 형식의 xml 파일이 HTML을 "메시"할 수 있다면 Bozo는 누구입니까? ;) 당신이받는 것에 자유를 주라.
yPhil

6

HTML Tidy 라이브러리는 잘못된 XML 파일을 수정할 수 있습니다. 피드를 파서에 전달하기 전에 피드를 실행하면 도움이 될 수 있습니다.


2

SimplePie 를 사용 하여 Google 리더 피드를 구문 분석하고 제대로 작동하며 적절한 기능 세트가 있습니다.

물론, 잘 구성되지 않은 RSS / Atom 피드로 테스트하지 않았으므로 어떻게 대처하는지 모릅니다 .Google의 표준을 준수한다고 가정합니다. :)


1

개인적으로 저는 BNC Advanced Feed Parser를 사용합니다-사용하기 매우 쉬운 템플릿 시스템을 좋아합니다



-2

또 다른 위대한 무료로 파서 - http://bncscripts.com/free-php-rss-parser/ 그것은 매우 가벼운 (단 3킬로바이트)과 간단한 사용입니다!


gzinflate 및 base64_decode를 사용하여 "위대한"이라고 말할 수 없으며 일반적으로 보안을 위해 비활성화됩니다.
ask_io

Porpuses 마케팅에 대한 죽은 링크입니다.
Sagive SEO
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.