Full text

За последние несколько лет инструментарий профессиональных программистов претерпел революционные изменения. Это связано с появлением и реализацией в программировании новых идей, возникновением новых парадигм и понятий. Огромное влияние на эти изменения оказало, в частности, развитие сети Интернет, которое поставило перед разработчиками программного обеспечения новые задачи и проблемы. В результате от преподавателей вузов потребовался быстрый и значительный пересмотр содержания целого ряда дисциплин компьютерного цикла и введение в учебные планы профильной подготовки студентов вузов новых дисциплин.

Большой интерес у студентов вызывают дисциплины, использующие средства веб-программирования. Именно они во многом формируют картину современного программирования. Особое место в списке языков программиста-профессионала занимают серверные языки программирования, такие как PHP, Ruby, Java, C, Python, Perl и дру­гие [1]. Они нужны, в частности, для реализации слоя приложения, называемого бизнес-логикой.

В преподавании цикла компьютерных дисциплин могут быть рассмотрены различные аспекты конкретных серверных языков программирования. В частности, в рамках дисциплины «Сетевые языки и веб-программирование» может быть рассмотрена тема «Парсинг ресурсов сети», которая сегодня весьма актуальна и популярна с точки зрения подготовки специалиста в области IT. Эта тема требует понимания взаимодействия различных программных механизмов, объектов и ресурсов сети. Очень важным аспектом этой темы является изучение той части языкового инструментария, которая необходима для решения задач парсинга. Одна из интересных и практически значимых возможностей таких языков – автоматизированный сбор информации с какого-либо источника с целью его дальнейшей обработки и преобразования для своих собственных потребностей. Такая технология называется парсингом [2]. Программа, которая используется для анализа и обработки данных, называется парсером. Готовые данные, как правило, выкладываются в базу данных, представляются в виде обычного файла или файла в формате XML. Примером парсинга может быть обработка сайта интернет-магазина, результатом которой является список товаров, представленных по категориям. Парсингом могут заниматься поисковые роботы, анализируя страницы и сохраняя полученные данные о них в собственной базе. Эти данные затем используются поисковой системой для ранжирования проанализированных сайтов и формирования выдачи. Парсинг лежит в основе многочисленных сервисов для различных специалистов (например, маркетологов), позволяющих анализировать сайты из поисковой выдачи. В некоторых случаях целью парсинга является не получение каких-то данных из обработанного контента, а сам контент, представленный в нужной заказчику форме.

Скрипты, которые выполняют подобные задачи, называются парсерами. Как правило, они пишутся для получения данных с какого-то конкретного, регулярно обновляемого источника. Целями парсинга могут быть ссылки на разные страницы какого-либо сайта, изображения, видео, текст и другой контент.

При изучении данной темы на лабораторном занятии требуется обсудить с обучающимися различные программные механизмы, языковые средства и объекты, позволяющие получить доступ к ресурсам сети с целью их обработки. Результативность изучения материала будет значительно повышена благодаря практической иллюстрации возможностей парсинга на основе PHP.

Для иллюстрации таких возможностей рассмотрим парсинг RSS ленты с помощью SimpleXML. RSS – семейство XML-форматов, созданных для описания новостных лент, заметок, статей, изменений в блогах и т. п. Информация из разных источников, представленная в формате RSS, может быть подобрана, подвергнута обработке и представлена в некотором удобном виде специальными программами-агрегаторами либо интернет-сервисами типа Feedly, Inoreader, BlinkFeed. Расширение SimpleXML предоставляет очень простой и легкий в использовании набор инструментов для преобразования XML в объект, с которым можно далее работать через его свойства и с помощью итераторов. В свою очередь, язык XML (eXtеnsible Markup Language) – это расширяемый язык, рекомендованный Консорциумом Всемирной паутины (W3C) как язык разметки. Он является подмножеством языка SGML. SimpleXML – это расширение для PHP5, встроенное в него по умолчанию. Оно представляет самый простой способ обработки XML-файлов (и файлов RSS, в частности).

