Делаем простой парсер новостей на php.


Итак, есть новостной ресурс (для примера, возьмем новости с Яндекса) и есть задача получать на автомате с этого сайта несколько последних новостей. Полученные новости мы должны в нужном нам формате выводить на странице нашего сайта.

1. Находим нужную rss ленту нашего новостника. В нашем случае — это http://news.yandex.ru/index.rss (у Яндекса множество лент, разбитых по категориям. Берем одну из них — «Главные новости»). Новости в ленте состоят из заголовка (с ссылкой на саму новость), даты публикации и краткого анонса.

Сам xml документ выглядит примерно так (укорочен):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:yandex="http://news.yandex.ru" xmlns:str="http://exslt.org/strings" version="2.0">
  <channel>
    <title>Яндекс.Новости: Главные новости</title>
    <link xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:lego="https://lego.yandex-team.ru">http://news.yandex.ru/index.html</link>
    <description>
      Первая в России служба автоматической обработки и систематизации новостей. Сообщения ведущих российских и мировых СМИ. Обновление в режиме реального времени 24 часа в сутки.
    </description>
    <image xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:lego="https://lego.yandex-team.ru">
      <url>http://company.yandex.ru/i/50x23.gif</url>
      <link>http://news.yandex.ru</link>
      <title>Яндекс.Новости</title>
    </image>
    <lastBuildDate>Mon, 12 Nov 2012 09:20:44 +0000</lastBuildDate>
    <item>
      <title>Путин утвердил состав нового Совета по правам человека</title>
      <link>http://news.yandex.ru/yandsearch?cl4url=www.forbes.ru%2Fnews%2F203951-putin-utverdil-sostav-novogo-soveta-po-pravam-cheloveka&amp;cat=0&amp;lang=ru</link>
      <description>Президент России Владимир Путин утвердил новый состав президентского Совета по развитию гражданского общества и правам человека ( СПЧ ). Текст указа опубликован на сайте Кремля. В утвержденном списке – 39 новых фамилий.</description>
      <pubDate>Mon, 12 Nov 2012 08:36:10 +0000</pubDate>
      <pubDateUT>1352709370</pubDateUT>
      <guid>http://news.yandex.ru/yandsearch?cl4url=www.forbes.ru%2Fnews%2F203951-putin-utverdil-sostav-novogo-soveta-po-pravam-cheloveka&amp;cat=0&amp;lang=ru</guid>
    </item>
<item>
      <title>«Луркморье» могло попасть в «черный список» за статью о марихуане</title>
      <link>http://news.yandex.ru/yandsearch?cl4url=izvestia.ru%2Fnews%2F539403&amp;cat=0&amp;lang=ru</link>
      <description>IP-адрес «Луркоморья» (85.17.124.180) был добавлен в «черный список». Решение о внесении ресурса в список запрещенных сайтов принял ФСКН. Об этом сообщается на официальном сайте Роскомнадзора.</description>
      <pubDate>Mon, 12 Nov 2012 07:30:00 +0000</pubDate>
      <pubDateUT>1352705400</pubDateUT>
      <guid>http://news.yandex.ru/yandsearch?cl4url=izvestia.ru%2Fnews%2F539403&amp;cat=0&amp;lang=ru</guid>
    </item>
</channel>
</rss>

Как видно из примера, структура включает несколько строк служебной информации об источнике, а уже затем идут сами новости, обрамленные тегами item. В конце документа идут заключительные теги channel и rss.

Для нашей задачи нужны только новости в тегах item, при этом лишь определенное количество новостей (последние четыре).

2. Парсим (считываем) нужное нам количество строк из xml-документа.

1
2
3
4
5
6
7
8
9
    $buffer="";//здесь будем хранить весь полученный документ
    $handle = fopen("http://news.yandex.ru/index.rss", "r");
    for($i=0;$i<46;$i++):
      feof($handle);
      $line = fgets($handle);
      $buffer .=$line;
    endfor;
    fclose($handle);
    $buffer .="</channel></rss>";

Здесь мы считываем 46 строк. Почему 46? Потому что последняя новость (ее заключительный тег item) находится на 46 строчке. Чтобы спарсенный документ был цельным, мы добавляем в его конец закрывающие теги channel и rss.

3. Разбираем полученный xml-документ в массив. Для решения данной задачи используем специальные функции php.

1
2
3
4
5
6
// создаем xml-анализатор, ссылка на него помещается в $p
$p = xml_parser_create(); 
//следующая функция разбирает наш документ и создает два массива (один со значениями, другой с индексами)
 xml_parse_into_struct($p, $buffer, $vals, $index);
//Освобождаем память, занятую XML анализатором $p
 xml_parser_free($p);

4. Для вывода полученного контента нам достаточно одного массива со значениями $val. Нам нужно создать цикл, который бы выводил заголовки, дату и анонсы новостей.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
//начинаем с 20-го элемента, т.к. вначале идут не новости, а служебная информация об источнике
  $e=20;
//выводим четыре новости
    for($k=0;$k<4;$k++):
//заголовок
      $yandex_title=$vals[$e]['value'];
      $e=$e+2;
//ссылка на новость
      $yandex_link=$vals[$e]['value'];
      $e=$e+2;
//анонс новости
      $yandex_desc=$vals[$e]['value'];
  ?>
      <div class="yandex_news">     
        <div class="news_text">
          <h2><a href="<?=$yandex_link?>"target="_blank"><?=$yandex_title?></a></h2>
            <?=$yandex_desc?></a>
        </div>
      </div>
<?php
//делаем переход к индексу в массиве для следующей новости
      $e=$e+11;
      endfor;
?>

Таким образом, на нашей странице будут выведены последние новости от новостной ленты Яндекса.





Другие посты

Категория: PHP-скрипты

Комментарии (4)

 

  1. Попробовал спарсить новости с яндекса, все получилось отлино.. буду пробовать дальше всегда было интересно что то выводить на сайте своем

  2. денис:

    а как с кодировкой решить проблему? выводится в утф-8 а у меня сайт в вин-1251..попробовал в див засунуть чарсет утф-8 но толку ноль..подскажите?

  3. admin:

    Попробуйте encoding сделать с помощью php функций

  4. Dmitry:

    както тяжело, что надо отсчитывать элементы. нельзя просто просматривать тело между тегами?

Оставить комментарий