当前位置: 首页 > 编程日记 > 正文

告别排队!用Python定时自动挂号和快捷查询化验报告

640?wx_fmt=jpeg


作者 | 阿文

来源 | 程序人生(ID: coder_life)


我什么要做这个事情


去年单位体检查出问题来,经过穿刺手术确诊是个慢性肾脏病2期, IGA 肾病三期,可能大家对于这个病并不是很了解,但是另外一个词可能大家都听过,叫"尿毒症"。


慢性肾脏病分五期,终末期就是尿毒症。慢性肾脏病非常隐秘,并且病情进展缓慢,一般到尿毒症需要0-20年时间,如果不是体检化验尿液看里面的隐血和尿蛋白指标,根本没任何感觉。


三甲医院人满为患,挂号跟春运买火车票一样的,很麻烦。所以我打算用程序员的方式来解决挂号这件事。


实现自动挂号代码


于是就自己通过 Charles 抓包分析了医院的 App 的请求,这里是分析浙江大学第一附属医院的 App,然后用 Python 写了个脚本去模拟登录医院的 App 然后去挂号,具体代码如下:


import requests
import json
import time
import  datetime
from dateutil.relativedelta import relativedelta

# 登录获取session_id
def login(username,password):

    url = "https://zyyy.zwjk.com/api/exec.htm"
    data = {"api_Channel":"1",
            "client_version":"3.6.6",
            "app_id":"zyyy_android",
            "app_key":"xxxx",
            "user_type":"0",
            "client_mobile":"863008041030718",
            "api_name":"api.user.user.login.info",
            "params":{"phone":username, # 账号
                      "psw":password}, # 密码
            }
    headers = {
        'Content-Type'"application/x-www-form-urlencoded",
        'User-Agent'"health",
        'Host'"zyyy.zwjk.com",
        'Connection'"Keep-Alive",
        'Accept'"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
        'cache-control'"no-cache",
    }

    response = requests_session.post( url, data={"requestData":json.dumps(data)}, headers=headers)

    if response.status_code != 200:
        return False
    resp_json = response.json()
    session_id = resp_json['return_params']['user_model']['session_id']
    return session_id


# 获取挂号信息

def get_doctor_info(session_id,appointment_date):

    url = "https://zyyy.zwjk.com/api/exec.htm"
    payload = {"api_Channel":"1",
               "client_version":"3.6.6",
               "app_id":"zyyy_android",
               "app_key":"xxxx",
               "user_type":"0",
               "client_mobile":"863008041030718",
               "api_name":"api.yygh.expert.schedule.list",
               "params":{"type_id":1,
                         "source_id":"12",
                         "dept_id":26,
                         "page_no":1,
                         "page_size":2147483647
                         },
               "session_id":session_id}

    headers = {
        'Content-Type'"application/x-www-form-urlencoded",
        'User-Agent'"health",
        'Host'"zyyy.zwjk.com",
        'Connection'"Keep-Alive",
        'Accept'"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
        'cache-control'"no-cache",
    }

    response = requests_session.post(url, data={"requestData":json.dumps(payload)}, headers=headers)

    if response.status_code != 200:
        return False
    resp_json = response.json()
    return_params = resp_json['return_params']['list']

    for key in return_params:
        if int(key['date']) == int(appointment_date):
            doctor_info  = key['doctor']
            for i in doctor_info:
                if i['id'] == 1960 and i['schedulList'][0]['am_pm_flag'] == "1":
                    return True

def get_time(session_id):
    pre_date = (time_now + datetime.timedelta(days=7)).strftime("%Y-%m-%d")

    url = "https://zyyy.zwjk.com/api/exec.htm"
    payload = {
    "api_Channel""1",
    "client_version""3.6.6",
    "app_id""zyyy_android",
    "app_key""xxxx",
    "user_type""0",
    "client_mobile""863008041030718",
    "api_name""api.yygh.remain.num",
    "params": {
        "sourceId""12",
        "planId"9759,
        "orderDate": str(pre_date),
        "ampmFlag""1"
    },
        "session_id": session_id
    }


    headers = {
        'Content-Type'"application/x-www-form-urlencoded",
        'User-Agent'"health",
        'Host'"zyyy.zwjk.com",
        'Connection'"Keep-Alive",
        'Accept'"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
        'cache-control'"no-cache",
    }

    response = requests_session.post(url, data={"requestData": json.dumps(payload)}, headers=headers)

    if response.status_code != 200:
        return False
    resp_json = response.json()
    regno = resp_json['return_params']['list'][0]['regno']
    timespan = resp_json['return_params']['list'][0]['timespan']
    return [regno,timespan]


