18
февраля
2008

Поговорим о погоде

За последнее время мне пришлось довольно основательно пообщаться с несколькими сервисами Yahoo! В этой заметке расскажу об одном из них, который для многих может оказаться полезным. Это сервис прогноза погоды Yahoo! Weather.

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

Yahoo! Weather порадовал отсутствием перечисленных недостатков. Информация о текущей погоде, а так же прогноз на ближайшие 5 дней экспортируется с их сервера в формате RSS. На мой взгляд, выбор этого формата притянут за уши, т.к. погодная RSS «лента» содержит всего однин item. Те же данные можно было бы экспортировать в более лаконичном виде, но в Yahoo, по всей видимости, расчитывали на стандартные методы обработки RSS, что тоже довольно весомый довод. Стандарт — это все-таки стандарт.

Адрес RSS фида для интересующего города можно найти на сайте weather.yahoo.com.

В общем виде URL выглядит следующим образом:

http://xml.weather.yahoo.com/forecastrss?p=кодгорода&u=единицыизмерения

Первый параметр — идентификатор интересующего города. Второй параметр определяет, в каких единицах будет выдаваться температура. Значение «c» соответствует градусам Цельсия, «f» — градусам Фаренгейта.

Несколько примеров:

Описанный ниже класс YahooWeather (PHP5) предназначен для загрузки RSS по HTTP и предварительной обработки данных.

<?php

class YahooWeather { // Ветер public $wind_chill; public $wind_direction; public $wind_speed;

// Атмосферные показатели
public $humidity;
public $visibility;
public $pressure;

// Время восхода и заката переводим в формат unix time
public $sunrise;
public $sunset;

// Текущая температура воздуха и погода
public $temp;
public $condition_text;
public $condition_code;

// Прогноз погоды на 5 дней
public $forecast;

public $units;

function __construct($code, $units = 'c', $lang = 'en') {
    $this-&gt;units = ($units == 'c')?'c':'f';

    $url = 'http://xml.weather.yahoo.com/forecastrss?p='.
        $code.'&u='.$this-&gt;units;

    $xml_contents = file_get_contents($url);
    if($xml_contents === false) 
        throw new Exception('Error loading '.$url);

    $xml = new SimpleXMLElement($xml_contents);

    // Ветер
    $tmp = $xml-&gt;xpath('/rss/channel/yweather:wind');
    if($tmp === false) throw new Exception("Error parsing XML.");
    $tmp = $tmp[0];

    $this-&gt;wind_chill = (int)$tmp['chill'];
    $this-&gt;wind_direction = (int)$tmp['direction'];
    $this-&gt;wind_speed = (int)$tmp['speed'];

    // Атмосферные показатели
    $tmp = $xml-&gt;xpath('/rss/channel/yweather:atmosphere');
    if($tmp === false) throw new Exception("Error parsing XML.");
    $tmp = $tmp[0];

    $this-&gt;humidity = (int)$tmp['humidity'];
    $this-&gt;visibility = (int)$tmp['visibility'];
    $this-&gt;pressure = (int)$tmp['pressure'];

    // Время восхода и заката переводим в формат unix time
    $tmp = $xml-&gt;xpath('/rss/channel/yweather:astronomy');
    if($tmp === false) throw new Exception("Error parsing XML.");
    $tmp = $tmp[0];

    $this-&gt;sunrise = strtotime($tmp['sunrise']);
    $this-&gt;sunset = strtotime($tmp['sunset']);

    // Текущая температура воздуха и погода
    $tmp = $xml-&gt;xpath('/rss/channel/item/yweather:condition');
    if($tmp === false) throw new Exception("Error parsing XML.");
    $tmp = $tmp[0];

    $this-&gt;temp = (int)$tmp['temp'];
    $this-&gt;condition_text = strtolower((string)$tmp['text']);
    $this-&gt;condition_code = (int)$tmp['code'];

    // Прогноз погоды на 5 дней
    $forecast = array();
    $tmp = $xml-&gt;xpath('/rss/channel/item/yweather:forecast');
    if($tmp === false) throw new Exception("Error parsing XML.");

    foreach($tmp as $day) {
        $this-&gt;forecast[] = array(
            'date' =&gt; strtotime((string)$day['date']),
            'low' =&gt; (int)$day['low'],
            'high' =&gt; (int)$day['high'],
            'text' =&gt; (string)$day['text'],
            'code' =&gt; (int)$day['code']
        );
    }
}

public function __toString() {
    $u = "&deg;".(($this-&gt;units == 'c')?'C':'F');
    return $this-&gt;temp.' '.$u.', '.$this-&gt;condition_text;
}

}

