はじめに
はじめまして。
PythonでEnkanetworkAPIを利用する際に、requestsで持ってくる記事はQiitaや他サイトなどに色々ありますが、enkanetwork.pyをインポートして利用する方法を書いている記事が見当たらなかったので書いていこうと思います。
Enkanetworkとは?
Enkanetworkとは、ざっくり申しますと原神内のプロフィールデータを持って来てくれるAPIです。
取得できる情報を具体的に言うと、フレンドの画面を開いて見る事が出来る情報を大体すべて取得できます。8枠あるキャラクターの欄だったりアチーブ数だったり、キャラクター詳細を非表示にしていなければ聖遺物や武器なんかも参照する事が出来ます。
今X(旧Twitter)などでよく見かける原神のキャラクターのビルドカードは全てこのAPIが絡んでいると考えてもらってOKです。日本だとArtifacterさんのデザインが一番有名だと思います。
なお、APIはJSやPython、javaにもあるそうな。
導入
enkanetwork.py公式サイトより説明していきます。
pipからインストールします。
pip install enkanetwork.py
モジュールが複数入ります。原神にアプデが来たときはモジュールのアプデも必要です(後述)。
自分の環境だとなぜかこのままでは動かないので、一緒に入ったモジュールの1つをダウングレードしておきます。
pip install pydantic==1.10.9
2023/12/25追記
上記サイトの方の更新が途絶えたらしく、別の方がフォークしてくれました。
インストール方法が変わります。
pip install git+https://github.com/0kq-github/EnkaNetwork.py.git@develop
使い方
基本の書き方です。この手のモジュールにはよくあるタイプの、async内に記述するものになります。
import asyncio
from enkanetwork import EnkaNetworkAPI, Assets
client = EnkaNetworkAPI()
assets = Assets(lang="jp")
async def main():
async with client:
data = await client.fetch_user(823473389) #UIDを入力
print(data.player.nickname)
asyncio.run(main())
上のプログラム内の変数data
にAPIの中身が入っています。この中身の階層を、.(ドット)で繋いで下っていくイメージです。中身は全てGithubのreadmeに載っています。ちなみにドットを付けた時にVSCodeなどのサジェストに一覧が出てきてすごい便利。
上記コードを実行すると、この場合data.player.nickname
はプレイヤーネームを参照しますので私のゲーム内の名前(多分tomo)が出力されます。
以下、主なものを紹介していきます。APIを代入する変数はdata
固定でいきます。
data.player
こちらは、ゲーム内のプロフィールで「キャラクター情報の詳細を非表示」をオンにしていても参照できます。
data.player.nickname
ゲーム内のプレイヤーネームを参照します。
data.characters
こちらは、ゲーム内のプロフィールで「キャラクター情報の詳細を非表示」をオンにしていると参照できず、None
が返ってきます。
data.characters
内には最大8人分のキャラクターデータが配列になって入っています。なのでプロフィールに1キャラも設定していない場合もNone
が返ってきます。
data.characters[n].name
キャラクターの名前を参照します。
data.characters[n].element.name
キャラクターの元素を参照します。
炎元素だとPyro
と返ってきます。value
にするとFire
となりますが、使い分けはお好みで。
data.characters[n].level
キャラクターのレベルを参照します。
max_level
もあり、今の突破段階での最大レベルが参照されます。
data.characters[n].equiments
聖遺物と武器の情報を参照します。
多分こいつが一番厄介なので詳しく解説。
まず、data.characters[n].equiments
の中身は聖遺物最大5つと武器が配列になって入っています。
聖遺物が5つ付いている場合は配列0~4が聖遺物(花羽砂杯冠の順)、5が武器になります。聖遺物が5つ付いていない場合は、空の配列は出来ず前から詰めて配列に入ります。
data.characters[n].equiments[n].detail.artifact_name_set
聖遺物のセット名が参照されます。
data.characters[n].equiments[n].detail.artifact_type.name
聖遺物の部位が出力されます。
花ならFlowerと出ます。
data.characters[n].equiments[n].detail.mainstats
聖遺物のメインステータスが参照されます。武器だと基礎攻撃力が出ます。
data.characters[n].equiments[n].detail.substats
聖遺物のサブステータスが配列になって参照されます。武器だとメイン効果が出ます。
ここら辺まで説明を読めば、Githubのページから必要なデータの取り出し方が分かってくるのではないでしょうか。書くのが面倒になってきたので例はこのぐらいにしておきます
発展
その1
このAPI内には何故か発動している聖遺物のセット効果がないので、セット効果を取り出すプログラムを簡単に書いてみます。
def set(data, n)
set = {}
artifact = {}
for i in range(len(data.characters[n].equipments)-1):
if data.characters[n].equipments[i].detail.artifact_name_set in artifact:
artifact[data.characters[n].equipments[i].detail.artifact_name_set] += 1
else:
artifact[data.characters[n].equipments[i].detail.artifact_name_set] = 1
for i, j in artifact.items():
if j >= 2:
set[i] = j
return set
辞書型のset
に{"聖遺物" : セット数}
という形で代入されました。。
このプログラムだと3や5という数字も出てきてしまいますが、ゲーム内でも同じ聖遺物5つを付けると「燃え盛る炎の魔女(5)」みたいな風に出てくるので大丈夫だと思います。
その2
多分このAPIはスコア計算目的で使われることが多いと思うので、計算式でも書いてみましょう。
引数のorder
はキャラクターの配列、calc_status
は0から順番に攻撃力%基準、防御力%基準、HP%基準、元素チャージ効率基準、元素熟知基準です。
def Calc(data, order, calc_status):
if calc_status == 0:
num = 1
base_status = "FIGHT_PROP_ATTACK_PERCENT"
elif calc_status == 1:
num = 0.8
base_status = "FIGHT_PROP_DEFENSE_PERCENT"
elif calc_status == 2:
num = 1
base_status = "FIGHT_PROP_HP_PERCENT"
elif calc_status == 3:
num = 0.9
base_status = "FIGHT_PROP_CHARGE_EFFICIENCY"
elif calc_status == 4:
num = 0.25
base_status = "FIGHT_PROP_ELEMENT_MASTERY"
allscore = 0
i = j = 0
artifact_score = [0, 0, 0, 0, 0]
for i in range(len(data.characters[order].equipments)-1):
temp = 0
for j in range(len(data.characters[order].equipments[i].detail.substats)):
if data.characters[order].equipments[i].detail.substats[j].prop_id == "FIGHT_PROP_CRITICAL_HURT":
temp = temp + data.characters[order].equipments[i].detail.substats[j].value
elif data.characters[order].equipments[i].detail.substats[j].prop_id == base_status:
temp = temp + (data.characters[order].equipments[i].detail.substats[j].value) * num
elif data.characters[order].equipments[i].detail.substats[j].prop_id == "FIGHT_PROP_CRITICAL":
temp = temp + (data.characters[order].equipments[i].detail.substats[j].value) * 2
if data.characters[order].equipments[i].detail.artifact_type.value == "EQUIP_BRACER":
artifact_score[0] = temp
elif data.characters[order].equipments[i].detail.artifact_type.value == "EQUIP_NECKLACE":
artifact_score[1] = temp
elif data.characters[order].equipments[i].detail.artifact_type.value == "EQUIP_SHOES":
artifact_score[2] = temp
elif data.characters[order].equipments[i].detail.artifact_type.value == "EQUIP_RING":
artifact_score[3] = temp
elif data.characters[order].equipments[i].detail.artifact_type.value == "EQUIP_DRESS":
artifact_score[4] = temp
allscore = allscore + temp
return artifact_score, allscore
artifact_score
に聖遺物ひとつひとつのスコアが、allscore
に合計スコアが入ってます。
絶対もっと綺麗に書けると思いますが、面倒なので誰か教えてください。
アップデートについて
原神がアップデートしてすぐは、Enkanetworkのサーバーメンテの為APIがしばらく動いていないです。
しばらくしてメンテが明けた時にはモジュールのアップデートが必要になります。
pip install enkanetwork==
このコマンドで最新版を確認し、バージョンを指定してアップデートを行ってください。
また、以下のPythonのコードを実行しましょう。
import asyncio
from enkanetwork import EnkaNetworkAPI
client = EnkaNetworkAPI(debug=True)
async def main():
async with client:
await client.update_assets()
# You can see the progress download new assets in console
asyncio.run(main())
多分どっちかのみでいいと思うのですが、アプデ後の挙動がおかしくなったら両方試しましょう。