2021-04-12

Kā iegūt bulk meteodatus no meteo.lv

 

Darbam ar meteo.lv datiem

Izvēlies staciju, izvēlies parametrus, izvēlies laika intervālu (sākuma un beigu gadus) un dari ar datiem, ko vēlies.

Staciju ID

30000 : Ainaži

30004 : Alūksne

30011 : Bauska

10000120 : Dagda

30018 : Dagda

30021 : Daugavpils

30022 : Dobele

30034 : Gulbene

30036 : Jelgava

30040 : Kalnciems

30046 : Kolka

30048 : Kuldīga

30058 : Lielpeči

30060 : Liepāja

10000118 : Liepāja piekraste

30068 : Madona

30072 : Mērsrags

30081 : Piedruja

30087 : Priekuļi

30080 : Pāvilosta

30099 : Rucava

10000180 : Rēzekne

30092 : Rēzekne

30094 : Rīga

30096 : Rīga - Universitāte

30100 : Rūjiena

30102 : Saldus

30103 : Sigulda

30105 : Skrīveri

30106 : Skulte

30111 : Stende

30104 : Sīļi

30128 : Ventspils

30132 : Vičaki

30141 : Zosēni

30140 : Zīlāni

parametru ID

4514 : Aramkārtas temperatūra 10 cm dziļumā, faktiskā

4515 : Aramkārtas temperatūra 15 cm dziļumā, faktiskā

4516 : Aramkārtas temperatūra 20 cm dziļumā, faktiskā

4513 : Aramkārtas temperatūra 5 cm dziļumā, faktiskā

4167 : Atmosfēras spiediens stacijas līmenī, faktiskais

4457 : Augsnes virsmas stāvoklis

4459 : Augsnes virsmas temperatūra, faktiskā

4464 : Augsnes virsmas temperatūra, stundas maksimālā

4462 : Augsnes virsmas temperatūra, stundas minimālā

4327 : Augšējo mākoņu forma

4001 : Gaisa temperatūra, faktiskā

4008 : Gaisa temperatūra, maksimālā iepriekšējo 3 stundu laikā

4003 : Gaisa temperatūra, minimālā iepriekšējo 3 stundu laikā

4006 : Gaisa temperatūra, stundas maksimālā

4004 : Gaisa temperatūra, stundas minimālā

4002 : Gaisa temperatūra, stundas vidējā

4321 : Kopējais mākoņu daudzums

10307 : Laika apstakļi 1. kods pēdējā 1 stundā;A

10308 : Laika apstakļi 2. kods pēdējā 1 stundā;A

10306 : Laika apstakļi, faktiskie;A

4627 : Laika apstākļi novērojumu termiņā

4676 : Meteoroloģiskā redzamība

9954 : Meteoroloģiskā redzamība faktiskā

4674 : Meteoroloģiskā redzamība, stundas maksimālā

4672 : Meteoroloģiskā redzamība, stundas minimālā

4494 : Minimālā temperatūra zāles augstumā

4323 : Mākoņu augstums

10193 : Mākoņu augstums 1

10194 : Mākoņu augstums 2

10195 : Mākoņu augstums 3

10196 : Mākoņu daudzums 1

10197 : Mākoņu daudzums 2

10198 : Mākoņu daudzums 3

9536 : Nokrišņu daudzums 10 minūšu laika intervālā

4568 : Nokrišņu daudzums starp termiņiem

4570 : Nokrišņu daudzums, stundas summa

4628 : Pagājušie laika apstākļi 1

4629 : Pagājušie laika apstākļi 2

4224 : Piekrastes vēja brāzmas, stundas maksimālās

4317 : Piekrastes vēja virziens, faktiskais

4220 : Piekrastes vēja ātrums, faktiskais

4223 : Piekrastes vēja ātrums, stundas minimālās

4670 : Redzamība jūras virzienā

4080 : Relatīvais mitrums, faktiskais

4084 : Relatīvais mitrums, stundas maksimālais