# 在指定时间挂号

def set_doctor_number(session_id,pre_date,reg_no,timeregion):
    url = "https://zyyy.zwjk.com/api/exec.htm"
    payload = {
        "api_Channel""1",
        "client_version""3.6.6",
        "app_id""zyyy_android",
        "app_key""Zxxxx",
        "user_type""0",
        "client_mobile""863008041030718",
        "api_name""api.yygh.expert.reservation",
        "params": {
            "card_no""x'x'x'x"# 社保卡号
            "doct_name""华佗"# 专家名称
            "user_name""xxx"# 你的姓名
            "id_card""xxxxx"#  身份证号
            "phone""xxxx",  # 电话
            "reg_id""xxxx",
            "reg_no": reg_no, # 预约号
            "dept_name""科室",
            "yuanqu_type""1",
            "type""1",
            "dept_id"103060302,
            "pre_date": str(pre_date), #预约日期
            "week_day""3"# 预约日期是星期几
            "plan_id"9759,
            "fee""14",
            "pre_time_type""1",
            "doct_id""1960",
            "clinic_fee""",
            "clinic_time":timeregion
        },
        "session_id": str(session_id)
    }

    headers = {
        'Content-Type'"application/x-www-form-urlencoded",
        'User-Agent'"health",
        'Host'"zyyy.zwjk.com",
        'Connection'"Keep-Alive",
        'Accept'"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
        'cache-control'"no-cache",
    }

    response = requests_session.post(url, data={"requestData": json.dumps(payload)}, headers=headers)

    if response.status_code != 200:
        return False
    resp_json = response.json()
    ret_info = resp_json['return_params']['ret_info']
    send_message_wchat("浙一预约挂号结果",ret_info)

# 发送消息到微信
def send_message_wchat(title, content):
    loging_datetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    url = "https://sc.ftqq.com/SCU9051Tc94a746xxxf1d559xxx5a545ff.send"
    querystring = {"text": title, "desp": str(loging_datetime) + str(content)}
    response = requests.request("GET", url, params=querystring)
    if response != 200:
        return
    return True


if __name__ == '__main__':
    requests_session = requests.Session()
    time_now = datetime.datetime.now()
    pre_date = (time_now+datetime.timedelta(days=7)).strftime("%Y%m%d")
    session_id = login('xxxx','xxxxxx')
    if get_doctor_info(session_id,pre_date):
        regno = get_time(session_id)[0]
        timespan = get_time(session_id)[1]
        set_doctor_number(session_id,pre_date,regno,timespan)
    else:
        send_message_wchat("浙一预约挂号结果","获取列表失败,可能原因:医生不在预约列表中或者医生门诊不在上午")

然后写个计划任务每个月的第一个周三去执行脚本:

0 15 1-7 * * if [ `date '+%w'` = "3" ]; then /usr/bin/python3 /opt/hospital/zheyi.py;fi

执行脚本后结果:

640?wx_fmt=png


命令行式输出化验单到 markdown 文件中


我觉得查询化验报告的功能不好用,每次都要登录App 然后输入姓名和医嘱号才能查询。


我希望对自己的病情做个管理,把每次的化验结果都保存起来进行分析,于是就实现只要输入医嘱号,就自动输出 markdown 格式的文档里面包含一张表格,如图所示:


640?wx_fmt=png

代码如下:

import requests
import json



requests_session = requests.Session()

