Все о парсинге RSS лент средствами PHP
Среда, 30 сентября 2009 г.
Просмотров: 688
Подписаться на комментарии по RSS
RSS — семейство XML-форматов, предназначенных для
описания лент новостей, анонсов статей, изменений в блогах и т. п.
Информация из различных источников, представленная в формате RSS, может
быть собрана, обработана и представлена
пользователю в удобном для него
виде специальными программами-агрегаторами.
То есть это по сути XML (кто незнает что это идем в википедию и читаем),
а XML как нам известно хорошо структурированный документ. Я клоню к
тому что если в RSS есть открывающий тег, то должен быть и закрывающий
(например: <title>Заголовок</title>), иначе это не RSS.
Думаю на данном этапе суть ясна: нам нужно получить информацию
заключенную между тегами. Любая RSS лента имеет заголовок заключенный
между тегами <title></title> и сам текст статьи заключенный
между тегами < description></description>, именно их нам и
нужно спарсить.
Теперь расскажу о способах написания RSS парсера и что предлагает нам PHP для реализации.
Способ 1 – SimpleXML
SimpleXML – это расширение для PHP5 устанавливаемое
в него по умолчанию, представляет самый простой и элегантный способ
обработки XML (соответственно и RSS) файлов. Это и наиболее
предпочтительный способ, но он стал доступным только в 5 версии PHP.
Тут нет ничего проще, данный код наглядно показывает как просто парсить
RSS ленты средствами SimpleXML:
<?
$url = 'rss.xml'; //адрес RSS ленты
$rss = simplexml_load_file($url); //Интерпретирует XML-файл в объект//цикл для обхода всей RSS лентыforeach ($rss->channel->item as $item) {
echo '<h1>'.$item->title.'</h1>'; //выводим на печать заголовок статьи
echo $item->description; //выводим на печать текст статьи}?>
Данный код выведет заголовки и тексты статей из RSS ленты. Просто
ведь? Этим SimpleXML и привлекает. Дальше вам нужно будет только
правильно распорядиться полученными данными, записать в базу или еще
куда-нибудь.
Способ 2 – XML Parser Functions
XML Parser Functions - это стандартные функции PHP
для работы с XML доступные начиная c 4-ой версии PHP. Тоже нет ничего
сложного, правда в отличие от SimpleXML совсем не элегантно.
Продемонстрирую пример:
<?
$url = 'rss.xml'; //адрес RSS ленты
$xml = xml_parser_create(); //создаёт XML-разборщик
xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1); //устанавливает опции XML-разборщика
xml_parse_into_struct($xml, file_get_contents($url), $element, $index); //разбирает XML-данные в структуру массива
xml_parser_free($xml); //освобождает XML-разборщик
$count = count($index["TITLE"])-1; //число проходов цикла.for ($i=0; $i < $count; $i++) {
echo '<h1>'.$element[$index["TITLE"][$i+1]]["value"].'</h1>'; //выводим на печать заголовок статьи
echo $element[$index["DESCRIPTION"][$i+1]]["value"]; //выводим на печать текст статьи}?>
Вот таким образом мы получаем интересующие нас содержимое элементов
RSS. Но тут уже нужно разобраться с массивами которые создает XML
разборщик.
Способ 3 – Написать RSS парсер самому
Например я делал именно так, когда не знал про существование
SimpleXML и XML Parser Functions. Приведу небольшой пример парсинга RSS
обычным процедурным PHP кодом, тут за парсинг отвечает функция
preg_match_all(), которая выполняет глобальный поиск шаблона в строке.
Данный пример не совершенен и парсит только титлы и дескрипшены у RSS:
<?
$url = 'rss.xml'; //адрес RSS ленты
$rss = @file_get_contents($url); //получаем содержимое RSS лент в виде одной строкиif ($rss) {
preg_match_all("/title>[^>]+>/", $rss, $title); //парсим титлы
preg_match_all("/<description>[^<]+<\/description>/", $rss, $description); //парсим дескрипшены
$count = count($title[0])-1; //число проходов цикла.
for ($i=0; $i < $count; $i++) {
echo '<h1>'.substr($title[0][$i+1], 6, -8).'</h1>'; //выводим на печать заголовок статьи
echo substr($description[0][$i], 13, -14); //выводим на печать текст статьи
}} else {
echo '<font color="red">Ошибка парсинга '.$url.'</font>'; //выводим ошибку если file_get_contents() вернула false}?>
Таким же способом можно и отпарсить остальные элементы RSS ленты, главное написать правильно регулярку.
На этих трех способах мы и остановимся, еще есть наверняка множество
сторонних скриптов и классов в PHP для парсинга XML, например magpieRSS
у которого проблемы с кодировкой при парсинге и решить ее у меня не
получилось, да собственно не очень то и хотелось, когда есть SimpleXML
и XML Parser Functions. Вот кстати о проблемах с кодировкой мы сейчас и
поговорим…
Проблемы с кодировкой
RSS ленты как правило находятся в кодировке UTF-8, при парсинге
русского текста тремя способами описанными выше, нам на экран выводятся
кракозябры. Все потому, что тест к нам приходит в кодировке UTF-8. Для
того что бы вывести нормальные РУССКИЕ буквы нужно перекодировать
спарсеный текст из кодировки UTF-8 в Windows-1251. Для этих целей в PHP
существует функция iconv(),
но она доступна не на всех серверах и чтобы избежать дальнейших проблем
с вашим RSS парсером советую использовать самописную функцию
перекодировки. Вникать в тонкости кодировок и разбираться как из одной
кодировки получается другая думаю вам не хочется, так же не хотелось и
мне. Немного погуглив я нашел замечательную функцию перекодировки из UTF-8 в Windows-1251 и обратно,
предоставляет ее некий товарищ E64F. Возможно конечно он тоже ее где-то
слямзил, но это не так важно, важно то что она мне очень понравилась по
сравнению с другими нагуглеными функциями. Выкладываю функцию и пример
ее использования:
<?
echo utf8_convert($str, "w"); //перекодирует $str из UTF-8 в Windows-1251 и выведет на экранfunction utf8_convert($str, $type){
static $conv = '';
if (!is_array($conv))
{
$conv = array();
for ($x=128; $x <= 143; $x++)
{
$conv['utf'][] = chr(209) . chr($x);
$conv['win'][] = chr($x + 112);
}
for ($x=144; $x<= 191; $x++)
{
$conv['utf'][] = chr(208) . chr($x);
$conv['win'][] = chr($x + 48);
}
$conv['utf'][] = chr(208) . chr(129);
$conv['win'][] = chr(168);
$conv['utf'][] = chr(209) . chr(145);
$conv['win'][] = chr(184);
}
if ($type == 'w')
{
return str_replace($conv['utf'], $conv['win'], $str);
}
elseif ($type == 'u')
{
return str_replace($conv['win'], $conv['utf'], $str);
}
else
{
return $str;
}}?>
Функция utf8_convert() принимает 2 параметра: $str – наша строка
которую нужно перекодировать и $type – в какую кодировку нужно
кодировать (“w” – из utf в win, “u” – из win в utf). Как это применить
к нашим 3-м способам парсинга RSS думаю разберетесь, если хоть немного
знаете PHP.
источник
Оставьте комментарий!