作者 | 阿文

来源 | 程序人生(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

执行脚本后结果:

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

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

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

代码如下:

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科技大本营转载文章,转载请联系原作者)

征稿

推荐阅读:

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

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

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

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

  • ProgPow:以太坊上浮世绘

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

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

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

  • “百练”成钢:NumPy 100练

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

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

  1. android 预约挂号代码_告别排队!用Python定时自动挂号和快捷查询化验报告

    作者 | 阿文 来源 | 程序人生(ID: coder_life) 我什么要做这个事情 去年单位体检查出问题来,经过穿刺手术确诊是个慢性肾脏病2期, IGA 肾病三期,可能大家对于这个病并不是很了解, ...

  2. android 预约挂号代码_还在医院苦苦排队挂号?Python定时自动挂号和快捷查询化验报告!...

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

  3. Python - 定时自动获取 Bing 首页壁纸

    一.引言 Bing 首页的壁纸好看且每日更新,下面介绍如何使用 python 每日自动获取壁纸并保存. 二.手动获取 自动获取前先介绍下如何手动获取,主要是了解壁纸的网页形式. 1.打开开发者模式 可 ...

  4. Python定时自动更换电脑壁纸

    周末好!难得放假,今天的你是不是一觉睡到大中午了?不要有愧疚感,现在的年轻人压力实在太大,好好睡上一觉已经是一件很奢侈的事情了,就给自己好好放个假吧! 在这难得的休闲时光,我们也不整那些太复杂的话题, ...

  5. python 定时自动爬取_python实现scrapy爬虫每天定时抓取数据的示例代码

    1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量 ...

  6. 用python定时自动发微博_用 Python 自动定时发微博

    其实小帅b已经挺久没有玩微博了,记得上次玩微博还是为了给周杰伦打榜,不过最近心血来潮,觉得俺的微博账号躺着也是躺着,要不就用 Python 做一个自动定时发微博的机器人,让它在上面飘一会. 怎么个飘法 ...

  7. python 定时自动爬取_python怎么定时爬取数据及将数据以邮件发送

    定时功能,即程序可以根据我们设定的时间自动爬取数据: 通知功能,即程序可以把爬取到的数据结果以邮件的形式自动发送到我们的邮箱. 程序分成三个功能块:[爬虫]+[邮件]+[定时]. 对爬虫部分,主要是获 ...

  8. 用python定时自动发微博_用python自动发微博

    --刚刚全部写完了点发布--结果什么都没保存--内心好忧伤. 终极目标是用raspberry pi + camera 捕捉画面,处理图像识别图中有我家主子(猫), 然后自动capture图像,发微博. ...

  9. 用python定时自动发微博_Python脚本实现自动发带图的微博

    要自动发微博最简单的办法无非是调用新浪微博的API(因为只是简单的发微博,就没必要用它的SDK了).参考开发文档http://open.weibo.com/wiki/API 进行代码编写 创建应用 要 ...

最新文章

  1. 无穷级数求和7个公式_双色球2019129期渗透围红蓝(6+1实战,附:7个双色球胆码公式)...
  2. 高级Java服务端工程师要求
  3. linux db2乱码,DB2乱码(开始和结束,字符串中间没有好的办法)
  4. Linux环境编程 用户层定时器使用一 timerfd的使用
  5. LINQ to SQL: DataContext.SubmitChanges() 失效问题
  6. CodeForces999E 双dfs // 标记覆盖 // tarjan缩点
  7. python及pycharm
  8. Jenkins+GitLab+Docker+SpringCloud+Kubernetes实现可持续自动化微服务
  9. android tmp目录权限不够,/tmp目录下执行脚本失败提示Permission denied
  10. python闹钟_用python做了个高级闹钟 欢迎借鉴
  11. [翻译]The Data Access Application Block
  12. CentOS7下Nginx 安装 Lua 支持
  13. 【EOS】2.2 发行Token,转移Token
  14. java poi导出Excel表格超大数据量解决方案
  15. 蓝色清爽可用做排行的侧边列表滑动门代码
  16. js es6 map 与 原生对象区别
  17. 方舟生存计划怎么删除服务器信息,方舟进化生存怎么删服务器存档
  18. php 句号,句号 - Programming Life - PHP博客
  19. 人工智能数学基础8:两个重要极限及夹逼定理
  20. android极简手机壁纸,极简桌面安卓版

热门文章

  1. showModalDialog关闭子窗口,并刷新父窗口
  2. 做行业研究时如何获取相关数据?
  3. java operators_Java Basic Operators
  4. [模拟]纺车的轮子 Spinning Wheels
  5. 对PInvoke函数函数调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。...
  6. “Assign Random Colors” is not working in 3ds Max 2015
  7. 【青少年编程】马雷越:商品价格竞猜
  8. 【怎样写代码】向现有类型“添加”方法 -- 扩展方法(二):扩展方法的实现与调用
  9. 如何利用离散Hopfield神经网络进行数字识别(1)
  10. 5个短小精悍的 Python 趣味脚本,太赞了,非常适合小白上手!