Публикувано в (Уеб програмиране) от на 13 август 2009 в 16:58

Ще ти покажа малко PHP код, с който много лесно можеш да извлечеш новини от някой сайт за новини, който има RSS хранилка (RSS feed). Много хора дори не предполагат, колко елементарно се прави това. Дори да имаш само бегли познания за PHP, можеш просто да копираш този код (даден с тъмнозелено долу) в някой от php файловете на твоя сайт (например index.php) и той ще покаже новини от друг сайт в твоя сайт. Изискването е новините да са в RSS 2.0 формат.

В този пример новините представляват статии от statii.net. Още като влезеш в началната страница на сайта вдясно виждаш малки оранжеви иконки и връзката „всички статии“. Това е RSS хранилка, която захранва с най-новите статии от сайта. Под всички се разбира последните 10 статии, като най-новите са най-отгоре. Това ограничение може да е различно и се задава от собственика на сайта, който осигурява RSS. Ако застанеш с мишката над линка ще видиш в статус бара на браузъра адреса http://statii.net/feed. Ако посетиш тази връзка ще видиш последните статии, като кода на страницата, която гледаш е в XML формат. Ако браузъра е нов той сам ще форматира съдържанието и ще го покаже удобно за четене, но ако погледнеш кода на страницата ще видиш XML. Кода на страницата с Internet Explorer се вижда с натискане на десен бутон на мишката в страницата и после от падащото меню се избира View Source, при Firefox опцията е View Page Source. В този пример XML-а ще изглежда така:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Директория за статии</title>
	<atom:link href="http://statii.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://statii.net</link>
	<description>Напиши нова статия. Вземи статии за твоя сайт.</description>
	<lastBuildDate>Sat, 08 Aug 2009 09:00:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
	<item>
	  <title>Градинска ножица Ciso на Bosch</title>
	  <link>http://statii.net/2009/%d0%b3%d1%80%d0%b0%d0%b4%d0%b8%d0%bd%d1%81%d0%ba%d0%b0
-%d0%bd%d0%be%d0%b6%d0%b8%d1%86%d0%b0-ciso-%d0%bd%d0%b0-bosch/</link>
	  <comments>http://statii.net/2009/%d0%b3%d1%80%d0%b0%d0%b4%d0%b8%d0%bd%d1%81%d0%ba
%d0%b0-%d0%bd%d0%be%d0%b6%d0%b8%d1%86%d0%b0-ciso-%d0%bd%d0%b0-bosch/#comments</comments>
	  <pubDate>Sat, 08 Aug 2009 08:59:49 +0000</pubDate>
	  <dc:creator>toto</dc:creator>
	  <category><![CDATA[Градинарство]]></category>
	  <category><![CDATA[Bosch]]></category>
	  <category><![CDATA[бамбук]]></category>
	  <category><![CDATA[градина]]></category>
	  <category><![CDATA[ножица]]></category>
	  <category><![CDATA[Цветя]]></category>

	  <guid isPermaLink="false">http://statii.net/?p=326</guid>
	  <description><![CDATA[Първата в света акумулаторна градинска ножица с вграден
литиево-йонен акумулатор.
Хубавата градина изисква много грижи. Подрязването на клони, които следва да се почистят с
градинска ножица е уморително, а понякога може да предизвика и болки в ставите и мускулите на
ръката. Тези проблеми се разрешават с помощта на Ciso &#8211; първата в света акумулаторна
градинска ножица [...]]]></description>
	  <wfw:commentRss>http://statii.net/2009/%d0%b3%d1%80%d0%b0%d0%b4%d0%b8%d0%bd%d1%81
%d0%ba%d0%b0-%d0%bd%d0%be%d0%b6%d0%b8%d1%86%d0%b0-ciso-%d0%bd%d0%b0-bosch/feed/</wfw:commentRss>
  	  <slash:comments>0</slash:comments>
	</item>

... още елементи item ...
	</channel>
</rss>

От реда rss version=“2.0″ се вижда, че този XML е във формат RSS версия 2.0.

PHP код за извличане и на RSS новини

