Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Języki skryptowe na co dzień | cz. 4. | mała stacja meteo

Kolejny skrypt również został przygotowany w pythonie. Ma on na celu pobranie strony internetowej, a następnie przeszukanie jej zawartości, pod kątem interesujących nas informacji pogodowych. Po czym, tak wyodrębnione dane zostaną wyświetlone na ekranie.

Do realizacji tego celu skorzystam ze strony http://www.meteoprog.pl/pl/. Dla przykładu, pogodę dla Leszna znajdziemy pod adresem: http://www.meteoprog.pl/pl/weather/Leszno/

Oto kod skryptu a poniżej jego omówienie:

import urllib, re, time www = urllib.urlopen('http://www.meteoprog.pl/pl/weather/Leszno/') www_tekst = www.read() wyrazenie = '<meta property="og:description" content="(.+?)" />' pogoda = re.findall(wyrazenie, www_tekst) wyrazenie2 = 'd</span><span class="colorNoBold">(.+?)</span>' wschodzachod = re.findall(wyrazenie2, www_tekst) print time.strftime("%Y-%m-%d, %H:%M:%S") print '=' * 20 print pogoda[0] print u'Wsch\u00f3d S\u0142o\u0144ca:', wschodzachod[0] print u'Zach\u00f3d S\u0142o\u0144ca:', wschodzachod[1]

W pierwszej kolejności zostały zaimportowane moduły, odpowiedzialne za: pobieranie informacji z internetu (urllib), obsługę wyrażeń regularnych (re), obsługę czasu (time).

Następnie, z określonego wcześniej adresu została pobrana strona (jako plik) i zapisana wpamięci po nazwą www. Następnie z pobranej strony został wyodrębniony cały tekst i przypisany, jako ciąg znaków do zmiennej www_tekst.

W dalszej kolejności ze źródła strony (w Firefox, na aktualnie otwartej stronie: prawy przycisk myszki › Pokaż źródło strony) zostały wyodrębnione ciągi znaków i zapisane pod nazwą wyrazenie, a potem wyrazenie2. W tych ciągach znajdują się dane pogodowe (aktualna temperatura i informacja o zachmurzeniu oraz godzina wschodu i zachodu Słońca).

Oczywiście te dane, ulegają zmianie ale można już wyodrębnić pozostałą część ciągu, która się nie zmienia. Do uzyskania zmieniających się danych zawartych pomiędzy niezmiennymi ciągami znaków zostały użyte tzw. wyrażenia regularne. Interesujące dane pogodowe w wybranym wcześniej ciągu znaków są odnajdywane za pomocą następujących symboli (w nawiasie): (.+?). Oznaczają one: "." (kropka) zastępuje dowolny jeden znak, a znak "+" (plus) oznacza, że poprzedzający go (dowolny) znak musi wystąpić min. raz. Odczytując teraz razem te dwa znaki, mamy: odszukaj dowolny ciąg znaków, który jest złożony z jednego lub większej ilości znaków. Na końcu znajduje się "?" (znak zapytania), który czyni z naszego wyrażenia regularnego, wyrażenie leniwe. Oprócz leniwych, istnieją również zachłanne (bez znaku zapytania). W skrócie, chodzi o to, że wyrażenia zachłanne w niektórych sytuacjach, mogą pobrać zbyt dużo danych, na których nam nie zależy.

findall z modułu re przeszukuje zawartość ściągniętej strony w poszukiwaniu wystąpień wyżej zadeklarowanego wyrażenia regularnego (wyrazenie). Znalezione wystąpienia (może być ich więcej niż jedno) są dopisywane do listy, czyli odpowiednika tablicy w innych językach programowania.

W ten sam sposób są pobierane kolejne informacje dot. wschodu i zachodu Słońca, znajdujące się w innej części treści ściągniętej strony. Z tego powodu, trzeba przygotować kolejny wzór do wyszukiwania (wyrazenie2). Tym razem można skorzystać z jednego wyrażenia, do pobrania czasu wschodu i zachodu Słońca. Zostaną one zapisane pod kolejnymi indeksami [0,1] w liście wschodzachod.

Ostatnia część skryptu, to wyświetlenie aktualnej daty i czasu oraz zebranych informacji pogodowych. Należy pamiętać, że pogoda i wschodzachod to są listy, do zawartości których, trzeba się odwołać podając odpowiedni indeks. Odwołujemy się do nich: pogoda[0], wschodzachod[0] i wschodzachod[1], ponieważ - w tym przykładzie - pod takimi adresami zapisane są interesujące nas dane.

Pod Symbianem również działa:

W kodzie źródłowym dla wersji na telefon dodana została część związana z odpowiednim kodowaniem znaków oraz kilka linijek związanych z wyświetlaniem informacji (w trybie konsolowym) na ekranie telefonu:

