如何通过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项目地址是来自这位大佬

posted @   ミanㄟ唯一挚爱  阅读(1961)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
点击右上角即可分享
微信分享提示