Webové API

Jak už bylo řečeno v lekci o JSON, hlavní výhoda formátu JSON je, že se na Internetu rozšířil nejvíc. Pojďme toho využít!

Spousta webových služeb poskytuje takzvané API (z application programming interface, programátorské rozhraní), přes které je možné s danou službou komunikovat programově. Místo klikání na tlačítka a čtení stránek „očima” dostaneme data ve formátu, kterým rozumí počítače – a v dnešní době to bude většinou formát JSON.

Requests

K práci s internetovými stránkami použijeme knihovnu Requests. V aktivovaném virtuálním prostředí si ji nainstaluj příkazem:

(env)$ python -m pip install requests

A potom v Pythonu zkus stáhnout nějakou stránku:

import requests

# stažení stránky
stranka = requests.get('https://cs.wikipedia.org', timeout=5)

# ověření, že dotaz proběhl v pořádku
stranka.raise_for_status()

# vypsání obsahu
print(stranka.text)

Měl by se vypsat obsah stránky https://cs.wikipedia.org – HTML kód, který se objeví když v prohlížeči dáš „Ukázat zdroj” (View Page Source, většinou Ctrl+U) a ze kterého prohlížeč umí vykreslit stránku.

Ale my nechceme obsah pro lidi. Podívejme se, co Wikipedia zpřístupňuje počítačům.

Data pro strojové zpracování

Nyní si načteme stránku, která nám vrátí výsledek v JSON:

import requests

# klíčové slovo, podle kterého budeme vyhledávat
klic = 'Vánoce'

# stažení stránky
stranka = requests.get('https://cs.wikipedia.org/w/api.php?action=query&prop=extracts&explaintext&exintro&format=json&titles={}'.format(klic), timeout=5)

# ověření, že dotaz proběhl v pořádku
stranka.raise_for_status()

# vypsání obsahu
print(stranka.text)

Na náš dotaz Wikipedia vrátí základní informace o zadaném vyhledávacím klíči v JSONU.

Zkus řetězec stranka.text převést z JSON na slovník a vypsat trochu srozumitelněji:

import json

# Převedeme do Pythoních struktur
data = json.loads(stranka.text)