4082 : Relatīvais mitrums, stundas minimālais

4606 : Saules spīdēšanas ilgums, stundas summa

4342 : Sniega segas biezums

4341 : Sniega segas biezums, stundas vidējais

4343 : Sniega segas biezums, termiņā 18

4344 : Sniega segas seguma pakāpe stacijas apkārtnē

4530 : Summārā radiācija, stundas maksimālā

4528 : Summārā radiācija, stundas minimālā

4527 : Summārā radiācija, stundas vidējā

10188 : Temperatūra zem dabiskās veģetācijas virsmas 0.1 m dziļumā, faktiskā

4495 : Temperatūra zem dabiskās veģetācijas virsmas 0.2 m dziļumā, faktiskā

4496 : Temperatūra zem dabiskās veģetācijas virsmas 0.4 m dziļumā, faktiskā

4497 : Temperatūra zem dabiskās veģetācijas virsmas 0.8 m dziļumā, faktiskā termiņā 12

10253 : Temperatūra zem dabiskās veģetācijas virsmas 1.6 m dziļuma, faktiskā

4499 : Temperatūra zem dabiskās veģetācijas virsmas 1.6 m dziļumā, faktiskā termiņā 12

4500 : Temperatūra zem dabiskās veģetācijas virsmas 3.2 m dziļumā, faktiskā termiņā 12

9880 : Temperatūra zāles augstumā, faktiskā

9883 : Temperatūra zāles augstumā, stundas maksimālā

9881 : Temperatūra zāles augstumā, stundas minimālā

9884 : Temperatūra zāles augstumā, stundas vidējā

10254 : Temperatūras zem dabiskās veģetācijas virsmas 3.2 m dziļuma, faktiskā

10252 : Temperatūta zem dabiskās veģetācijas virsmas 0.8 m dziļuma, faktiskā

4544 : Ultravioletā radiācija, stundas maksimālā

4542 : Ultravioletā radiācija, stundas minimālā

4541 : Ultravioletā radiācija, stundas vidējā

4330 : Vidējo mākoņu forma

4212 : Vēja brāzmas, maksimālās starp termiņiem

4218 : Vēja brāzmas, stundas maksimālās

10208 : Vēja virziens, faktiskais (10 minūšu vidējais)

4313 : Vēja virziens, faktiskais (2 minūšu vidējais)

4211 : Vēja ātrums, faktiskais

4216 : Vēja ātrums, stundas minimālais

4322 : Zemo mākoņu daudzums

4324 : Zemo mākoņu forma

In [1]:
import requests as reqs
from requests.packages.urllib3.exceptions import InsecureRequestWarning
reqs.packages.urllib3.disable_warnings(InsecureRequestWarning)

Tā kā meteo.lv ir https, tad, veidojot zināmu pieprasījumu, ignorēsim zināmu pieprasījumu.

In [2]:
sc="https://www.meteo.lv/josso_security_check"
sec_check=reqs.post(sc)
cookies=sec_check.cookies.get_dict()
cookies["JSESSIONID"]
Out[2]:
'DB28619DC4248262E9EEDFFEA023CFAB'

Lai varētu lejuplādēt datus, nepieciešams cookie ar nosaukumu JSESSIONID. No pārlūka atverot datu meklēšanas lapu, tiek izveidots redirekts uz šo un atpakaļ uz datu meklēšanas lapu.

Tālāk jāsagatavo pieprasījums.

  1. Būs vajadzīga adrese url
  2. Būs nepieciešamas vismaz dažas lietas iekš header
In [3]:
url="https://www.meteo.lv/meteorologija-datu-meklesana/?"

headers={
"Content-Type":"application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Referer": "https://www.meteo.lv/meteorologija-datu-meklesana/?nid=461",
"Cookie": "JSESSIONID="+cookies["JSESSIONID"]
}

Noderīgi būs arī izveidot datu nosaukumu sarakstus. Tie sevī ietver novērojumu staciju nosaukumus un parametru nosaukumus

