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

2023-11-20 13:20

本文主要是介绍告别排队!用 Python 定时自动挂号和快捷查询化验报告,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

640?wx_fmt=jpeg

作者 | 阿文

出品 | 程序人生(ID:coder_life


1、我什么要做这个事情


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

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

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


2、实现自动挂号代码


于是就自己通过 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


3、命令行式输出化验单到 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 之类的表格里面进行统计分析每次的指标变化。


4、最后


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

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


福利

公众号后台回复:2018Python,获取2018Python开源项目Top100整理资料!或扫码添加小助手微信,回复:1,入群获取。

640?wx_fmt=jpeg


推荐阅读:


  • 2019最新实战!给程序员的7节深度学习必修课,最好还会Python!

  • 2:0!谷歌 AI “AlphaStar“ 虐杀职业星际玩家

  • 斗图?教你用Python制作表情包

  • 啥是佩奇排名算法

  • 用Python全自动下载漂亮小姐姐的抖音视频!

  • PDF翻译神器,再也不担心读不懂英文Paper了

  • 算法工程师必须要知道的面试技能雷达图

  • 100+Python编程练习题~

  • PDF翻译神器,再也不担心读不懂英文Paper了


640?wx_fmt=png

这篇关于告别排队!用 Python 定时自动挂号和快捷查询化验报告的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/394883

相关文章

Python运行中频繁出现Restart提示的解决办法

《Python运行中频繁出现Restart提示的解决办法》在编程的世界里,遇到各种奇怪的问题是家常便饭,但是,当你的Python程序在运行过程中频繁出现“Restart”提示时,这可能不仅仅是令人头疼... 目录问题描述代码示例无限循环递归调用内存泄漏解决方案1. 检查代码逻辑无限循环递归调用内存泄漏2.

pytorch自动求梯度autograd的实现

《pytorch自动求梯度autograd的实现》autograd是一个自动微分引擎,它可以自动计算张量的梯度,本文主要介绍了pytorch自动求梯度autograd的实现,具有一定的参考价值,感兴趣... autograd是pytorch构建神经网络的核心。在 PyTorch 中,结合以下代码例子,当你

Python中判断对象是否为空的方法

《Python中判断对象是否为空的方法》在Python开发中,判断对象是否为“空”是高频操作,但看似简单的需求却暗藏玄机,从None到空容器,从零值到自定义对象的“假值”状态,不同场景下的“空”需要精... 目录一、python中的“空”值体系二、精准判定方法对比三、常见误区解析四、进阶处理技巧五、性能优化

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo

Python如何自动生成环境依赖包requirements

《Python如何自动生成环境依赖包requirements》:本文主要介绍Python如何自动生成环境依赖包requirements问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录生成当前 python 环境 安装的所有依赖包1、命令2、常见问题只生成当前 项目 的所有依赖包1、

如何将Python彻底卸载的三种方法

《如何将Python彻底卸载的三种方法》通常我们在一些软件的使用上有碰壁,第一反应就是卸载重装,所以有小伙伴就问我Python怎么卸载才能彻底卸载干净,今天这篇文章,小编就来教大家如何彻底卸载Pyth... 目录软件卸载①方法:②方法:③方法:清理相关文件夹软件卸载①方法:首先,在安装python时,下

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

python uv包管理小结

《pythonuv包管理小结》uv是一个高性能的Python包管理工具,它不仅能够高效地处理包管理和依赖解析,还提供了对Python版本管理的支持,本文主要介绍了pythonuv包管理小结,具有一... 目录安装 uv使用 uv 管理 python 版本安装指定版本的 Python查看已安装的 Python

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t