Lekce 6 - Google Apps Script - Získání externích dat - Kurzy ČNB II
V minulé lekci, Google Apps Script - Získání externích dat - Kurzy ČNB I, jsme si připravili samostatný skript, tabulku pro data a napsali funkci pro vytvoření listu s názvem aktuálního dne.
Získání kurzů ČNB pro dnešní den
Dnešní kurzy devizového trhu ve tvaru vhodném pro zpracování programem nabízí ČNB na této stránce.
Pokud potřebujeme kurzy za jiný než aktuální den, doplníme na konec
adresy ještě parametr ?date=
, doplněný datem, které nás
zajímá. Např. pro kurzy ze dne 1.9.2019 bude celá adresa vypadat takto:
https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.txt?date=01.09.2019
Ještě si můžeme ručně vyzkoušet různé tvary datumu a snadno
zjistíme, že funguje i tvar 1.9.2019
, přestože ČNB píše, že
den a měsíc má být na 2 znaky.
O víkendech se kurzy nevyhlašují, proto nám pro sobotu a neděli ČNB vrátí páteční kurz. A ještě drobnost, i v pondělí dopoledne nám stránka bude vracet páteční kurz, protože ČNB aktualizuje kurzy v pracovní dny po 14:30, jak se můžete dočíst na této stránce.
Na to budeme muset pamatovat, až budeme zakládat náš časový spouštěč.
Stejně jako id tabulky si i adresu serveru ČNB uložíme do globální proměnné, takže začátek našeho skriptu bude vypadat takto:
var table_id = 'tady_bude_id_vasi_tabulky'; var kurzy_url = 'https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.txt';
Pokud si adresu otevřeme v prohlížeči, ukáží se nám kurzy v tomto tvaru:
Vidíte, že jde o jednoduchý textový formát, žádné XML nebo podobné složitosti. Z prvního řádku můžeme získat datum, abychom kurzy zapsali na správný list tabulky a také ověřili, že nám ČNB vrátila kurz, který nás zajímá.
Všechny další řádky náš program jednoduše projde a obsah každého
řádku rozdělí na části podle znaku |
. Tím získá data ve
tvaru vhodném pro zápis do tabulky.
Načtení dat
Pro vlastní načtení dat z ČNB si napíšeme tuto funkci:
function nacti_data_z_cnb(url, datum) { var url = url || 'https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.txt'; var datum = datum || '01.09.2019'; var url_cele = url + '?date=' + datum; var resp = UrlFetchApp.fetch(url_cele); var data = resp.getContentText(); return data; }
Nyní si ji trochu vysvětlíme. Vidíme, že funkce má 2 vstupní
parametry: url
a datum
. Parametr url
je
základní adresa stránky ČNB a datum
je text ve tvaru
DD.MM.RRRR.
Další řádek:
var url = url || 'https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.txt';
nám možná přijde nesmyslný. Proč na něm definujeme proměnnou
url
, když ta by měla být jako vstupní parametr. A k čemu je
tam operátor ||
?
Operátor ||
je logický operátor OR, čili
řádek znamená: "do proměnné url
ulož hodnotu
url
, která došla jako první parametr a pokud parametr
url
není definovaný, ulož tam text
'https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.txt'
".
Obdobně další řádek do proměnné datum
uloží parametr
datum
nebo text '01.09.2019'
;
K čemu je to dobré? To si za chvíli ukážeme na příkladu, jak je
možné v Apps Scriptu funkce krokovat a hledat v nich chyby. Při těchto
pokusech budeme funkci spouštět ručně přímo v editoru a v té chvíli
žádné parametry url
a datum
nedostane. Proto si je
ve funkci nastavíme tímto způsobem.
Na dalším řádku:
var url_cele = url + '?date=' + datum;
si jen sestavíme výslednou adresu, kterou budeme volat. Pro komunikaci s
libovolnou externí adresou slouží v Apps Scriptu knihovna
UrlFetchApp
. Pomocí ní můžeme data jak přijímat, tak i
odesílat.
Řádek:
var resp = UrlFetchApp.fetch(url_cele);
tedy zavolá externí adresu a do proměnné resp
uloží
výsledek. Nebudou to zatím přímo naše kurzy, ale objekt třídy
HTTPResponse
, zjednodušeně řečeno kompletní odpověď serveru
ČNB.
Z objektu resp
nyní potřebujeme získat naše kurzy. Obecně
může mít odpověď serveru nejrůznější formát, může to být obrázek,
text, XML a podobně. Podle toho je poté třeba odpověď zpracovat.
Víme, že v našem případě by odpověď měl být prostý text, takže ho
zkusíme z objektu získat metodou resp.getContentText()
a
uložíme ho do proměnné data
, kterou na posledním řádku
funkce vrátí.
Krokování
A teď si zkusíme slibované krokování. V menu editoru vybereme volbu Spustit, uvidíme tam tuto nabídku:
Pod Spustit funkci a Ladit funkci uvidíme
stejný seznam všech funkcí, které máme v souboru Kód.gs
napsaný. Rozdíl je v tom, že Spustit funkci pouze provede,
kdežto Ladit nám umožní její provádění zastavit a pak v
něm opět pokračovat.
Úplně stejně jako přes menu můžeme funkci vybrat na liště pod menu, jako to vidíte na obrázku:
Kliknutím myši na číslo řádku si ještě vložíme místa, kde chceme provádění funkce zastavit. Místo je označené červenou tečkou, další klik ji zase smaže.
Kliknutím na ikonu brouka zkusíme spustit ladění funkce. Po zastavení funkce na prvním bodě (u mě je to řádek 48) byste měli vidět něco podobného jako na obrázku níže:
Vidíme, že ve výpisu proměnných máme správně nastavené hodnoty pro
url
, datum
nebo url_cele
, ale hodnota
resp
je undefined
.
Je to z toho důvodu, že program zastaví na konkrétním řádku před jeho vlastním provedením. Pokud klikneme na ikonu pro pokračování ladění, měly by se provést řádky 48 a 49 a celé by to mělo vypadat nějak takto:
Vidíte, že program zastavil na řádku 50. O odpovědi serveru, která je v
proměnné resp
, se tu nic zajímavého nedozvíme. Vidíme jen,
že je to jakýsi objekt.
Naproti tomu v proměnné data
vidíme začátek kurzovního
lístku, takže metodu resp.getContentText()
jsme použili
správně a máme řetězec obsahující kurzovní lístek. Ukončíme
krokování a můžeme pokročit dál.
Ve skutečné aplikaci bychom ještě nějak museli ošetřit i stav, kdy server ČNB odpoví za dlouhou dobu, neodpoví vůbec, pošle něco jiného než kurzovní lístek a podobně. V našem ukázkovém příkladu to zatím zanedbáme.
V příští lekci, Google Apps Script - Získání externích dat - Kurzy ČNB III, si popíšeme získání surových dat kurzovních lístků z ČNB a ukážeme si, jak funkce v Apps Scriptu krokovat a hledat v nich chyby.