In [4]:
import json
saraksts=reqs.get("https://www.meteo.lv/klasifikatoru-filtrs/?iBy=station&iStation=&iParameter=4001&pMonitoringType=METEOROLOGY")
saraksts= json.loads(saraksts.text)

Var redzēt, ka klasifikatoru sarakstu var iegūt pēc pieprasījuma, norādot, piemēram, parametra id. Tiks nofiltrētas tās stacijas, kurās tiek veikts šī parametra mērījums.

In [5]:
stacijuSaraksts={}
for each in saraksts["stations"][1:]:
    stacijuSaraksts[each["id"]]=each["name"]

parametruSaraksts={}
for each in saraksts["parameters"][1:]:
    parametruSaraksts[each["id"]]=each["name"]

Tiek izveidotas vārdnīcas, kuras saturēs staciju un parametru nosaukumus - vēlāk būs ērti strādāt ciklā un glabāt failus, to nosaukumos norādot šo info.

Šajā brīdī viss ir sagatavots un var palaist galveno ciklu. Jānorāda stacijas ID, parametra ID, kā arī laika periods - sākuma un beigu gads.

In [7]:
####
stationID=30022
paramID=4001
startYear=2016
endYear=2020
####


for year in range(startYear,endYear+1):
    StartDate="01.01."+str(year)
    EndDate="31.12."+str(year)
    params="iBy=station&nid=461&pMonitoringType=METEOROLOGY&iStation="+str(stationID)+"&iParameter="+str(paramID)+"&iDateFrom="+StartDate+"&iDateTill="+EndDate
    fname=stacijuSaraksts[str(stationID)]+"_" \
    +parametruSaraksts[str(paramID)] + "_" \
    +StartDate+"-" \
    +EndDate+".xls"
    print(fname)
    
    result=reqs.post(url,verify=False,data=params, headers=headers)
    with open(fname, 'wb') as f:
        f.write(result.content)
Dobele_Gaisa temperatūra, faktiskā_01.01.2016-31.12.2016.xls
Dobele_Gaisa temperatūra, faktiskā_01.01.2017-31.12.2017.xls
Dobele_Gaisa temperatūra, faktiskā_01.01.2018-31.12.2018.xls
Dobele_Gaisa temperatūra, faktiskā_01.01.2019-31.12.2019.xls
Dobele_Gaisa temperatūra, faktiskā_01.01.2020-31.12.2020.xls

Darbs ar saglabātajiem failiem

Saglabātos failus būtu vērts apvienot. Lai to izdara pandas.

In [8]:
import pandas as pd
In [12]:
####
stationID=30022
paramID=4001
startYear=2016
endYear=2020
####

df=[]

for enum, year in enumerate(range(startYear,endYear+1)):
    StartDate="01.01."+str(year)
    EndDate="31.12."+str(year)
    fname=stacijuSaraksts[str(stationID)]+"_" \
    +parametruSaraksts[str(paramID)] + "_" \
    +StartDate+"-" \
    +EndDate+".xls"
    #df[enum]=pd.read_excel(fname)
    df.append(pd.read_excel(fname,skiprows=1,parse_dates=["Datums \ Laiks"],index_col=0,dayfirst=True))
    df[enum]["vidējā"]=df[enum].mean(axis=1)
    #df[enum]["summa"]=df[enum].sum(axis=1)
    
    

Ciklā tiek norādīti tie faili, no kuriem vajag apvienot datus, balstoties uz to nosaukumu, kas sastāv no stacijas, parametra un gadiem. Ir izveidots mainīgais df, kas ir masīvs un satur visas pandas tabulas. Pie reizes arī aprēķināta visu rindu vidējā vērtība (šajā piemērā - dienas vidējā temperatūra)

ar pandas.concat() palīdzību šis masīvs tiek apvienots vienā kopējā datu tabulā dataf

