如何通过api请求了解原神抽卡数据
main.py
import os
import sys
import writeXLSX
import webbrowser
from writeJson import writeJson
def get_user():
return os.path.expanduser('~')
output_log_path = get_user() + '/AppData/LocalLow/miHoYo/原神/output_log.txt'
if __name__ == '__main__':
url = ""
with open(output_log_path, "r", encoding="mbcs", errors="ignore") as f:
log = f.readlines()
for line in log:
if line.startswith("OnGetWebViewPageFinish") and line.endswith("#/log\n"):
url = line.replace("OnGetWebViewPageFinish:", "").replace("\n", "")
if url == "":
print("路径" + output_log_path + "下:\r\n日志文件中找不到OnGetWebViewPageFinish的链接\r\n")
print("请进游戏后按f3 查询一次祈愿历史记录!")
os.system("pause")
else:
spliturl = url.split("?")
spliturl[0] = "https://hk4e-api.mihoyo.com/event/gacha_info/api/getGachaLog"
writeJson(spliturl)
writeXLSX.main()
print("清除临时文件\r\n", end="...", flush=True)
gen_path = os.path.dirname(os.path.realpath(sys.argv[0]))
del_paths = [name for name in os.listdir(gen_path) if
name.startswith("gacha") and (name.endswith(".json"))]
for del_path in del_paths:
try:
os.remove(gen_path + "\\" + del_path)
except:
pass
print("\t数据抓取完成,试着将excel文件拖入打开的网页?")
webbrowser.open_new_tab('https://api.heycmm.cn/genshin-gacha-analyzer/')
os.system("pause")
writeJson.py
import json
import os
import sys
import time
from api import checkApi, getGachaTypes, getGachaLogs, mergeDataFunc
def writeJson(spliturl: list):
url = "?".join(spliturl)
if checkApi(url):
print("获取抽卡记录", flush=True)
gachaTypes = getGachaTypes(url)
gachaTypeIds = [banner["key"] for banner in gachaTypes]
gachaTypeNames = [banner["name"] for banner in gachaTypes]
gachaTypeDict = dict(zip(gachaTypeIds, gachaTypeNames))
gachaData = {}
gachaData["gachaType"] = gachaTypes
gachaData["gachaLog"] = {}
for gachaTypeId in gachaTypeIds:
gachaLog = getGachaLogs(url, gachaTypeId, gachaTypeDict)
gachaData["gachaLog"][gachaTypeId] = gachaLog
uid_flag = 1
for gachaType in gachaData["gachaLog"]:
for log in gachaData["gachaLog"][gachaType]:
if uid_flag and log["uid"]:
gachaData["uid"] = log["uid"]
uid_flag = 0
gen_path = os.path.dirname(os.path.realpath(sys.argv[0]))
uid = gachaData["uid"]
localDataFilePath = f"{gen_path}\\gachaData-{uid}.json"
if os.path.isfile(localDataFilePath):
with open(localDataFilePath, "r", encoding="utf-8") as f:
localData = json.load(f)
mergeData = mergeDataFunc(localData, gachaData)
else:
mergeData = gachaData
print("写入文件", end="...", flush=True)
with open(f"{gen_path}\\gachaData.json", "w", encoding="utf-8") as f:
json.dump(mergeData, f, ensure_ascii=False, sort_keys=False, indent=4)
with open(f"{gen_path}\\gachaData-{uid}.json", "w", encoding="utf-8") as f:
json.dump(mergeData, f, ensure_ascii=False, sort_keys=False, indent=4)
print("JSON", flush=True)
t = time.strftime("%Y%m%d%H%M%S", time.localtime())
with open(f"{gen_path}\\gachaData-{uid}-{t}.json", "w", encoding="utf-8") as f:
json.dump(gachaData, f, ensure_ascii=False, sort_keys=False, indent=4)
api.py
import urllib.parse
import requests
import json
from time import sleep
def checkApi(url) -> bool:
if not url:
print("url为空")
return False
if "getGachaLog" not in url:
print("错误的url,检查是否包含getGachaLog")
return False
try:
r = requests.get(url)
s = r.content.decode("utf-8")
j = json.loads(s)
except Exception as e:
print("API请求解析出错:" + str(e))
return False
if not j["data"]:
if j["message"] == "authkey valid error":
print("authkey错误")
else:
print("数据为空,错误代码:" + j["message"])
return False
return True
def getApi(url: str, gachaType: str, size: str, page: int, end_id="") -> str:
parsed = urllib.parse.urlparse(url)
querys = urllib.parse.parse_qsl(parsed.query)
param_dict = dict(querys)
param_dict["size"] = size
param_dict["gacha_type"] = gachaType
param_dict["page"] = page
param_dict["lang"] = "zh-cn"
param_dict["end_id"] = end_id
param = urllib.parse.urlencode(param_dict)
path = url.split("?")[0]
api = path + "?" + param
return api
def getGachaLogs(url: str, gachaTypeId: str, gachaTypeDict: dict) -> list:
size = "20"
# api限制一页最大20
gachaList = []
end_id = "0"
for page in range(1, 9999):
print(f"正在获取 {gachaTypeDict[gachaTypeId]} 第 {page} 页", flush=True)
api = getApi(url, gachaTypeId, size, page, end_id)
r = requests.get(api)
s = r.content.decode("utf-8")
j = json.loads(s)
gacha = j["data"]["list"]
if not len(gacha):
break
for i in gacha:
gachaList.append(i)
end_id = j["data"]["list"][-1]["id"]
sleep(0.5)
return gachaList
def getGachaTypes(url: str) -> list:
tmp_url = url.replace("getGachaLog", "getConfigList")
parsed = urllib.parse.urlparse(tmp_url)
querys = urllib.parse.parse_qsl(parsed.query)
param_dict = dict(querys)
param_dict["lang"] = "zh-cn"
param = urllib.parse.urlencode(param_dict)
path = tmp_url.split("?")[0]
tmp_url = path + "?" + param
r = requests.get(tmp_url)
s = r.content.decode("utf-8")
configList = json.loads(s)
return configList["data"]["gacha_type_list"]
def mergeDataFunc(localData: dict, gachaData: dict) -> dict:
gachaTypes = gachaData["gachaType"]
gachaTypeIds = [banner["key"] for banner in gachaTypes]
gachaTypeNames = [banner["name"] for banner in gachaTypes]
gachaTypeDict = dict(zip(gachaTypeIds, gachaTypeNames))
for banner in gachaTypeDict:
bannerLocal = localData["gachaLog"][banner]
bannerGet = gachaData["gachaLog"][banner]
if bannerGet == bannerLocal:
pass
else:
print("合并", gachaTypeDict[banner])
flaglist = [1] * len(bannerGet)
loc = [[i["time"], i["name"]] for i in bannerLocal]
for i in range(len(bannerGet)):
gachaGet = bannerGet[i]
get = [gachaGet["time"], gachaGet["name"]]
if get in loc:
pass
else:
flaglist[i] = 0
print("获取到", len(flaglist), "条记录")
tempData = []
for i in range(len(bannerGet)):
if flaglist[i] == 0:
gachaGet = bannerGet[i]
tempData.insert(0, gachaGet)
print("追加", len(tempData), "条记录")
for i in tempData:
localData["gachaLog"][banner].insert(0, i)
return localData
writeXLSX.py
import json
import os
import sys
uid = ""
gachaInfo = []
gachaTypes = []
gachaLog = []
gachaTypeIds = []
gachaTypeNames = []
gachaTypeDict = {}
gachaTypeReverseDict = {}
def getInfoByItemId(item_id):
for info in gachaInfo:
if item_id == info["item_id"]:
return info["name"], info["item_type"], info["rank_type"]
return
def writeXLSX(uid, gachaLog, gachaTypeIds):
import xlsxwriter
import time
gen_path = os.path.dirname(os.path.realpath(sys.argv[0]))
t = time.strftime("%Y%m%d%H%M%S", time.localtime())
workbook = xlsxwriter.Workbook(f"{gen_path}\\{uid}-{t}.xlsx")
for id in gachaTypeIds:
gachaDictList = gachaLog[id]
gachaTypeName = gachaTypeDict[id]
gachaDictList.reverse()
header = "时间,名称,类别,星级,总次数,保底内"
worksheet = workbook.add_worksheet(gachaTypeName)
content_css = workbook.add_format(
{"align": "left", "font_name": "微软雅黑", "border_color": "#c4c2bf", "bg_color": "#ebebeb", "border": 1})
title_css = workbook.add_format(
{"align": "left", "font_name": "微软雅黑", "color": "#757575", "bg_color": "#dbd7d3", "border_color": "#c4c2bf",
"border": 1, "bold": True})
excel_col = ["A", "B", "C", "D", "E", "F"]
excel_header = header.split(",")
worksheet.set_column("A:A", 22)
worksheet.set_column("B:B", 14)
for i in range(len(excel_col)):
worksheet.write(f"{excel_col[i]}1", excel_header[i], title_css)
worksheet.freeze_panes(1, 0)
idx = 0
pdx = 0
i = 0
for gacha in gachaDictList:
time = gacha["time"]
name = gacha["name"]
item_type = gacha["item_type"]
rank_type = gacha["rank_type"]
idx = idx + 1
pdx = pdx + 1
excel_data = [time, name, item_type, rank_type, idx, pdx]
excel_data[3] = int(excel_data[3])
for j in range(len(excel_col)):
worksheet.write(f"{excel_col[j]}{i + 2}", excel_data[j], content_css)
if excel_data[3] == 5:
pdx = 0
i += 1
star_5 = workbook.add_format({"color": "#bd6932", "bold": True})
star_4 = workbook.add_format({"color": "#a256e1", "bold": True})
star_3 = workbook.add_format({"color": "#8e8e8e"})
worksheet.conditional_format(f"A2:F{len(gachaDictList) + 1}",
{"type": "formula", "criteria": "=$D2=5", "format": star_5})
worksheet.conditional_format(f"A2:F{len(gachaDictList) + 1}",
{"type": "formula", "criteria": "=$D2=4", "format": star_4})
worksheet.conditional_format(f"A2:F{len(gachaDictList) + 1}",
{"type": "formula", "criteria": "=$D2=3", "format": star_3})
workbook.close()
def main():
gen_path = os.path.dirname(os.path.realpath(sys.argv[0]))
f = open(f"{gen_path}\\gachaData.json", "r", encoding="utf-8")
s = f.read()
f.close()
j = json.loads(s)
global uid
global gachaInfo
global gachaTypes
global gachaLog
global gachaTypeIds
global gachaTypeNames
global gachaTypeDict
global gachaTypeReverseDict
uid = j["uid"]
gachaTypes = j["gachaType"]
gachaLog = j["gachaLog"]
gachaTypeIds = [banner["key"] for banner in gachaTypes]
gachaTypeNames = [key["name"] for key in gachaTypes]
gachaTypeDict = dict(zip(gachaTypeIds, gachaTypeNames))
gachaTypeReverseDict = dict(zip(gachaTypeNames, gachaTypeIds))
print("写入文件", end="...", flush=True)
writeXLSX(uid, gachaLog, gachaTypeIds)
print("XLSX", end=" ", flush=True)
if __name__ == "__main__":
main()
这部分代码是Python编写
git项目地址是来自这位大佬
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?