Первый шаг нашей работы – анализ XML-документа и его сохранение в переменной. Это требует написания всего лишь одной строки кода, которая передает URL функции simplexml_load_file():

$rss = simplexml_load_file

('http://news.yandex.ru/hardware.rss');

Функция simplexml_load_file() интерпретирует XML-файл в объект.

Второй шаг – нахождение имени канала.

Имя всего канала находится в дочернем элементе title от элемента channel, порожденного корневым элементом rss. Этот заголовок можно загрузить так, как будто XML-документ был просто последовательной формой объекта класса rss с полем channel, которое, в свою очередь, имело бы поле title. Используя регулярный PHP-синтаксис ссылки на объект, запишем команду нахождения заголовка:

$title = $rss->channel->title;

Далее найдем элементы канала. Выражение, выполняющее эту задачу, записывается также просто:

$rss->channel->item;

Однако каналы могут содержать более одного элемента, либо их может не быть вовсе. Следующая команда возвращает массив, который можно обработать с помощью цикла for-each:

foreach ($rss->channel->item as $item)

{ echo "<h2>". $item->title. "</h2>";

echo "<p>". $item->description. "</p>"; }

Это все, что нужно для написания простой программы чтения RSS средствами PHP. Пример выполнения скрипта показан на рис. 1.

 

 

 

Рис. 1. Результаты парсинга

 

Для улучшения и расширения возможностей данного скрипта можно вывести дополнительные информационные элементы, например дату новости, добавить некоторые свойства CSS, оформить информацию в табличном виде. Результат дополнительной обработки показан на рис. 2.

 

 

 

Рис. 2. Дополнительное оформление результатов парсинга

Еще один пример парсинга, который способствует повышению интереса и мотивации студентов при изучении данной темы, – создание собственного информера погоды.

Информеров погоды много, но у них есть недостаток: такие сервисы в случае необходимости не позволяют изменить внешний вид информера. Это приходится делать в случае необходимости программисту самостоятельно. 

В качестве примера воспользуемся сервисами Яндекс и Yahoo.

Сервис Яндекс предоставляет прогноз в формате XML. Данные, полученные из этого документа, представляют собой подробную сводку по всем метеопараметрам, которые есть на сайте https://pogoda.yandex.ru.

Наш информер будет состоять из двух блоков: первый будет содержать краткую информацию о погоде на сегодняшний день, второй – более подробную, для различных времен суток (утро, день, вечер, ночь).

Перейдем к непосредственному парсингу XML-документа. Для этого воспользуемся специальным расширением SimpleXML, которое появилось в РНР версии 5.0. 

С помощью функции simplexml_load_file() конвертируем файл XML в объект класса SimpleXMLElement.

$xml = simplexml_load_file