?>

Пример использования:

<?php

try { $weather = new YahooWeather('RSXX0091'); } catch(Exception $e) { echo "Caught exception: ".$e->getMessage(); exit(); }

echo '<h1>'.$weather.'</h1>';

echo "<pre>"; print_r($weather); echo "</pre>";

?>

Вывод:

Временные значения восхода и заката солнца (поля sunrise и sunset соответственно) автоматически переводятся в формат unix time. стоит так же обратить внимание на то, что по непонятной причине Yahoo! выдает явно некорректное значение атмосферного давления (0). Но само наличие соответствующего атрибута в XML дает некоторую надежду на то, что рано или поздно экспорт этих данных починят.

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

КодОписание
0tornado
1tropical storm
2hurricane
3severe thunderstorms
4thunderstorms
5mixed rain and snow
6mixed rain and sleet
7mixed snow and sleet
8freezing drizzle
9drizzle
10freezing rain
11showers
12showers
13snow flurries
14light snow showers
15blowing snow
16snow
17hail
18sleet
19dust
20foggy
21haze
22smoky
23blustery
24windy
25cold
26cloudy
27mostly cloudy (night)
28mostly cloudy (day)
29partly cloudy (night)
30partly cloudy (day)
31clear (night)
32sunny
33fair (night)
34fair (day)
35mixed rain and hail
36hot
37isolated thunderstorms
38scattered thunderstorms
39scattered thunderstorms
40scattered showers
41heavy snow
42scattered snow showers
43heavy snow
44partly cloudy
45thundershowers
46snow showers
47isolated thundershowers
3200not available

Ссылки по теме

Комментарии к заметке «Поговорим о погоде»

# electrocat: (19 февраля, 2008 @ 22:58)

Спасибо !

# electrocat: (20 февраля, 2008 @ 20:51)

а вы не переводили на русский эту таблицу condition_code ? :)

# admin: (20 февраля, 2008 @ 21:20)

electrocat: Не переводил.Была такая мысль, но не было прямой необходимости.

# Janik: (24 февраля, 2009 @ 04:00)

Здравствуйте! Спасибо за информацию, очень познавательно. Только есть ещё один вопрос: Не доводилось ли Вам встречаться с некой, может быть, таблицей кодов городов, наподобие RSXX0091 и что означают зашифрованные данные в этих ZIP-кодах? Спасибо.

# admin: (24 февраля, 2009 @ 10:52)

Janik: Я встречался с такими кодами как раз в сервисе Yahoo Weather. Как именно расшифровывается Location ID — не знаю, но первые две буквы — идентификатор страны, вторые две — какая-то дополнительная его часть (не идентификатор города). Вроде бы, если вторые два символа не использвуются, они заменяются на XX. Все вместе с номером образует код города. Ну а если немного поискать, можно найти таблицу: http://b23.ru/q2k

# Janik: (24 февраля, 2009 @ 13:31)

О! Спасибо большое.

# GeK@: (17 июня, 2009 @ 08:52)

Что то я не понял где взять прогноз на ближайшие 5 дней?

# seotavr: (16 июля, 2009 @ 16:43)

А моей диревни тама нет – Уфа.А жаль….

# somebody: (9 ноября, 2009 @ 11:16)

если добавите в коне &d= то получите прогноз на несколько дней, макс. 5 дней

# Палю тему: (24 февраля, 2010 @ 00:54)

Пожалуйста пример в студию! Куда именно добавить &d=5 ?

# Юрий: (15 ноября, 2010 @ 22:42)

Глупо брать погоду с yahoo, если yahoo берет ее с weather.com откуда ее тоже можно брать в формате xml, что и делает программа conky для Linux. Все в Linux! :)

# mir46.ru: (26 января, 2011 @ 11:38)

Сейчас тестил, почему-то в массиве $forecast, инфа не на 5 дней а на 2 =\

Написать комментарий

Можно использовать следующие HTML теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> .