def login(username,password):

    url = "https://zyyy.zwjk.com/api/exec.htm"
    data = {"api_Channel":"1",
            "client_version":"3.6.6",
            "app_id":"zyyy_android",
            "app_key":"ZW5sNWVWOWhibVJ5YjJsaw==",
            "user_type":"0",
            "client_mobile":"863008041030718",
            "api_name":"api.user.user.login.info",
            "params":{"phone":username, # 账号
                      "psw":password}, # 密码
            }
    headers = {
        'Content-Type'"application/x-www-form-urlencoded",
        'User-Agent'"health",
        'Host'"zyyy.zwjk.com",
        'Connection'"Keep-Alive",
        'Accept'"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
        'cache-control'"no-cache",
    }

    response = requests_session.post( url, data={"requestData":json.dumps(data)}, headers=headers)

    if response.status_code != 200:
        return False
    resp_json = response.json()
    session_id = resp_json['return_params']['user_model']['session_id']
    return session_id


def get_huayan_save(session_id,username, barcode):

        url = "https://zyyy.zwjk.com/api/exec.htm"
        payload = {"api_Channel""1",
                   "client_version""3.6.6",
                   "app_id""zyyy_android",
                   "app_key""ZW5sNWVWOWhibVJ5YjJsaw==",
                    "user_type""0",
                   "client_mobile""863008041030718",
                   "api_name""api.assay.report.socket",
                    "params": {"name": username,
                               "barcode": barcode},
                   "session_id": session_id
                   }

        headers = {
            'Content-Type'"application/x-www-form-urlencoded",
            'User-Agent'"health",
            'Host'"zyyy.zwjk.com",
            'Connection'"Keep-Alive",
            'Accept'"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
            'cache-control'"no-cache",
        }

        response = requests_session.post(url, data={"requestData": json.dumps(payload)}, headers=headers)

        if response.status_code != 200:
            return False
        resp_json = response.json()
        if resp_json['return_params']['ret_code'] == -1:
            return resp_json['return_params']['ret_info']
        file_name =  resp_json['return_params']['assayreport']['test_name']
        username = resp_json['return_params']['assayreport']['name']
        sample_type = resp_json['return_params']['assayreport']['sample_type']
        report_barcode =  resp_json['return_params']['assayreport']['report_barcode']
        send_time = resp_json['return_params']['assayreport']['send_time']
        send_name = resp_json['return_params']['assayreport']['send_name']
        assayreportdetail = resp_json['return_params']['assayreportdetail']
        entry_time = resp_json['return_params']['assayreport']['entry_time']
        entry_name = resp_json['return_params']['assayreport']['entry_name']
        audit_name = resp_json['return_params']['assayreport']['audit_name']


        with open(username+file_name+"+"+report_barcode+".md","at"as f:
            f.write("|项目||||"+"\n")
            f.write("|---|---|---|---|"+"\n")
            f.write("|化验项目|"+sample_type+"|"+file_name+"||"+"\n")
            f.write("|接收时间|"+send_time+"|||"+"\n")
            f.write("|报告时间|"+entry_time+"|||"+"\n")
            f.write("|送检医生|"+send_name+"|||"+"\n")
            f.write("|报告医生|"+entry_name+"|||"+"\n")
            f.write("|审计医生|"+audit_name+"|||"+"\n")
            f.write("|医嘱号|"+report_barcode+"|||"+"\n")
            f.write("\n")
            f.write("|项目|单位|结果|参考范围|"+"\n")
            f.write("|---|---|---|---|"+"\n")
            for i in assayreportdetail:
                item_name_info = i['item_name']
                try:
                    result_unit_info = i['result_unit']
                    result_data_info = i['result_data']
                    ref_range_low_info = i['ref_range_low']
                except KeyError:
                    pass
                if result_unit_info:
                    f.write("|"+item_name_info+"|"+str(result_unit_info)+"|"+result_data_info+"|"+ref_range_low_info+"|"+"\n")
                else:
                    f.write("|"+item_name_info+"|"+"|"+result_data_info+"|"+ref_range_low_info+"|"+"\n")

if __name__ == '__main__':

    session_id = login('xxxx','xxx')
    report_barcode = input("请输入医嘱号:")
    print(get_huayan_save(session_id,"阿文",report_barcode))

后面我可以把这些数据都导入Excel 之类的表格里面进行统计分析每次的指标变化。


最后


年纪越大身体经不起体检,希望新的一年里,能够早日康复,也希望所有人都能够健康。


现在我改掉了很多坏习惯,比如熬夜、喝饮料,不吃辣、不烧烤、不饮酒、不吃高盐油腻食品等,命比这些重要。最后提醒大家,为了自己也为了家人,一定要定期体检。

(本文为 AI科技大本营转载文章,转载请联系原作者


征稿

640?wx_fmt=png


推荐阅读:

  • 近900000条if-then关系图谱,让神经网络“懂”常识推理

  • 你的红包狂欢夜,互联网巨头们的流量争夺战

  • 程序员给银行植入病毒,分 1300 次盗取 718 万,被判 10 年半!

  • 大厂必问的分布式究竟是什么鬼?

  • ProgPow:以太坊上浮世绘

  • 这4门AI网课极具人气,逆天好评!(附代码+答疑)

  • 给AI开发者的新年礼物,技术公开课大放送(附演讲PPT)

  • 如何用最强模型BERT做NLP迁移学习?

  • “百练”成钢:NumPy 100练

    640?wx_fmt=png

点击“阅读原文”,打开CSDN APP 阅读更贴心!

相关文章:

【POCO】POCO学习总结(三)——交叉编译

最小功能编译 编译选项:–minimal :只构建XML, JSON, 工具 and 网络 1 修改配置文件 $ vi poco-1.7.8p3-all/build/config/ARM-Linux13 LINKMODE ? SHARED 14 TOOL ? arm-linux 15 POCO_TARGET_OSNAME Linux 16 POCO_TARGET_OSARCH ? armv7l 主要…

转:入侵网站必备-sql server

来源:http://www.bitscn.com/plus/view.php?aid28692 1.判断有无注入点 ; and 11 and 12 2.猜表一般的表的名称无非是admin adminuser user pass password 等.. and 0(select count(*) from *) and 0(select count(*) from admin) ---判断是否存在admin这张表 3.猜…

27.5. PROCEDURE ANALYSE()

数据列优化 SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements,[max_memory]]) 原文出处:Netkiller 系列 手札 本文作者:陈景峯 转载请与作者联系,同时请务必标明文章原始出处和作者信息及本声明。