<?php

        # ganbox.com: парсва RSS новини	в масив arrFeeds
        $url='http://statii.net/feed/'; # адрес на RSS хранилката
        $doc = new DOMDocument();
	$doc->load($url);
	$arrFeeds = array();
	foreach ($doc->getElementsByTagName('item') as $node) {
		$itemRSS = array (
			'title'=>$node->getElementsByTagName('title')->item(0)->nodeValue,
			'desc' =>$node->getElementsByTagName('description')->item(0)->nodeValue,
			'link' =>$node->getElementsByTagName('link')->item(0)->nodeValue,
			'date' =>$node->getElementsByTagName('pubDate')->item(0)->nodeValue,
			);
		array_push($arrFeeds, $itemRSS);
	}

        # ganbox.com: отпечатване на feedLimit на брой новини от масива arrFeeds
        $feedLimit=0; # ако feedLimit=0 се показват всичките
        $feedCount=0;
        foreach($arrFeeds as $oneItem){
            # ако твоя сайт има кодиране cp1251, тогава махни коментара # на следващия ред
            # foreach($oneItem as $key=>$value){$oneItem[$key]=iconv('utf-8','cp1251',$value);}
            $feedCount++;
            print '<div class="feedItem"><h3 class="feedTitle"><a href="'.$oneItem['link'].'"
                class="feedLink">'.$oneItem['title'].'</a></h3>';
            print '<p class="feedDesc">'.$oneItem['desc'].'</p>';
            print '</div>';
            if($feedLimit>0 && $feedCount>=$feedLimit) break;
        }
?>

Това е всичко. Сложил съм класовете feedItem, feedTitle, feedLink и feedDesc за по-лесно управление на изгледа от CSS файл. Ако искаш сложи всичко в един div контейнер.

Масива arrFeeds съдържа и поле date, в което е датата на публикуване. Ако искаш може да показваш и нея с още един ред: print ‘<p class=“feedDate“>’.$oneItem['desc'].’</p>’;  поставен след реда съдържащ feedDesc.

Важно е да се отбележи, че използвания метод зарежда всички новини в паметта на сървъра, където е твоя сайт. Ако новините са много или текста им е прекалено дълъг това ще доведе до счупване на страницата на твоя сайт или в най-добрия случай на забавяне на зареждането. Трябва да се увериш, че хранилката, която ползваш показва само част от текста, както е в statii.net или показва само най-новите X на брой новини. Друг вариант е да се абонираш само за тема, която те интересува. Продължавай да четеш :)

Избор на категория със статии

Ако не искаш да показваш всички статии, а само статии от определена категория първо влез в категорията. Например в  „Практически съвети“  тогава отдясно се показва трета връзка „тази категория“ и може да видиш, че линка има адрес http://statii.net/tema/дом-и-семейство/практически-съвети/feed/  Сложи този адрес в променливата $url в началото на кода и ще се извличат само статии от тази категория. Нещо повече – може да извличаш само статии, които съдържат определена дума например seo. За да направиш това първо извърши търсене в сайта statii.net от търсачката най-горе по думата seo. Тогава третата връзка в дясно се променя на „това търсене“ с адрес на линка http://statii.net/search/seo/feed/ сложи този адрес в променливата $url и ще получаваш само статии съдържащи думата SEO.

Ползите за твоя сайт

Получаваш автоматично и безплатно ново съдържание и посетителите на твоя сайт, започват да го посещават по-често. Търсачките забелязват, че твоя сайт е динамичен и го оценяват по-високо. Внимание! Задължително оставяй реална връзка към източника на новината (така както е в примера), защото със сигурност новината вече е индексирана от търсачките и ако няма връзка това ще се отчете като кражба на съдържание и сайта ти ще започне да се класира по-лошо.

Трябва да внимаваш съдържанието с новини което включваш на всяка страница да не бъде прекалено много. То трябва да бъде не повече от 20% от общото съдържание на страницата. В противен случай ще получиш негативен SEO ефект, защото чуждото съдържание ще размие тематиката на твоя сайт. Затова в горния пример може да ползваш feedLimit=3 в страниците с по-малко текст.

Този PHP код е тестван и все пак ако има проблем пиши коментари по статията.

VN:F [1.9.16_1159]
Рейтинг: 10.0/10 (2 гласа)
PHP парсване на XML новини за твоя сайт, 10.0 out of 10 based on 2 ratings
Брой разглеждания на тази статия: 4941
(след дата 20 декември 2009)

