美文网首页python开发@IT·互联网程序员
12306抢票脚本开发(三)实现一个简单的查询脚本

12306抢票脚本开发(三)实现一个简单的查询脚本

作者: 王一航 | 来源:发表于2017-02-23 18:22 被阅读3454次

    文章地址 :

    12306抢票脚本开发(一)提纲
    12306抢票脚本开发(二)解析火车站代号并分析查询的HTTP请求
    12306抢票脚本开发(三)实现一个简单的查询脚本
    12306抢票脚本开发(四)完善上节课的代码并面向对象
    12306抢票脚本开发(五)更友好的使用方式
    12306抢票脚本开发(六)更友好的时间输入方式
    12306抢票脚本开发(七)将前几节课的成果结合起来实现一个完整的工具


    简介 :

    根据上节课的分析 , 我们已经知道了查询余票的接口的参数 :

    https://kyfw.12306.cn/otn/leftTicket/query?
    leftTicketDTO.train_date=2017-02-23&
    leftTicketDTO.from_station=BJP&
    leftTicketDTO.to_station=SHH&
    purpose_codes=ADULT
    很简单 , 四个参数 : 
    leftTicketDTO.train_date : 出发日期
    leftTicketDTO.from_station : 出发站的代号
    leftTicketDTO.to_station : 到达站的代号
    purpose_codes : ADULT 表示成人票 , 改变选项为学生票可以发现该参数的值变成了 : 0X00
    

    这样的话 , 我们就可以来写一个函数模拟这个接口 :

    #!/usr/bin/env python
    # encoding:utf-8
    
    import requests
    
    def buildQueryUrl(train_date, station_from, station_to, purpose_code):
        url = "https://kyfw.12306.cn/otn/leftTicket/query?"
        url += "leftTicketDTO.train_date=" + train_date
        url += "&leftTicketDTO.from_station=" + station_from
        url += "&leftTicketDTO.to_station=" + station_to
        url += "&purpose_codes=" + purpose_code
        return url
    
    def main():
        print buildQueryUrl("2017-02-23", "BJP", "SHH", "ADULT")
        print buildQueryUrl("2017-02-23", "BJP", "SHH", "0X00")
    
    if __name__ == "__main__":
        main()
    

    运行结果 :

    Paste_Image.png

    访问一下 :

    Paste_Image.png

    呣~Good
    让我们现在快乐地解析 json 吧 , 根据上节课猜的字段名 , 找出几个比较重要的字段 :

    "start_station_name": "北京南", # 始发站火车站名
    "end_station_name": "上海虹桥", # 终点站火车站名
    "from_station_name": "北京南", # 乘客上车的站的名称
    "to_station_name": "上海虹桥", # 乘客下车的站的名称
    "start_time": "19:00", # 开车时间
    "arrive_time": "23:56", # 到达时间
    "gg_num": "--", # 
    "gr_num": "--", # 高级软卧
    "qt_num": "--", # 其他
    "rw_num": "--", # 软卧
    "rz_num": "--", # 软座
    "tz_num": "--", # 特等座
    "wz_num": "--", # 无座
    "yb_num": "--", # 
    "yw_num": "--", # 硬卧
    "yz_num": "--", # 硬座
    "ze_num": "有", # 二等座
    "zy_num": "10", # 一等座
    "swz_num": "8" # 商务座
    # 这里有两个字段实在不知道是干啥的 ... 先搁置吧 ...
    

    继续码代码 :

    #!/usr/bin/env python
    # encoding:utf-8
    
    import json
    import requests
    import logging
    
    logging.captureWarnings(True)
    
    def getStartStationName(jsonContent):
        return jsonContent["queryLeftNewDTO"]["start_station_name"]
    
    def getEndStationName(jsonContent):
        return jsonContent["queryLeftNewDTO"]["end_station_name"]
    
    def getFromStationName(jsonContent):
        return jsonContent["queryLeftNewDTO"]["from_station_name"]
    
    def getToStationName(jsonContent):
        return jsonContent["queryLeftNewDTO"]["to_station_name"]
    
    def getStartTime(jsonContent):
        return jsonContent["queryLeftNewDTO"]["start_time"]
    
    def getArriveTime(jsonContent):
        return jsonContent["queryLeftNewDTO"]["arrive_time"]
    
    def getQitaNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["qt_num"]
    
    def getWuzuoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["wz_num"]
    
    def getYingzuoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["yz_num"]
    
    def getYingwoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["yw_num"]
    
    def getRuanzuoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["rz_num"]
    
    def getRuanwoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["rw_num"]
    
    def getGaojiruanwoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["gr_num"]
    
    def getErdengzuoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["ze_num"]
    
    def getYidengzuoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["zy_num"]
    
    def getTengdengzuoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["tz_num"]
    
    def getShangwuzuoNumber(jsonContent):
        return jsonContent["queryLeftNewDTO"]["swz_num"]
    
    url = "https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-02-23&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT"
    content = requests.get(url, verify=False).text.encode("UTF-8")
    jsonContent = json.loads(content)
    for i in jsonContent["data"]:
        print "=" * 36
        print "始发站 : ", getStartStationName(i)
        print "终点站 : ", getEndStationName(i)
        print "起始站 : ", getFromStationName(i)
        print "到达站 : ", getToStationName(i)
        print "发车时间 : ", getStartTime(i)
        print "到达时间 : ", getArriveTime(i)
        print "其他 : ", getQitaNumber(i)
        print "无座 : ", getWuzuoNumber(i)
        print "硬座 : ", getYingzuoNumber(i)
        print "硬卧 : ", getYingwoNumber(i)
        print "软座 : ", getRuanzuoNumber(i)
        print "软卧 : ", getRuanwoNumber(i)
        print "高级软卧 : ", getGaojiruanwoNumber(i)
        print "二等座 : ", getYidengzuoNumber(i)
        print "一等座 : ", getErdengzuoNumber(i)
        print "特等座 : ", getTengdengzuoNumber(i)
        print "商务座 : ", getShangwuzuoNumber(i)
    

    运行之后的效果 :

    Paste_Image.png

    总结和预告

    好了这节课就先到这里 , 下节课我们会继续完善这节课的代码
    下节课会将这些函数封装到一个类里面 , 方便之后调用 , 谢谢大家赏脸啦
    {:-)

    相关文章

      网友评论

      • 张贤同学:哥们,你是怎么找到那个json文件,我死活找不到呀,打开network窗口没看到,烦请给点线索或者关键字,不胜感激
        王一航:@斜川雨 这么说是因为有可能使用了 websocket , 目前的浏览器好像并不能监控 websocket 的数据 , 只能使用系统级的抓包工具
        王一航:@斜川雨 这样吧 , 你看要是实在不行就不用浏览器的开发者工具了 , 直接使用系统级的抓包工具 , 例如 tcpdump/wireshark 之类的
        王一航:@斜川雨 我当时在分析的时候是有一个 json 的 , 但是现在再用之前的脚本已经不好使了 , 所以我猜 12306 的接口已经发生了变化 , 具体怎么变得还没有分析过

      本文标题:12306抢票脚本开发(三)实现一个简单的查询脚本

      本文链接:https://www.haomeiwen.com/subject/rcbbwttx.html