In [13]:
dataf=pd.concat(df)
In [14]:
dataf
Out[14]:
00:0001:0002:0003:0004:0005:0006:0007:0008:0009:00...15:0016:0017:0018:0019:0020:0021:0022:0023:00vidējā
Datums \ Laiks
2016-01-01-14.5-12.9-12.5-11.6-11.1-10.8-11.0-11.0-10.5-10.0...-8.9-9.2-9.3-9.1-9.1-9.2-9.4-9.8-11.5-10.183333
2016-01-02-13.9-14.6-15.1-15.7-16.0-16.4-16.9-16.9-17.0-16.7...-14.9-15.5-16.9-16.6-16.7-17.0-17.2-17.4-18.6-16.208333
2016-01-03-19.6-19.4-20.8-20.4-20.5-18.3-16.8-14.7-13.1-11.5...-8.8-8.3-8.3-8.4-8.4-8.3-8.0-7.4-7.1-12.404167
2016-01-04-6.8-6.7-7.3-7.2-7.4-6.5-6.4-7.0-9.2-10.0...-9.7-9.9-10.0-10.2-10.5-10.6-10.9-11.1-11.2-8.983333
2016-01-05-11.3-11.4-11.6-12.9-14.0-14.1-15.5-14.5-13.6-14.8...-13.0-14.0-13.1-13.7-15.7-16.9-17.6-18.2-18.9-14.187500
..................................................................
2020-12-27-1.0-1.1-1.6-0.9-0.7-0.6-0.7-1.2-0.7-0.5...-0.7-0.9-1.2-1.2-1.1-1.0-1.4-1.5-1.9-0.891667
2020-12-28-2.0-2.3-2.5-2.4-2.0-2.4-2.2-1.7-1.2-0.4...1.21.00.60.81.11.41.11.21.4-0.250000
2020-12-291.41.61.81.71.91.92.01.81.91.9...1.92.01.91.01.00.71.82.43.11.775000
2020-12-300.92.73.43.23.33.53.73.53.02.1...2.01.40.90.30.10.50.91.91.92.250000
2020-12-311.81.81.71.51.51.31.11.41.11.3...1.71.61.50.70.4-0.8-1.0-1.0-1.20.941667

1793 rows × 25 columns

In [16]:
dataf=dataf[["vidējā"]]

Saglabāsim tikai visu rindu vidējo vērtību un saglabāsim to excel failā.

In [17]:
fname2=stacijuSaraksts[str(stationID)]+"_" \
    +parametruSaraksts[str(paramID)] + "_" \
    +str(startYear)+"-" \
    +str(endYear)+".xls"
dataf.to_excel(fname2)
In [18]:
fname2
Out[18]:
'Dobele_Gaisa temperatūra, faktiskā_2016-2020.xls'
In [ ]:
 

2 komentāri:

  1. Kā ielikt pārbaudi, ja mērījumi par konkrēto gadu nav veikti? Tā vietā skripts lejupielādē HTML lapu un kļūdaini to saglabā xls.

    AtbildētDzēst
    Atbildes
    1. Es to droši vien darītu 7.solī pēc šīs rindiņas "result=reqs.post(url,verify=False,data=params, headers=headers)". Mainīgais result vai nu ir html lapa vai arī dati. Tām HTML lapām., kuras ielādējas, ja datu nav, ir līdzīga vai pat identiska struktūra un saturs. Ja ir identiska, tad var iepriekš noskaidrot hash struktūrai, kas raksturo to html lapu un vienmēr lejuplādējot saturu aprēķinātu tā hash un salīdzinātu. ja sakrīt, tad datu nav bet ir html lapa, kas būtu jāignorē. Bet ja pieprasījumu dēļ lapā būs atšķirības, tad hash nestrādās. Tas būs unikāls konkrētajam saturam. Tad droši vien ar kādas html bibliotēkas palīdzību mēģinātu noskaidrot, vai iegūtais saturs ir līdzīgs, atbilstošs html lapai. ja ir, tad neder. Kaut kā tā, bet neesmu mēģinājis.

      Dzēst