Сподели статията в Бутончета на сайтове, в които можете да споделите линк към тази страница.
  • CenBg.com
  • BgrStar.com
  • Novoto.net
  • Bghot.net
  • Trohi.com
  • Zdravei.net
  • Web-bg.com
  • Plus
  • Facebook
  • Twitter

Подобни статии:

  1. Оптимизиране на бързодействието на сайт Пиша тази статия като продължение на статията PHP парсване на XML новини за твоя сайт. Разглеждам оптимизиране на бързодействието на...
  2. PHP създаване на RSS Feed Generator Ganbox.com предоставя безплатно един PHP клас за бързо създаване на динамична RSS емисия с новини, които се извличат от базата...
Ако тази статия е била полезна за теб може да почерпиш автора в тази страница »


Коментари
Димитър Чакъров на 13 август 2009 в 22:28       директен линк

мерси за урока. имам един въпрос – знаеш ли други сайтове с български новини, от които може да се дърпа безплатно?

gan на 14 август 2009 в 23:49       директен линк

Има доста сайтове с RSS новини ето един dnes.bg/rss_info.php

Toshko на 8 септември 2009 в 12:39       директен линк

GAN много хубав урок но при мен на сайта излиза маймунски знаци, защото кодировката мие 1252 а там е utf-8 как да я оправя?

gan на 8 септември 2009 в 13:15       директен линк

След реда: foreach($arrFeeds as $oneItem){
Добави кода:
foreach($oneItem as $key=>$value){ $oneItem[$key]=iconv(‘utf-8′,’cp1252′,$value); }

Toshko на 8 септември 2009 в 15:08       директен линк

Gan Браво стана чак сега погледнах как си го направил мерси
Черпихте една голяма виртуална бира така трябва да прави всеки това е труд все пак :)

Toshko на 15 септември 2009 в 14:52       директен линк

Gan а можели да се направи с картинките да показва …има и такива емисии. Аз пробвах да сложа още един ред ‘image’ =>$node->getElementsByTagName(‘pubDate’)->item(0)->nodeValue, Но грешка ми дава.

gan на 16 септември 2009 в 11:16       директен линк

Това pubDate е датата на публикуване на статията. Картинките обикновено са в текста description и се подават като HTML от RSS в такъв случай не трябва да променяш нищо. Дай връзка към страницата в която се опитваш да покажеш RSS.

Georgy на 28 септември 2009 в 19:36       директен линк

Здрасти. :) Ами ако искаш да извлечеш картинката от enclosure таг? Някои знае ли как става това, търсих из нета но не мога да намеря. Благодаря предварително.

gan на 29 септември 2009 в 10:40       директен линк

Прави се лесно, защото enclosure тага съдържа само пътя до мултимедиен файл, а не самия файл. Дай връзка към RSS който съдържа enclosure и може да напиша пример.

Georgy на 30 септември 2009 в 18:10       директен линк

Ок ако ми напишеш сте сам ти много благодарен дакажем с http://news.ibox.bg/rss_1 . Може и само реда на пхп да напищеш. Мерси.

gan на 30 септември 2009 в 19:26       директен линк

За парсване на enclosure таг, след реда:
date’ =>$node->getElementsByTagName(‘pubDate’)->item(0)->nodeValue,
Добави реда:
‘enclosure’ => $node->getElementsByTagName(‘enclosure’)->item(0)->getAttribute(‘url’),
Така в масива $itemRSS ще имаш и пътя до мултимедийния файл.

Адаш имаш да черпиш ;)

Georgy на 30 септември 2009 в 22:38       директен линк

