top of page
blog_zahlavi_pozadi_00.jpg

Blog

  • Obrázek autoraJan Hora

Lekce 6 – získání externích dat – Kurzy ČNB II

V minulé lekci jsme si připravili samostatný skript, tabulku pro data a napsali funkci pro vytvoření listu s názvem aktuálního dne. Teď se pustíme do získání kurzů z ČNB.

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:



Po kliknutí na odkaz zjistíte, že vypíše kurzy z 30.8.2019. Je to proto, že 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ěč.

Ještě si můžeme ručně vyzkoušet různé tvary data 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.


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 || kurzy_url;

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.

První řádek

var url = url || kurzy_url;

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 (nebo), čili řádek znamená: do proměnné url ulož hodnotu, která došla jako první parametr a pokud parametr url není definovaný, ulož tam hodnotu globální proměnné kurzy_url.

Obdobně další řádek do proměnné datum uloží parametr datum nebo text ’01.09.2019';

K čemu je to dobré? Ukážeme si, 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. Druhou možností je napsat si funkci, která naši funkci nacti_data_z_cnb s potřebnými parametry zavolá, třeba takto.


function test_cteni(){

nacti_data_z_cnb(kurzy_url, '01.09.2019')

}

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. Její pomocí 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 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 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ě byste měli vidět něco podobného jako na tomto obrázku.



Program zastavil na řádku 67 a v dolní části máme vypsané hodnoty všech proměnných. Můžeme tak zkontrolovat, že máme správně nastavené hodnoty pro url, datum nebo url_cele. Hodnota proměnné 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 67 a 68 a při dalším zastavení na řádku 69 by to mělo vypadat nějak takto.


Program zastavil na řádku 69, kde už jen vrací výsledek. 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 u proměnné data máme typ String. Vidíme sice jen začátek obsahu, nicméně vypadá to na začátek kurzovního lístku, tak jak jsme si ho ukazovali na začátku. Takže metodu resp.getContentText() jsme použili správně a máme text obsahující kurzovní lístek, který funkce vrátí. Můžeme ukončit krokování a pokročit dál.

Ve skutečné aplikaci bychom ještě museli ošetřit 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 si získaná data zpracujeme, uložíme do tabulky a nastavíme si automatické stahování přes časový spouštěč.

bottom of page