🐹

PokeAPIからセルフホスト用のjsonを作る

2023/09/09に公開

環境

Node.js v18.16.0

動作概要

fetchでPokeAPIエンドポイントにアクセスする。
fsモジュールを用いてjsonファイルを作成し、作成した一覧データから、言語ごとに小分けにしたjsonを作成する。

https://pokeapi.co/

完成ファイルの内容

例として日本語のファイルを掲載する

ja_pokemon.json
[
  {
    "id": 1,
    "names": "フシギダネ",
    "genera": "たねポケモン",
    "types": ["くさ", "どく"]
  },
  {
    "id": 2,
    "names": "フシギソウ",
    "genera": "たねポケモン",
    "types": ["くさ", "どく"]
  },

// 以下略

コード

ひとつずつコメントアウトを外して実行すると勝手にjsonができる。
いつもこのひな形でやってるけど、かなり便利。

getdata.js
const fs = require("fs");

const request_pokemon_a = "https://pokeapi.co/api/v2/pokemon/"; // id,typeを取得
const request_pokemon_b = "https://pokeapi.co/api/v2/pokemon-species/"; // name,generaを取得
const request_type = "https://pokeapi.co/api/v2/type/";
const request_pokemon_local = JSON.parse(fs.readFileSync("./all_pokemon.json"));
const request_type_local = JSON.parse(fs.readFileSync("./all_types.json"));
// ↑ ファイルがない状態で実行するとエラーになるので、コメントアウトしておいてください。
const lang_arr = ["ja", "en", "de", "it", "fr", "es", "ko", "zh-Hans", "zh-Hant"];
// 日、英、独、伊、仏、西、韓、中[簡、繁]
let _number = 1; // 図鑑番号
let _max_number = 898; // この番号のポケモンまで取得する
let _current_data = { id: "", names: "", genera: "", types: [] }; // 一時データ入れ

// all_pokemon.jsonを作成する
function getData(request) {
  fetch(request + _number)
    .then((response) => response.json())
    .then((data) => {
      console.log(_number);
      if (request == request_pokemon_a) {
        // 一つ目のエンドポイント(id,typeを取得)
        _current_data.id = data.id;
        _current_data.types = data.types.map((element) => element.type.name);
        getData(request_pokemon_b);
      } else if (request == request_pokemon_b) {
        // 二つ目のエンドポイント(name,generaを取得)
        _current_data.genera = data.genera;
        _current_data.names = data.names;

        // jsonに追記
        if (_number == 1) {
          fs.appendFileSync(`all_pokemon.json`, "[" + JSON.stringify(_current_data, null, "    ") + ",");
        } else if (_number == _max_number) {
          fs.appendFileSync(`all_pokemon.json`, JSON.stringify(_current_data, null, "    ") + "]");
        } else {
          fs.appendFileSync(`all_pokemon.json`, JSON.stringify(_current_data, null, "    ") + ",");
        }

        _number++;
        if (_number <= _max_number) {
          getData(request_pokemon_a);
        }
      }
    });
}

// 実行1 かなり時間がかかる
// getData(request_pokemon_a);

// タイプ一覧(all_types.json)を取得
function getTypes(request) {
  fetch(request + _number)
    .then((response) => response.json())
    .then((data) => {
      console.log(_number);
      if (_number == 1) {
        fs.appendFileSync(`all_types.json`, "[" + JSON.stringify(data.names, null, "    ") + ",");
      } else if (_number == 18) {
        fs.appendFileSync(`all_types.json`, JSON.stringify(data.names, null, "    ") + "]");
      } else {
        fs.appendFileSync(`all_types.json`, JSON.stringify(data.names, null, "    ") + ",");
      }
      _number++;
      if (_number <= 18) {
        getTypes(request_type);
      }
    });
}

// 実行2
// getTypes(request_type);

// all_pokemon.jsonを言語ごとに分割
function CreateLangData(data, lang) {
  for (let i = 0; i < data.length; i++) {
    console.log(i);
    _current_data.id = data[i].id;
    _current_data.types = changeTypesLang(data[i].types, lang);
    _current_data.genera = data[i].genera.filter((item) => item.language.name === lang).map((item) => item.genus)[0];
    _current_data.names = data[i].names.filter((item) => item.language.name === lang).map((item) => item.name)[0];
    if (i == 0) {
      fs.appendFileSync(`${lang}_pokemon.json`, "[" + JSON.stringify(_current_data, null, "    ") + ",");
    } else if (i == _max_number - 1) {
      fs.appendFileSync(`${lang}_pokemon.json`, JSON.stringify(_current_data, null, "    ") + "]");
    } else {
      fs.appendFileSync(`${lang}_pokemon.json`, JSON.stringify(_current_data, null, "    ") + ",");
    }
  }
}

// タイプ名を翻訳
function changeTypesLang(types, lang) {
  let _types_en = ["normal", "fighting", "flying", "poison", "ground", "rock", "bug", "ghost", "steel", "fire", "water", "grass", "electric", "psychic", "ice", "dragon", "dark", "fairy"];
  let _data = request_type_local;
  return types.map((element) => {
    let _index = _types_en.indexOf(element);
    return _data[_index].filter((item) => item.language.name === lang).map((item) => item.name)[0];
  });
}

// 実行3
// lang_arr.forEach((element) => {
//   CreateLangData(request_pokemon_local, element);
// });

Discussion