("http://export.yandex.ru/weather-ng/

forecasts/27760.xml");

В нашем примере http://export.yandex.ru/weather-ng/forecasts/27760.xml – адрес XML файла, где 27760 – id города, в данном случае Саранска.

Теперь выбираем необходимые параметры для нашего информера (город, температура, пиктограмма, тип погоды текстом, влажность, давление, направление и скорость ветра).

   $city = $xml->attributes()->city;

   $temp = $xml->fact->temperature;

   $img = 'image-v3';

   $pic = $xml->fact->$img;

   $w_type = $xml->fact->weather_type;

   $wind_direction = $xml->fact->wind_direction;

   $wind_speed = $xml->fact->wind_speed;

   $humidity = $xml->fact->humidity;

   $pressure = $xml->fact->pressure;

Выводим все это на экран и добавляем CSS. Результат показан на рис. 3.

 

 

 

Рис. 3

 

Далее создаем второй блок с более подробной информацией. Файл погоды содержит прогноз на 10 дней, но для нашего примера возьмем информацию только за один день. Вывод будем осуществлять с помощью многомерного массива $OutWeather.

 

$OutWeather = array();

foreach ($xml->day as $day ) {

for ($i = 0; $i <= 3; $i++) {

   if($day->day_part[$i]->temperature == '')

{

   $temp_from = $day->

day_part[$i]->temperature_from;

$temp_to = $day->day_part[$i]->

temperature_to;

    }

else

{                         $temp_from = (int)$get_temp – 1;

                            $temp_to = (int)$get_temp + 1;

                }

               if ($temp_from > 0)

{ $temp_from = '+'.$temp_from; }

               if ($temp_to > 0) { $temp_to ='+'.$temp_to; }

    $OutWeather[0]['weather'][$i]['temp_from'] =

$temp_from;

$OutWeather[0]['weather'][$i]['temp_to'] =

$temp_to;

               $OutWeather[0]['weather'][$i]['image'] =

$day->day_part[$i]->{'image-v3'};

               $OutWeather[0]['weather'][$i]['time_day'] =

$TimeDay[$i];

               $OutWeather[0]['weather'][$i]['wind_speed'] =

$day->day_part[$i]->wind_speed;

               $OutWeather[0]['weather'][$i]['wind_direction']=

$day->day_part[$i]->wind_direction;

               $OutWeather[0]['weather'][$i]['humidity'] =

$day->day_part[$i]->humidity;

               $OutWeather[0]['weather'][$i]['pressure'] =

$day->day_part[$i]->pressure;

               $OutWeather[0]['weather'][$i]['weather_type'] =

$day->day_part[$i]->weather_type;

    }

   }

Результат работы данного кода показан на рис. 4–5.

 

 

 

Рис. 4

 

   
   

 

Рис. 5

 

Yahoo! Weather предоставляет информацию в формате RSS на ближайшие пять дней.

Опять с помощью функции simplexml_load_file() конвертируем файл XML в объект класса SimpleXMLElement.

$xml =

simplexml_load_file("http://xml.weather.yahoo.com/

forecastrss?p=RSXX1460&u=c");

RSXX1460& – код города, с – параметр, который соответствует градусам Цельсия.

Для парсинга будем использовать XPath.

XPath (XML Path Language) – язык запросов к элементам XML-документа. Язык разработан для организации доступа к частям документа XML в файлах трансформации XSLT и является стандартом консорциума W3C. XPath призван реализовать навигацию по DOM в XML.

//Ветер

   $wind = $xml->xpath("/rss/channel/yweather:wind");

   $wind = $wind[0];

   $wind_direction = (int)$wind['direction'];

   $wind_speed = (int)$wind['speed'];

//Атмосферные показатели

   $atmosphere = $xml->xpath

("/rss/channel/yweather:atmosphere");

   $atmosphere = $atmosphere[0];

   $humidity = (int)$atmosphere['humidity'];

   $visibility = (int)$atmosphere['visibility'];

   $pressure = (int)$atmosphere['pressure'];

// Время восхода и заката

   $astronomy = $xml->xpath

('/rss/channel/yweather:astronomy');

$astronomy = $astronomy[0];

$sunrise = $astronomy['sunrise'];

   $sunset = $astronomy['sunset'];

//Текущая температура воздуха и погода

   $condition = $xml->xpath

('/rss/channel/item/yweather:condition');

   $condition = $condition[0];

   $temperature = (int)$condition['temp'];

$condition_text = (string)$condition['text'];

$condition_code = (int)$condition['code'];

Прогноз погоды на следующие дни:

$forecast = array();

$weatherFiveDays = $xml->xpath

('/rss/channel/item/yweather:forecast');

foreach($weatherFiveDays as $day) {

$forecast[] = array(

'date' => strtotime((string)$day['date']),

'low' => (int)$day['low'],

'high' => (int)$day['high'],

'text' => (string)$day['text'],

'code' => (int)$day['code']);

}

Давление можно перевести в миллиметры ртутного столба. Для этого $pressure умножим на 0,75006375541921. Результат скрипта показан на рис. 6.

 

 

 

Рис. 6

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

Рассмотренные языковые инструменты и примеры способствуют более качественному усвоению студентами заявленной темы в образовательном курсе, а также дают возможность не только понять идеи механизма парсинга, но и использовать их в решении образовательных и практических жизненных задач.