Pogoda na stronie www
23 czerwca 2010
Skryptów PHP do pobierania informacji o pogodzie widziałem kilka. Większość to straszne kobyły, część nie działa, inna część działa błędnie lub mało wydajnie. Znowu przyszło mi pisać coś swojego...
Z pogodą na stronie jest jeden podstawowy problem: trzeba skądś pobrać dane. Są trzy wyjścia:
- Wstawić na stronę gotową "wklejkę", która jest odpowiedzialna za wyświetlenie pogody (i przy okazji linka do źródła, logo innego serwisu itp.).
- Parsować jakąś stronę www i "na chama" wyciągać z niej informacje o pogodzie (np. z pogoda.onet.pl).
- Parsować ogólnodostępne źródło, najczęściej jakiś RSS
Pierwszym sposobem zajmować się nie będziemy wcale. Po to piszemy własny skrypt żeby wyświetlić pogodę dokładnie tak jak chcemy, bez zbędnych linków, obrazków itd. a nie tak jak ktoś nam nakaże.
Drugi sposób ma swoje zalety i wady.
Nasze rodzime serwisy informacyjne mają bogatą bazę polskich miejscowości. Każdy znajdzie tam swoją miejscowość lub inną, bardzo blisko położoną swojej. Dodatkowo najczęściej udostępniają bardzo wiele informacji pogodowych.
Przejdźmy do wad. Po pierwsze, nasze (znaczy polskie) serwisy nie udostępniają informacji o pogodzie w jakimś otwartym standardzie np. RSS. Musimy na własną rękę parsować wybraną witrynę. Gdy na stronie coś się zmieni to w najlepszym przypadku nasza pogoda nagle przestanie działać. W najgorszym, zaczną się u nas wyświetlać jakieś bzdury co w skrajnym przypadku rozwali nam cały serwis...
Druga wada jest powiązana z pierwszą. Skoro musimy parsować stronę to zwyczajnie kradniemy dane. I nie pomoże nawet informacja u nas na stronie skąd pobieramy pogodę. Jeżeli ktoś nie udostępnił RSS, XML czy innego ustrojstwa to znaczy, że nie chce nam czegoś dać, koniec kropka.
I nareszcie przechodzimy do trzeciego sposobu. Zagraniczne serwisy o pogodzie są bardziej liberalne od polskich i najczęściej każde miasto ma swój kanał RSS, który możemy spokojnie pobierać. Mamy dużo większą pewność, że nie będziemy musieli raz na kilka miesięcy zmieniać swoich skryptów w skutek zmian w strukturze pliku nad którym pracujemy. Nie obejdzie się jednak bez wad. Baza miejscowości jest przeważnie dużo skromniejsza niż byśmy tego oczekiwali. Jednak na własnym przykładzie przetestowałem, że nie jest to aż taki duży problem. Dla Tomaszowa Mazowieckiego na jednej ze stron wyświetlam pogodę z kanału Łodzi (jakieś 45km odległości licząc od środka jednego miasta do środka drugiego) i zawsze jest wyjątkowo aktualna ![]()
Udostępniono tylko kilka podstawowych informacji o pogodzie ale tu również praktyka pokazuje, że to jest wystarczające. Pamiętaj, że pogoda na Twojej stronie to tylko dodatek a nie główny element. Jeżeli jest inaczej to musisz podpisać umowę z odpowiednimi instytucjami o udostępnienie danych pogodowych a nie myśleć o pobieraniu tego wszystkiego od innych...
Przejdźmy do konkretów. Rok temu stanąłem przed problemem wyświetlania pogody na stronie www. Dzisiaj udostępniam skrypt
Zdecydowałem się skorzystać z serwisu weather.yahoo.com i po dziś dzień nie miałem okazji pożałować tego wyboru. Poniżej zamieszczam prostą klasę PHP5 z której korzystam:
-
<?php
-
-
class yahoo_weather {
-
-
public $city_code;
-
protected $weather;
-
-
public function __construct($city_code) {
-
$this->city_code = $city_code;
-
}
-
-
public function get($get_channel = NULL) {
-
-
-
try {
-
$xml = @new SimpleXMLElement('http://weather.yahooapis.com/forecastrss?w='. $this->city_code .'&u=c', NULL, TRUE);
-
} catch (Exception $e) {
-
return FALSE;
-
}
-
-
$xml->registerXpathNamespace('yweather', 'http://xml.weather.yahoo.com/ns/rss/1.0');
-
-
$wind = $xml->xpath('//channel/yweather:wind');
-
$atmosphere = $xml->xpath('//channel/yweather:atmosphere');
-
$astronomy = $xml->xpath('//channel/yweather:astronomy');
-
$condition = $xml->xpath('//channel/item/yweather:condition');
-
$forecast = $xml->xpath('//channel/item/yweather:forecast');
-
-
'chill' => "{$wind[0]['chill']}",
-
'direction' => "{$wind[0]['direction']}",
-
'speed' => "{$wind[0]['speed']}",
-
),
-
'humidity' => "{$atmosphere[0]['humidity']}",
-
'visibility' => "{$atmosphere[0]['visibility']}",
-
'pressure' => "{$atmosphere[0]['pressure']}",
-
'rising' => "{$atmosphere[0]['rising']}",
-
),
-
'sunrise' => "{$astronomy[0]['sunrise']}",
-
'sunset' => "{$astronomy[0]['sunset']}",
-
),
-
'text' => "{$condition[0]['text']}",
-
'code' => "{$condition[0]['code']}",
-
'temp' => "{$condition[0]['temp']}",
-
'date' => "{$condition[0]['date']}",
-
),
-
'day' => "{$forecast[0]['day']}",
-
'date' => "{$forecast[0]['date']}",
-
'low' => "{$forecast[0]['low']}",
-
'high' => "{$forecast[0]['high']}",
-
'text' => "{$forecast[0]['text']}",
-
'code' => "{$forecast[0]['code']}",
-
),
-
'day' => "{$forecast[1]['day']}",
-
'date' => "{$forecast[1]['date']}",
-
'low' => "{$forecast[1]['low']}",
-
'high' => "{$forecast[1]['high']}",
-
'text' => "{$forecast[1]['text']}",
-
'code' => "{$forecast[1]['code']}",
-
)
-
)
-
);
-
-
$xml = NULL;
-
}
-
-
if($get_channel == NULL) {
-
return $this->weather;
-
}
-
else {
-
return $this->weather[$get_channel];
-
}
-
}
-
}
Użycie skryptu wygląda następująco (pobieramy kanał http://weather.yahooapis.com/forecastrss?w=505120&u=c):
-
$yahoo_weather = new yahoo_weather('505120');
-
$weather = $yahoo_weather->get();
I od teraz w zmiennej $weather mamy piękną tablicę ze wszystkimi informacjami o pogodzie. Dodatkowo możemy dokonać pewnych przekształceń (według własnych upodobań):
-
-
-
$sunset[0] += 12;
-
-
$weather['astronomy']['sunset'] = $sunset[0] .':'. $sunset[1];
Specjalny kod miejscowości, który przekazujemy do klasy musimy znaleźć sami. Wchodzimy na weather.yahoo.com, odszukujemy miasto, które nam najbardziej odpowiada i klikamy w prawym górnym roku na pomarańczową ikonkę RSS. W adresie na jaki zostaniemy przekierowani w parametrze "p" odnajdziemy interesujący nas kod. Właśnie wyczytałem w dokumentacji, że w adresie RSS zamiast parametru "p" (który został uznany za przestarzały) należy używać parametru "w" podając tzw. kod WOEID. Problem w tym, że gdy odnajdzie się stronę z pogodą dla wybranej miejscowości to sami linkują ikonkę RSS pod adres z parametrem "p". Kod, którego potrzebujemy jest w adresie strony z pogodą dla miasta. Dla Łodzi adres to http://weather.yahoo.com/poland/lodz/%EF%BF%BD%EF%BF%BDd%EF%BF%BD-505120/ z czego interesują nas ostatnie cyferki czyli 505120. Oto nasz kod (wcześniej PLXX0014). Poprawiłem klasę, jest już przygotowana do nowego standardu.
Klasa jest prosta i nie będę jej omawiał
Na jej podstawie można napisać parser pogody z innego serwisu niż weather.yahoo.com lub np. nauczyć się jak pobierać i parsować dokumenty RSS, Atom, XML itp.
Skąd wziąć ikony pogody? Ten problem powtarza się bardzo często, ładne ikony to nieodzowny element prognozy pogody na każdej stronie www. Tu nie pomogą nam nawet zagraniczne serwisy. Nie chcą udostępniać swoich ikon bo to dla nich dodatkowy ruch na łączach i serwerach. A jak chcą to są dodatkowe obostrzenia, konieczność wyświetlania ich logo itp. Z tego powodu moja klasa nie wyciąga adresu do ikony aktualnej pogody mimo, że taki jest podawany (chociaż nie tak otwarcie jak reszta danych). Na szczęście w internecie jest sporo ikon, często darmowych (przynajmniej dla zastosowań niekomercyjnych), którymi możemy na swojej stronie zobrazować pogodę. Tu pojawia się zaleta wyboru weather.yahoo.com. Ich RSS udostępnia kod warunków pogody np. w chwili gdy to piszę jest częściowe zachmurzenie w nocy czemu powinna odpowiadać ikona księżyca za lekkimi chmurkami i takim warunkom przypisano kod 33. Wiele gotowych pakietów ikon uwzględnia te kody przez co sami już nie musimy sprawdzać wszystkich kodów i samemu ich przypisywać do odpowiednich ikon. Wystarczy wyświetlić ikonę 33.png
Nie możesz znaleźć ikon dla siebie? Moim faworytem są te ikony. Są już przystosowane do kodów z weather.yahoo.com. Co więcej, ich autorem jest nasz rodak
Ikony są darmowe do zastosowań niekomercyjnych a za wykorzystanie w komercyjnym projekcie trzeba zapłacić 200zł (tak było rok temu, teraz nie wiem). Warte tych pieniędzy.
W ekstremalnej sytuacji można ściągnąć ikony weather.yahoo.com na własny serwer. Chyba się nie pogniewają...
Na koniec pamiętaj aby wynik powyższej klasy zapisywać jakoś do cache (np. korzystając z dobrodziejstw crona). Niedopuszczalne jest pobieranie informacji o pogodzie za każdym razem gdy musimy je wyświetlić u siebie na stronie. To spowodowałoby bardzo duży wzrost transferu, niepotrzebne obciążenie maszyny i opóźnienie w wyświetlaniu się naszej witryny. Osobiście ściągam pogodę raz na godzinę.
PS
Zachęcam do zapoznania się z dokumentacją RSS, którą można znaleźć pod tym adresem developer.yahoo.com/weather.
PS 2
A może jednak jakiś polski serwis udostępnia w prostej postaci i za darmo informacje o pogodzie? Poproszę o linki w komentarzach
Blog przede wszystkim o Internecie i mojej pasji jaką jest tworzenie stron www. Ale nie ograniczam się do jednej tematyki, piszę o wszystkim o czym mam ochotę :-)
SpeX napisał: 23.06.10 o godzinie 1:43
Wygląda iż pogodynka na podstawie pisemnej zgody udostępnia pogodę. Ale nie wiem jak wygląda pozyskanie takiej zgody.
MariuszT napisał: 23.06.10 o godzinie 2:16
Oni udostępniają tzw. widget z ich logo itd. i raczej tylko na coś takiego może liczyć zwykły Kowalski
info napisał: 23.06.10 o godzinie 2:22
Wojewódzkie sanepidy mają swoje stacje meteo. Ja na swoją stronę dostaję dane właśnie od nich. Zapytałem, zgodzili się (z podaniem źródła).
Kamil napisał: 25.06.10 o godzinie 1:57
Wp udostępnia RSS z pogodą ;> http://rss.wp.pl/s,pogoda,inde.....;_ticrsn=3
Nie chciało mi się czytać regulaminu i nie wiem jak z wykorzystaniem tych informacji.
MariuszT napisał: 25.06.10 o godzinie 2:16
Faktycznie, nie wiedziałem o tym. Może przeoczyłem a może jak kiedyś sprawdzałem to jeszcze nie było. I RSS można wyciągnąć dla każdego miasta, nie tylko dla tych kilkunastu na liście. Trzeba tylko podmienić ID miasta.
I wszystko byłoby pięknie gdyby nie jeden problem. RSS udostępnia dane tylko w postaci kodu HTML, nie ma żadnych danych w XML. A więc i tak trzeba parsować samemu. Jedyna pociecha, że mniejszy plik i mniejsza szansa na pomyłkę. Ale to jednak nadal nie to na czym webmasterom zależy najbardziej…
PS
Poczytam sobie trochę.
Kamil, prowadzisz fajnego bloga
Kamil napisał: 25.06.10 o godzinie 19:08
Dziękuję Mariusz za miłe słowo
Co do samej pogody dorzucę jeszcze jeden link, który może okazać się przydatny:
http://www.programmableweb.com.....at=Weather
Kilka alternatywnych usług sieciowych dla wspomnianego Yahoo Weather
SpeX napisał: 25.06.10 o godzinie 20:45
A jak z poprawnością tych pogód? W szczególności tych zachodnich?
MariuszT napisał: 25.06.10 o godzinie 21:25
Od roku zerkam na wyniki dla Tomaszowa Maz. (dane pobierane dla Łodzi) i najczęściej zgadza się to z tym co mam za oknem. Nie wiem jak jest z innymi miastami czy krajami.
Michał napisał: 04.08.10 o godzinie 13:30
Nagnę trochę i przy okazji spytam się czy używasz GZIP. Zastanawiam się czy się opłaca implementować to w moim cms, bo z transferem krucho
Pozdrawiam
MariuszT napisał: 05.08.10 o godzinie 21:55
Używam. Implementacja to chwila a przynosi zyski.
Zaciekawiony napisał: 02.10.10 o godzinie 10:06
A skąd taka pewnośc ze jak ktoś udostępnia RSS’y to zezwala na ich obróbkę i wykorzystanie!!?? To wzbudza kontrowersjie prawne w naszym karaju.
MariuszT napisał: 02.10.10 o godzinie 13:43
Nie zezwala. To chyba oczywiste. Pisząc o RSS skupiłem się na łatwości pobierania i obróbki takich danych bo artykuł miał być przede wszystkim o technicznych aspektach problemu. Natomiast sprawa zezwoleń, licencji itp. to osobny temat. Mam nadzieję, że każdy ma dość rozumu i wie, że trzeba mieć jakieś pozwolenie/zgodę na wykorzystanie czegokolwiek co jest w internecie.
Fixer napisał: 26.02.11 o godzinie 20:35
Polecam gotowy skrypt PP2XML
http://pp2xml.ogloszenia.devtown.net/
KaRo napisał: 06.03.11 o godzinie 10:38
Czy byłbyś zainteresowany pomocą w opracowaniu pasującego do mojej strony serwisu pogodowego?
Mieszkam całkiem blisko ” . Kod, którego potrzebujemy jest w adresie strony z pogodą dla Łodzi ”
Niestety jestem totalnym laikiem informatycznym,ratuje mnie prosty sposób wstawienia kodu na stronę. Więc jak?
Pozdrawiam serdecznie
MariuszT napisał: 06.03.11 o godzinie 15:16
Ale tu nie ma co opracowywać
Masz podany gotowy kod PHP, wystarczy na weather.yahoo.com znaleźć swoje miasto, skopiować jego kod z adresu i wstawić wszystko do siebie.
KaRo napisał: 06.03.11 o godzinie 22:46
Hej wstawic do siebie mówisz?????
Ale gdzie ? Do skryptu?
Do jakiego katalogu miałabym to wstawić?
Wszystko to dla mnie tabularaza ,nie będę umiała tego zrobić…
No nic dzięki
MariuszT napisał: 06.03.11 o godzinie 23:21
Przykro mi, ten artykuł jest przeznaczony dla programistów.
kolo napisał: 24.03.11 o godzinie 12:28
szkoda tylko , że jest tak mało miast i lokalizacji na Yahoo Weather, nie ma Łowicza…
kolo napisał: 24.03.11 o godzinie 12:44
jaki parametr odpowiada za dodatkowy opis do ciśnienia:
„1,015.92 mb [and steady]” ?
MariuszT napisał: 24.03.11 o godzinie 15:13
Kolo, niestety, miast jest niewiele.
Ciśnienie jest w $weather['astronomy']['pressure'].