# vypíšeme s odsazením 
print(json.dumps(data, ensure_ascii=False, indent=2))
{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2018/pyladies-hradec-podzim:dict:2",
      "title": "Web API",
      "html": "\n          \n    \n\n    <h1>Webov&#xE9; API</h1>\n<p>Jak u&#x17E; bylo &#x159;e&#x10D;eno v&#xA0;<a href=\"/2018/pyladies-hradec-podzim/intro/json/\">lekci o JSON</a>,\nhlavn&#xED; v&#xFD;hoda form&#xE1;tu JSON je, &#x17E;e se na Internetu roz&#x161;&#xED;&#x159;il nejv&#xED;c.\nPoj&#x10F;me toho vyu&#x17E;&#xED;t!</p>\n<p>Spousta webov&#xFD;ch slu&#x17E;eb poskytuje takzvan&#xE9;\n<em>API</em> (z&#xA0;<em>application programming interface</em>,\nprogram&#xE1;torsk&#xE9; rozhran&#xED;), p&#x159;es kter&#xE9; je mo&#x17E;n&#xE9; s danou\nslu&#x17E;bou komunikovat programov&#x11B;.\nM&#xED;sto klik&#xE1;n&#xED; na tla&#x10D;&#xED;tka a &#x10D;ten&#xED; str&#xE1;nek &#x201E;o&#x10D;ima&#x201D;\ndostaneme data ve form&#xE1;tu, kter&#xFD;m rozum&#xED; po&#x10D;&#xED;ta&#x10D;e &#x2013;\na v&#xA0;dne&#x161;n&#xED; dob&#x11B; to bude v&#x11B;t&#x161;inou form&#xE1;t JSON.</p>\n<h2>Requests</h2>\n<p>K pr&#xE1;ci s internetov&#xFD;mi str&#xE1;nkami pou&#x17E;ijeme knihovnu Requests.\nV aktivovan&#xE9;m virtu&#xE1;ln&#xED;m prost&#x159;ed&#xED; si ji nainstaluj p&#x159;&#xED;kazem:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">(env)$ </span>python -m pip install requests\n</pre></div><p>A potom v Pythonu zkus st&#xE1;hnout n&#x11B;jakou str&#xE1;nku:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">requests</span>\n\n<span class=\"c1\"># sta&#x17E;en&#xED; str&#xE1;nky</span>\n<span class=\"n\">stranka</span> <span class=\"o\">=</span> <span class=\"n\">requests</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&apos;https://cs.wikipedia.org&apos;</span><span class=\"p\">,</span> <span class=\"n\">timeout</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># ov&#x11B;&#x159;en&#xED;, &#x17E;e dotaz prob&#x11B;hl v po&#x159;&#xE1;dku</span>\n<span class=\"n\">stranka</span><span class=\"o\">.</span><span class=\"n\">raise_for_status</span><span class=\"p\">()</span>\n\n<span class=\"c1\"># vyps&#xE1;n&#xED; obsahu</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">stranka</span><span class=\"o\">.</span><span class=\"n\">text</span><span class=\"p\">)</span>\n</pre></div><p>M&#x11B;l by se vypsat obsah str&#xE1;nky\n<a href=\"https://cs.wikipedia.org\">https://cs.wikipedia.org</a> &#x2013;\nHTML k&#xF3;d, kter&#xFD; se objev&#xED; kdy&#x17E; v prohl&#xED;&#x17E;e&#x10D;i d&#xE1;&#x161;\n&#x201E;Uk&#xE1;zat zdroj&#x201D; (<em>View Page Source</em>, v&#x11B;t&#x161;inou <kbd>Ctrl</kbd>+<kbd>U</kbd>)\na ze kter&#xE9;ho prohl&#xED;&#x17E;e&#x10D; um&#xED; vykreslit str&#xE1;nku.</p>\n<p>Ale my nechceme obsah pro lidi.\nPod&#xED;vejme se, co Wikipedia zp&#x159;&#xED;stup&#x148;uje po&#x10D;&#xED;ta&#x10D;&#x16F;m.</p>\n<h2>Data pro strojov&#xE9; zpracov&#xE1;n&#xED;</h2>\n<p>Nyn&#xED; si na&#x10D;teme str&#xE1;nku, kter&#xE1; n&#xE1;m vr&#xE1;t&#xED; v&#xFD;sledek v JSON:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">requests</span>\n\n<span class=\"c1\"># kl&#xED;&#x10D;ov&#xE9; slovo, podle kter&#xE9;ho budeme vyhled&#xE1;vat</span>\n<span class=\"n\">klic</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;V&#xE1;noce&apos;</span>\n\n<span class=\"c1\"># sta&#x17E;en&#xED; str&#xE1;nky</span>\n<span class=\"n\">stranka</span> <span class=\"o\">=</span> <span class=\"n\">requests</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&apos;https://cs.wikipedia.org/w/api.php?action=query&amp;prop=extracts&amp;explaintext&amp;exintro&amp;format=json&amp;titles={}&apos;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">klic</span><span class=\"p\">),</span> <span class=\"n\">timeout</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># ov&#x11B;&#x159;en&#xED;, &#x17E;e dotaz prob&#x11B;hl v po&#x159;&#xE1;dku</span>\n<span class=\"n\">stranka</span><span class=\"o\">.</span><span class=\"n\">raise_for_status</span><span class=\"p\">()</span>\n\n<span class=\"c1\"># vyps&#xE1;n&#xED; obsahu</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">stranka</span><span class=\"o\">.</span><span class=\"n\">text</span><span class=\"p\">)</span>\n</pre></div><p>Na n&#xE1;&#x161; dotaz Wikipedia vr&#xE1;t&#xED; z&#xE1;kladn&#xED; informace o zadan&#xE9;m vyhled&#xE1;vac&#xED;m kl&#xED;&#x10D;i v JSONU.</p>\n<p>Zkus &#x159;et&#x11B;zec <code>stranka.text</code> p&#x159;ev&#xE9;st z&#xA0;JSON na slovn&#xED;k\na vypsat trochu srozumiteln&#x11B;ji:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">json</span>\n\n<span class=\"c1\"># P&#x159;evedeme do Python&#xED;ch struktur</span>\n<span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">json</span><span class=\"o\">.</span><span class=\"n\">loads</span><span class=\"p\">(</span><span class=\"n\">stranka</span><span class=\"o\">.</span><span class=\"n\">text</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># vyp&#xED;&#x161;eme s odsazen&#xED;m </span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">json</span><span class=\"o\">.</span><span class=\"n\">dumps</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">ensure_ascii</span><span class=\"o\">=</span><span class=\"bp\">False</span><span class=\"p\">,</span> <span class=\"n\">indent</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">))</span>\n</pre></div>\n\n\n        "
    }
  }
}