Linux 日志管理(RHEL7)

日志管理系统和程序的日记本记录系统,程序运行中发生的各种事件通过查看日志,了解及排除故障信息安全控制的依据 内核及系统日志由系统服务rsyslog统一记录/管理日志消息采用文本格式主要记录事件发生的时间,主机,进程,内容常见的日志文件 /var/log/messages 记录内核消息…

汇聚6年思想变迁:知识图谱报告幻灯片大全

本文汇总了中文知识图谱计算会议CCKS报告合集,涵盖从2013年至2018年,共48篇,从中可以看出从Google 2012年推出知识图谱以来,中国学术界及工业界这6年来知识图谱的主流思想变迁。作者 | 刘焕勇来源 | CSDN博客编辑 | apddd项目介绍…

【POCO】POCO学习总结(四)——MinGW编译poco

在window下使用MinGW编译poco 使用MSYS 下载MSYS 官网介绍:http://www.mingw.org/wiki/Getting_Started 官网下载:https://jaist.dl.sourceforge.net/project/mingw/Installer/mingw-get-setup.exe 安装 运行mingw-get-setup.exe,只选择…

辞职之后的思考--激励

本人曾拿过多次奖金,也曾与很多同事沟通过拿奖金的感觉,引发一些思考,这其实也是希望在以后有机会给别人发奖金时做参考之用。   并不是所有人都会有奖金,所以如果我没有奖金其实也没有什么关系,但是,我非…

【linux】串口编程(一)——配置串口

目前遇到的串口编程都是用于通信,很少作为终端显示。以前没有对串口编程做深入研究,本次以libmodbus源码中对串口的设置为例,详解总结串口编程时配置的属性(struct termios) 以libmodbus中_modbus_rtu_connect函数为例…

Playboy封面女郎、互联网第一夫人,程序员们的“钢铁审美”