ok А за да я прнтне какво да напиша? Така не я показва не знам защо. Сигурно трябва да се напише нещо и в foreach($arrFeeds as $oneItem){

gan на 1 октомври 2009 в 21:42       директен линк

Е разбира се, че ще трябва да го изведеш от масива. Реда:
print ‘<p class=“feedDesc“>’.$oneItem['desc'].’</p>’;
трябва да стане нещо като:
print ‘<p class=“feedDesc“><img src=“‘.$oneItem['enclosure'].’“ align=“left“ />’.$oneItem['desc'].’</p>’;

Ivaylo на 30 декември 2009 в 23:29       директен линк
bankera на 28 януари 2010 в 0:02       директен линк

Здр. Искам да те питам защо ми изкарва тази грешка на ред 65
‘enclosure’ => $node->getElementsByTagName(‘enclosure’)->item(0)->getAttribute(‘url’),
като го махна всичко е ок но сложа ли го дава грешка. Това е за да изкарам и картинката от http://news.ibox.bg/rss_1

gan на 28 януари 2010 в 1:31       директен линк

Очевидно е. Някои от новините нямат enclosure елемент и заради тях гърми. Трябва леко да се промени кода. Там където пълниш масива $itemRSS става:
‘enclosure’ => $node->getElementsByTagName(‘enclosure’),
Там където показваш новините става:

$articlesOutput .= '<p class="feedDesc">'.(is_object($oneItem['enclosure']->item(0)) ? '<img src="'.$oneItem['enclosure']->item(0)->getAttribute('url').'" width="50" alt="" />' : '').$oneItem['desc'].'</p>';
potrebitel на 21 февруари 2010 в 19:21       директен линк

Скрипта работи,но имам един проблем как да взема новини от сайт с енкодинг utf-8 и да ги сложа на сайта си скойто има енкодинг windows 1251

gan на 21 февруари 2010 в 20:29       директен линк

Отговорът на твоя въпрос се намира в самия код. Прочети внимателно коментарите в кода.

Koev на 10 март 2010 в 23:47       директен линк

На мен ми дава грешка – Parse error: syntax error, unexpected T_OBJECT_OPERATOR, expecting ‘)’ in /users/xteamonl/public_html/consultcommerce99/index2.php on line 79

Възможно ли е да е от версията на PHP?

gan на 11 март 2010 в 0:35       директен линк

Ако близо до ред 79 има: $doc = new DOMDocument();
значи е заради версията. Този пример изисква PHP 5.

Koev на 11 март 2010 в 0:48       директен линк

А какви са вариантите за PHP4xx?

less is more на 6 август 2010 в 9:25       директен линк

ползвайте simplexml :)

mitko на 1 юли 2011 в 23:03       директен линк

Здр. чудесна статия, но бихте ли ми казали и как да огранича до напримерно 10, 20 знака да се показват от всяка новина?

gan на 3 юли 2011 в 18:12       директен линк

Използва се функция $text=mb_substr($text,0,20);

Вик на 27 октомври 2011 в 21:30       директен линк

Здравейте, и аз се опитва да съкратя текста, но как точно се поставя $text=mb_substr($text,0,20); пробвам но все не се получава

Георги Стефанов на 27 октомври 2011 в 23:48       директен линк

От това „все не се получава“ не е ясно какъв е проблема. Ако PHP дава грешка (или бяла страница) това означава, че на хостинга няма библиотеката mb_string. Ако функцията сработва, но не отрязва правилния брой символи може да пробвате с поставяне на четвърти параметър за енкодинга. Например $text=mb_substr($text,0,20,’UTF-8′); или $text=mb_substr($text,0,20,’cp1251′); в зависимост от това кой енкодинг ползвате.

Вик на 28 октомври 2011 в 22:08       директен линк

mb_string имам поддръжка, но на кой ред се слага? как би изглеждал нагледно кода? Благодаря (надявам се това да бъде полезно и за другите потребители)

Георги Стефанов на 28 октомври 2011 в 22:47       директен линк

Ако трябва да съкратя заглавията до 20 символа, бих направил следното. В цикъла foreach, преди операторите print и след реда $feedCount++; ще поставя следния код:
if(mb_strlen($oneItem['title'])>20){
$oneItem['title']=mb_substr($oneItem['title'],0,20,’UTF-8′).’…’;
}

Glo на 29 март 2012 в 9:51       директен линк

Имам един въпрос. Скрипта си бачка, но във feed-a имам една новина, към която няма текст, а само снимка, което ми разформатира текста. Възможно ли е да се направи ако $oneItem['desc'] е 0 да се слагат няколко тага?

Георги Стефанов на 29 март 2012 в 9:53       директен линк

Защо не? Контролът е при вас. Можете в този случай да сложите всичко. Например

 
Напиши коментар

Твоето име: (без ключови думи!) 
Имейл: (не се показва) 
Сайт: (незадължително) 
Коментар