import urllib, re, time print '\n' * 14 print 'Pobieram dane...' www = urllib.urlopen('http://www.meteoprog.pl/pl/weather/Leszno/') www_tekst = www.read() wyrazenie = '<meta property="og:description" content="(.+?)" />' pogoda = re.findall(wyrazenie, www_tekst) wyrazenie2 = 'd</span><span class="colorNoBold">(.+?)</span>' wschodzachod = re.findall(wyrazenie2, www_tekst) print '\n' * 14 print time.strftime("%Y-%m-%d, %H:%M:%S") print '=' * 17 print pogoda[0].decode('utf8') print u'Wsch\u00f3d S\u0142o\u0144ca:', wschodzachod[0].decode('utf8') print u'Zach\u00f3d S\u0142o\u0144ca:', wschodzachod[1].decode('utf8') print '\n' * 7

W podobny sposób możemy "wyciągać" ze stron różne informacje a nawet pliki. Jeśli więc, np. jakaś aplikacja na telefon nam nie odpowiada albo po prostu jej nie ma, możemy samodzielnie taką stworzyć i dostosować pobierane dane do własnych potrzeb.

Dodatek

Po małych modyfikacjach, możemy uzyskać informację o ilości komentarzy do poszczególnych artykułów na blogu DP. W kodzie, w miejsce nazwy użytkownika (entat) trzeba wpisać swoją.

import urllib, re, time www = urllib.urlopen('http://www.dobreprogramy.pl/entat') www_tekst = www.read() wyrazenie = '<span style="display:block;" class="text-h0">(.+?)</span>' ilosc_komentarzy = re.findall(wyrazenie, www_tekst) ilosc_wpisow = len(ilosc_komentarzy) wyrazenie2 = '.html">(.+?)</a></h1>' tytul = re.findall(wyrazenie2, www_tekst) print time.strftime("%Y-%m-%d, %H:%M:%S") print '=' * 20 for n in range(ilosc_wpisow): print tytul[n]+':', ilosc_komentarzy[n]

Pozdrawiam. 

linux porady programowanie

Komentarze

0 nowych
  #1 23.02.2014 23:06

Te regexpy wyglądają nawet ładniej niż beautifulsoup :-)

kwpolska   6 #2 24.02.2014 12:23

> www = urllib.urlopen('http://www.meteoprog.pl/pl/weather/Leszno/')

pip install requests

> wyrazenie = ''
> wyrazenie2 = 'd(.+?)'

http://stackoverflow.com/a/1732454

> print u'Wsch\u00f3d S\u0142o\u0144ca:', wschodzachod[0]
> print u'Zach\u00f3d S\u0142o\u0144ca:', wschodzachod[1]

Łojezu, zapisuj jako UTF-8 i nie kombinuj!

Jim1961   7 #3 24.02.2014 18:28

Polecam serwis openweathermap.org, nie trzeba niczego parsować. Przykładowy JSON dla Leszna:
http://api.openweathermap.org/data/2.5/weather?q=Leszno,pl&lang=pl_pl
W celach edukacyjnych, mogą być wyrażenia :)

  #4 25.02.2014 04:08

kwpolska: Przerost formy nad treścią. Po pierwsze ma działać.
W społeczności Pythona zawsze panowała liberalność rozwiązań. Różne frustracje i inne "łojezu" chrakteryzują raczej ludzi z PHP. Oni muszą ze sobą konkurować, więc wmawiają wszystkim jacy to inni są źli i do dupy.

Python to jeden z tych języków pozwalający na każdym etapie edukacji stworzyć każde rozwiązanie. Więc nie ma co hejtować. Każdy dorośnie do tego co dla niego najwygodniejsze ucząc się na własnych błędach. Zatem miej miłe uczucia dla ludzi, choćby pisali system widgetów html, zamiast użyć systemu szablonów.

entat   6 #5 25.02.2014 10:14

@Jim1961 - o openweathermap.org nie słyszałem. Fajnie, że jest taki serwis - z pewnością wykorzystam:)

@kwpolska, tak wiem, że można inaczej...

entat   6 #6 25.02.2014 19:56

@ sprae (niezalogowany)
Jeśli chodzi o beautifulsoup, to nie miałem jeszcze styczności z tą biblioteką:) Póki regex spełnia swoją rolę, to z niego korzystam (@kwpolska). Jak dla mnie, to fajna sprawa z tym wyciąganiem danych z różnych miejsc w sieci. Szczególnie, jeśli chodzi o wykorzystanie dosyć leciwego telefonu, na którego już ciężko znaleźć oprogramowanie;)

Pozdrawiam.