整理 | 琥珀 出品 | AI科技大本营(ID:rgznai100) 46 年前,《花花公子》(Playboy)的一期杂志封面女郎 Lenna,成为数万“钢铁直男”的梦中女神。然而,这位女性更为人所知的是她在计算机图像处理领…

开源实时日志分析ELK

开源实时日志分析ELK 2018-01-04 转自:开源实时日志分析ELK平台部署 日志主要包括系统日志、应用程序日志和安全日志。系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷,性…

【linux】串口编程(二)——非阻塞接收

项目中很少会使用阻塞接收,一般都是selectread监听模式来实现非阻塞接收。 使用selece时,需要处理一些异常情况的返回,比如:系统中断产生EINTR错误;超时错误ETIMEDOUT。 使用read时,需要处理读取时可能出现…

使用Photoshop制作网页模板

用图层组管理网页元素首先是在Photoshop中制作好网页的框架。网页中的元素有很多, 像Banner条、文本框、文字、版权、Logo、广告等。尽量把这些相对独立的元素放在不同的图层中,这样方便以后的再编辑。不过图层一多,就 显得很凌乱&#xff0c…

赵本山:我的时代还没有结束 | Python告诉你

作者 | 丁彦军来源 | 恋习Python(ID: sldata2017)【AI科技大本营按】今年春晚的小品好看吗?没有了赵本山的春晚总觉得少了点什么,然而许久不登春晚舞台的本山大叔借着B站的东风证明了「你大爷还是你大爷」。最近很多人被“改革春…

038——VUE中组件之WEB开发中组件使用场景与定义组件的方式

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>组件之WEB开发中组件使用场景与定义组件的方式</title><script src"vue.js"></script> </head> <body> <…

IronPython系列:Composite Pattern及其实现

最近挺经常做鱼的。对于做鱼的步骤算是熟悉。以烤制为例&#xff0c;主要有三步&#xff1a;洗&#xff08;Clean&#xff09;、切&#xff08;Cut&#xff09;和烤&#xff08;Bake&#xff09;。烤鱼&#xff08;Bake&#xff09;又有两个小步&#xff1a;加热(Heat)和烤(Bak…

2019全球AI 100强,中国占独角兽半壁江山,但忧患暗存

整理 | apddd出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;日前&#xff0c;创投研究机构CB Insights发布了年度人工智能企业百强榜单——由100个最具前途的AI公司组成&#xff0c;它们从3000多个候选者中脱颖而出&#xff0c;其业务涵盖人工智能硬件、数据基础设施…

【linux】串口编程(三)——错误处理

一个程序的优劣&#xff0c;可以从多个角度来判断&#xff0c;错误处理就是其中之一。从代码中的错误处理部分&#xff0c;可以体现出一个程序员的水平和修养。 下面还是以libmodbus为例&#xff0c;总结下串口编程中的错误处理。 【1】基础 【1.1】modbus中错误处理有三种&a…

微服务实战之春云与刀客(三)—— 面向接口调用代码结构实例

2019独角兽企业重金招聘Python工程师标准>>> 概述 在上一篇中提到了spring cloud 面向接口调用的开发风格&#xff0c;这一篇会举一个简单的但完整的例子来说明整个代码结构。 代码已上传到 https://github.com/maruixiang/spring-cloud-demo/tree/master/demo1 代码…

如何创建复杂的机器学习项目?

翻译 | 光城责编 | 郭芮转载自CSDN&#xff08;CSDNnews&#xff09;scikit-learn提供最先进的机器学习算法。但是&#xff0c;这些算法不能直接用于原始数据。原始数据需要事先进行预处理。因此&#xff0c;除了机器学习算法之外&#xff0c;scikit-learn还提供了一套预处理方…

关闭vmware喇叭报警声

关闭vmware喇叭报警声 在vmware里面安装linux系统后&#xff0c;操作时经常使用tab键或使用VI时经常听到pc speaker突然叫一声&#xff0c;如果正当戴着耳机欣赏音乐&#xff0c;被这么一叫还要吓一跳。下面是解决办法&#xff1a;C:\Documents and Settings\All Users\Applica…

