Парсер погоды через API Яндекса на PHP

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

Для начала хотелось бы отметить необходимость при использовании погоды Яндекса указания ссылки на правообладателя. Я в примерах этого делать не буду, так как статья обучающая. Думаю, Яндекс меня поймет и простит.

Итак, начнем сразу с простейшего примера, состоящего из двух файлов: weather.php для описания функции получения погоды и index.php для вывода прогноза с необходимыми нам параметрами. Выглядит это так:

Пример 1

Исходники смотрите в окончании статьи. Ниже я не буду приводить весь код, содержащийся в файлах, только основные моменты.

Файл weather.php описывает функцию get_weather. В качестве обязательного параметра — только идентификатор города, который можно найти здесь:

http://weather.yandex.ru/static/cities.xml

Находим нужный город поиском и забираем параметр id. Файл погоды содержит прогноз на 10 дней, предусмотрим в скрипте указание количества дней, на которые необходимо получить данные. По умолчанию ставим 10, т.е. парсим по максимуму. Также в качестве дополнительных настроек указываем массивы имен дней недели и времени суток для более удобного вывода информации конечному пользователю.

В итоге получаем функцию get_weather со следующими параметрами:
$city — город
$col — количество дней, для которых получить погоду
$day_of_the_week_array — массив дней недели
$time_of_day — массив времени суток

Первый — обязательный, для других по умолчанию устанавливаем привычные «понедельник, вторник…» и «утро, день, вечер…»

Далее с помощью функции simplexml_load_file заполняем переменную $xml, в адрес подставляем идентификатор города, так Яндекс поймет, какой именно прогноз нам показать.

$data_file = 'http://export.yandex.ru/weather-ng/forecasts/'.$city.'.xml';    
$xml = simplexml_load_file($data_file);  


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

Дату обрабатываем из xml следующим образом:

$get_date = explode ("-" , $day['date']); 
$day_of_week = date("N", mktime(0, 0, 0, $get_date[1], $get_date[2], $get_date[0]));
 
$out[$counter]['day'] = $get_date[2];
$out[$counter]['month'] = $get_date[1];
$out[$counter]['year'] = $get_date[0];
$out[$counter]['day_of_week'] = $day_of_the_week_array[$day_of_week]; 


Разбиваем дату на составляющие (день, месяц, год), получаем затем день недели и заполняем все это в переменную вывода для текущего дня.

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

Поясню получение температуры:

if ($day->day_part[$i]->temperature == '') {
 
$get_temp_from =  $day->day_part[$i]->temperature_from;
$get_temp_to =  $day->day_part[$i]->temperature_to;
 
} else {
     $get_temp_from = (integer)$get_temp-1;
     $get_temp_to = (integer)$get_temp+1;
}


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

Иначе забираем содержимое temperature. Я решил добавлять для него плюс и минус один, образуя тем самым диапазон. В любом случае прогноз таким точным не будет, а для нас важно однообразно выводить информацию.

Добавляем также + для температуры больше нуля.

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


Теперь все, что осталось, это добавить в массив полученную информацию о температуре, плюс имя файла изображения и наименование времени суток.

Повторяем эту операцию для нужного количества дней и возвращаем массив $out.

В файле index.php создаем переменную, в которую в результате выполнения функции заносим этот самый массив, и теперь используем его для вывода информации. Используем при этом foreach для прохода по массиву.

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

Используя данный метод, можно создавать удобные сервисы, отображающие погоду в автоматическом режиме. В примере два мы выводим два выпадающих списка — страна и город. Данные подгружаем из файла cities.xml (ссылка на него выше). После выбора города погода подгружается через ajax автоматически.

Пример 2

Заметил для некоторых городов скрипт выдает ошибку — не находит прогноз. Это глюк Яндекса. Т.е город в списке есть, но при попытке получить xml для выбранного id оказывается, что файл не существует. Решение проблемы я вижу только в выводе текстового сообщение вроде «Прогноз погоды для выбранного города в данный момент не доступен».

Из преимуществ также отмечу быстрый ответ сервера Яндекса и его устойчивость. Также он выдерживает большое количество обращений и не дает сбоев. Это здорово. Хотя при многотысячной посещаемости, предполагаю, могут возникнуть проблемы и ошибки.

Выход прост — пишем скрипт по закачке файлов к себе на сервер, ставим на cron и проделываем данную операцию раз в сутки (лучше ночью). Таким образом, получаем несколько тысяч xml-файлов прогнозов для каждого города и по ходу дня обращаемся уже к ним, а не к Яндексу. В этом случае также есть смысл ограничить количество городов парсинга. К примеру, если пишете скрипт для сайта туристического агенства — ограничьтесь городами, с которыми оно работает. Составьте массив необходимых городов и парсите только нужные.



Просмотров: 7114
13.02.2015, 23:46 -

Категория: Статьи » Программирование » PHP