Ammonite/HTTP запит з парсингом JSON

Матеріал з Вікіпідручника

Одержання даних за допомогою HTTP запитів[ред.]

Зробимо щось цікаве, наприклад отримаємо список новостворених статей у Вікіпедії. MediaWiki надає API, який дозволяє і отримувати недавні редагування — API:RecentChanges

Візьмемо приклад рядка запиту з довідки MediaWiki API

val query = "https://uk.wikipedia.org" + "/w/api.php?action=query&format=json" + "&list=recentchanges" + "&rcprop=title%7Csizes%7Cuser" + "&rctype=new" + "&rclimit=3"

за допомогою функції стандартної бібліотки Scala отримаємо текст відповіді scala.io.Source.fromURL(s:String)

import scala.io.Source 
val text = Source.fromURL(query).mkString

Відповідь:

text: String = """
{"batchcomplete":"","continue":{"rccontinue":"20170104183620|37482690","continue":"-||"},"query":{"recentchanges":[{"type":"new","ns":1,"title":"\u041e\u0431\u0433\u043e\u0432\u043e\u0440\u0435\u043d\u043d\u044f:\u0416\u0430\u043d-\u041b\u0443\u0457 \u041f\u0435\u0442\u0456","user":"Brunei","oldlen":0,"newlen":64},{"type":"new","ns":0,"title":"\u0427\u043e\u0440\u043d\u043e\u043a\u0430\u043c'\u044f\u043d\u0441\u044c\u043a\u0438\u0439 \u043f\u0440\u0438\u0442\u0456\u043a\u0438\u0447\u0441\u044c\u043a\u0438\u0439 \u043a\u0430\u043d\u044c\u0439\u043e\u043d","user":"Maxim Gavrilyuk","oldlen":0,"newlen":1185},{"type":"new","ns":0,"title":"\u0422\u0435\u0440\u0430\u0441\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0430","user":"\u0411\u0456\u043b\u0435\u0446\u044c\u043a\u0438\u0439 \u0412.\u0421.","oldlen":0,"newlen":799}]}}
"""

Символи кирилиці у відповіді закодовані в Unicode послідовності \u

Парсинг JSON[ред.]

Тепер розпарсимо json відповідь. Ammonite дозволяє імпортувати залежності з Maven Central. Імпортуємо бібліотеку circe для парсингу json

import $ivy.`io.circe::circe-parser:0.6.1`

і розпарсимо json:

import io.circe._, io.circe.parser._ 
val doc = parse(text).getOrElse(Json.Null)

Вивід:

doc: Json = {
  "batchcomplete" : "",
  "continue" : {
    "rccontinue" : "20170104183620|37482690",
    "continue" : "-||"
  },
  "query" : {
    "recentchanges" : [
      {
        "type" : "new",
        "ns" : 1,
        "title" : "Обговорення:Жан-Луї Петі",
        "user" : "Brunei",
        "oldlen" : 0,
        "newlen" : 64
      },
      {
        "type" : "new",
        "ns" : 0,
        "title" : "Чорнокам'янський притікичський каньйон",
        "user" : "Maxim Gavrilyuk",
        "oldlen" : 0,
        "newlen" : 1185
      },
      {
...

Отримаємо список статей, скористашись модулем circe-optics

import $ivy.`io.circe::circe-optics:0.6.1`
import io.circe.optics.JsonPath._ 
val titles = root.query.recentchanges.each.title.string.getAll(doc)

Вивід:

titles: List[String] = List("Обговорення:Жан-Луї Петі", "Чорнокам'янський притікичський каньйон", "Тераса локальна")

Збереження коду в скрипт-файл[ред.]

Поєднаємо все вищенаписане разом

import $ivy.`io.circe::circe-parser:0.6.1`, $ivy.`io.circe::circe-optics:0.6.1`
import io.circe._, io.circe.parser._ , io.circe.optics.JsonPath._ 
import scala.io.Source 

val query = "https://uk.wikipedia.org" + "/w/api.php?action=query&format=json" + "&list=recentchanges" + "&rcprop=title%7Csizes%7Cuser" + "&rctype=new" + "&rclimit=3"

val text = Source.fromURL(query).mkString

val doc = parse(text).getOrElse(Json.Null)

val titles = root.query.recentchanges.each.title.string.getAll(doc)

println(titles)

і запишемо у файл recentarticles.sc

Тепер набравши amm recentarticles.sc можна отримати 3 останні створені статті у Вікіпедії