【ubuntu工具】Atom的简介及安装

Atom中文社区&#xff1a;https://atom-china.org/ 知乎atom&#xff1a;https://www.zhihu.com/question/22867204 Atom&#xff0c;是github用nodejs编写的一个编辑器 Atom安装步骤&#xff1a; sudo add-apt-repository ppa:webupd8team/atomsudo aptitude updatesudo a…

破解Win2008口令-ERD6.0

我们在日常使用计算机的过程中&#xff0c;大多都经历过由于忘记口令从而无法进入系统的遭遇。遇到这种问题该如何处理呢&#xff1f;很多朋友一定想到了形形的口令破解工具&#xff0c;这些工具中名气最大的就是ERD Commander Boot CD。 ERD Commander Boot CD是一张可以启动操…

【Qt】Qt5.9.0: error: GL/gl.h: 没有那个文件或目录

重新安装ubuntu&#xff0c;在编译Qt时报错&#xff1a; /home/Qt5.9.0/Examples/Qt-5.9/widgets/widgets/calculator/button.cpp:51: from …/calculator/button.cpp:51: /home/Qt5.9.0/5.9/gcc_64/include/QtGui/qopengl.h:139: error: GL/gl.h: 没有那个文件或目录 解决方…

给Chrome“捉虫”16000个,Google开源bug自检工具

整理 | 一一出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 在内部开发和使用八年之久&#xff0c;近日&#xff0c;Google 宣布开源 bug 自动化检测工具 ClusterFuzz。ClusterFuzz 是一款提供端到端的自动化模糊测试工具&#xff1a;从错误检测到分类排查&…

小巧的日志记录组件 - 开源研究系列文章

今天给大家带来一个小巧的日志记录组件LogHelper。这个组件是由Log4Net这个组件的由来而来的&#xff0c;不过只是写入.txt文本文件而已。如果能够对大家的项目有帮助那就更好了。 首先&#xff0c;打开.SLN解决方案&#xff0c;添加引用日志组件。 然后&#xff0c;先对日志组…

.NET开发人员值得关注的七个开源项目

微软近几年在.NET社区开源项目方面投入了相当多的时间和资源&#xff0c;不禁让原本对峙的开源社区阵营大吃一惊&#xff0c;从微软.NET社区中的反应来看&#xff0c;微软.NET开发阵营对开源工具的依赖正日益增强&#xff0c;本文就为所有.NET开发人员介绍7个应该关注的开源项目…

SystemTap了解

SystemTrap是监控和跟踪运行中的Linux内核操作的动态方法。 http://www.ibm.com/developerworks/cn/linux/l-systemtap/ 使用SystemTrap需要使用trap来运行一个stp脚本 如何安装&#xff1a; Centos下直接yum install systemtrap就行了 测试是否可以运行 运行&#xff1a;stap …

Windows 95被做成了App,可玩扫雷和纸牌

6 秒重温 Windows95 开机画面 作者 | 琥珀 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; “看到 Win95&#xff0c;再看到仙剑 DOS 的画面&#xff0c;突然有种想哭的感觉&#xff0c;小时候帮李逍遥实现了仗剑江湖的愿望&#xff0c;但自己却没有实现自己的愿望…

【Ubuntu】虚拟机VirtualBox安装win7完整步骤

在Ubuntu16.04中使用VirtualBox安装win7&#xff0c;亲测可以完美使用; 完整步骤参见如下链接&#xff1a; 1、VirtualBox安装步骤&#xff1a;http://www.xitongcheng.com/jiaocheng/xtazjc_article_23804.html 2、win7镜像下载&#xff1a;http://www.xitongcheng.com/jia…

全栈AI工程师指南,DIY一个识别手写数字的web应用

作者 | shadow chi本文经授权转载自 无界社区mixlab&#xff08;ID&#xff1a;mix-lab&#xff09;网上大量教程都是教如何训练模型&#xff0c;往往我们只学会了训练模型&#xff0c;而实际应用的环节是缺失的。def AIFullstack&#xff08; &#xff09;&#xff1a;本文从「…