返回顶部
首页 > 资讯 > 后端开发 > Python >教你用python实现12306余票查询
  • 222
分享到

教你用python实现12306余票查询

2024-04-02 19:04:59 222人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

python实现12306余票查询 我们说先在浏览器中打开开发者工具(F12),尝试一次余票的查询,通过开发者工具查看发出请求的包 余票查询界面 可以看到红框框中的URL就是我们向

python实现12306余票查询

我们说先在浏览器中打开开发工具(F12),尝试一次余票的查询,通过开发者工具查看发出请求的包

余票查询界面

可以看到红框框中的URL就是我们向12306服务器发出的请求,那么具体是什么呢?我们来看看

[
https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2019-01-21&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=SZQ&purpose_codes=ADULT](Https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2019-01-21&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=SZQ&purpose_codes=ADULT)

可以看到发出请求的几个字段:

leftTicketDTO.train_date:查询的日期
leftTicketDTO.from_station:查询的出发地
leftTicketDTO.to_station:查询的目的地
purpose_codes:不太清楚这个字段是用来做什么的,就默认吧

可以从我们递交的URL请求看出,我们输入的成都,深圳都变成了对应的编号,比如,成都(CDW)、深圳(SZQ),所以当我们程序进行输入的时候要进行一下处理,12306的一个地方存储着这些城市名与编码对应的文档:

[
https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971](https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971)

站点编码对应

下面我们就编写一个小程序,将这些城市名与编号提取出来:


    import re,requests
    url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971"
    response = requests.get(url,verify=False)
    #将车站的名字和编码进行提取
    chezhan = re.findall(r'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)
    chezhan_code = dict(chezhan)
    #进行交换
    chezhan_names = dict(zip(chezhan_code.values(),chezhan_code.keys()))
    #打印出得到的车站字典
    print(chezhan_names)

得到的打印结果如下(只截取部分显示):

{‘VAP': ‘北京北', ‘BOP': ‘北京东', ‘BJP': ‘北京', ‘VNP': ‘北京南', ‘BXP': ‘北京西', ‘IZQ':
‘广州南', ‘CUW': ‘重庆北', ‘CQW': ‘重庆', ‘CRW': ‘重庆南', ‘CXW': ‘重庆西', ‘GGQ': ‘广州东',
‘SHH': ‘上海', ‘SNH': ‘上海南', ‘AOH': ‘上海虹桥', ‘SXH': ‘上海西', ‘TBP': ‘天津北', ‘TJP':
‘天津', ‘TIP': ‘天津南', ‘TXP': ‘天津西', ‘XJA': ‘香港西九龙', ‘CCT': ‘长春', ‘CET': ‘长春南',
‘CRT': ‘长春西', ‘ICW': ‘成都东', ‘CNW': ‘成都南', ‘CDW': ‘成都', ‘CSQ': ‘长沙', ‘CWQ':
‘长沙南',}

接下来我们就动手开始程序的主要代码编写:


    def main():
      date     = input("请输入时间(如2019-01-22):\n")
      from_station = chezhan_code[input("请输入起始站点:\n")]
      to_station  = chezhan_code[input("请输入目的站点:\n")]
      url     = "https://kyfw.12306.cn/otn/leftTicket/queryZ?"
      headers = {
        "User-Agent": "Mozilla/5.0 (windows NT 6.1; WOW64) AppleWEBKit/537.36 (Khtml, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5702.400 QQBrowser/10.2.1893.400"
      }
      url=url+"leftTicketDTO.train_date="+date+"&leftTicketDTO.from_station="+from_station+"&leftTicketDTO.to_station="+to_station+"&purpose_codes=ADULT"
      #print(url) 已经检查过生成的URL是正确的
      #request请求获取主页
      r = requests.get(url,headers=headers)
      r.raise_for_status()  #如果发送了一个错误的请求,会抛出异常
      r.encoding = r.apparent_encoding
      showTicket(r.text)

用户输入时间、起始站点、目的站点,然后通过get来请求,然后我们对返回的网页信息进行解析。我们现将上面代码的r.text进行打印,看看我们请求之后,返回了什么样的信息,然后决定我们应该如何解析

运行结果

这样看着不方便,我们粘贴到记事本中,进行详细的分析:

请求返回的结果信息

可以与12306显示的信息进行对比,K829是车次,CDW与BJQ是出发地和目的地,10:10是出发时间,06:13是到达时间,44:21是历时时间,20190123为查询的日期,剩下的就是一系列票的各种信息。

下面就是对这些返回的信息进行解析,其实这也是python爬虫的关键,就是解析!!!

我们先把信息转化为JSON格式,可以看到都是用“|”隔开的,那么我们就用split函数分割出来,下面是主要功能代码:


    def showTicket(html):
      html = json.loads(html)
      table = PrettyTable([" 车次 ","出发车站","到达车站","出发时间","到达时间"," 历时 ","商务座"," 一等座","二等座","高级软卧","软卧","动卧","硬卧","软座","硬座","无座","其他","备注"])
      for i in html['data']['result']:
        name = [
              "station_train_code",
              "from_station_name",
              "to_station_name",
              "start_time",
              "arrive_time",
              "lishi",
              "swz_num",
              "zy_num",
              "ze_num",
              "dw_num",
              "gr_num",
              "rw_num",
              "yw_num",
              "rz_num",
              "yz_num",
              "wz_num",
              "Qt_num",
              "note_num"
            ]
        data = {
              "station_train_code": '',
              "from_station_name": '',
              "to_station_name": '',
              "start_time": '',
              "arrive_time": '',
              "lishi": '',
              "swz_num": '',
              "zy_num": '',
              "ze_num": '',
              "dw_num": '',
              "gr_num": '',
              "rw_num": '',
              "yw_num": '',
              "rz_num": '',
              "yz_num": '',
              "wz_num": '',
              "qt_num": '',
              "note_num": ''
            }
        #将各项信息提取并赋值
        item = i.split('|')                 #使用“|”进行分割
        data["station_train_code"] = item[3]        #获取车次信息,在3号位置
        data["from_station_name"]  = item[6]        #始发站信息在6号位置
        data["to_station_name"]   = item[7]        #终点站信息在7号位置
        data["start_time"]     = item[8]        #出发时间在8号位置
        data["arrive_time"]     = item[9]        #抵达时间在9号位置
        data["lishi"]        = item[10]       #经历时间在10号位置
        data["swz_num"]       = item[32] or item[25] #特别注意,商务座在32或25位置
        data["zy_num"]       = item[31]       #一等座信息在31号位置
        data["ze_num"]       = item[30]       #二等座信息在30号位置
        data["gr_num"]       = item[21]       #高级软卧信息在21号位置
        data["rw_num"]       = item[23]       #软卧信息在23号位置
        data["dw_num"]       = item[27]       #动卧信息在27号位置
        data["yw_num"]       = item[28]       #硬卧信息在28号位置
        data["rz_num"]       = item[24]       #软座信息在24号位置
        data["yz_num"]       = item[29]       #硬座信息在29号位置
        data["wz_num"]       = item[26]       #无座信息在26号位置
        data["qt_num"]       = item[22]       #其他信息在22号位置
        data["note_num"]      = item[1]        #备注信息在1号位置
        color = Colored()
        data["note_num"] = color.white(item[1])
        #如果没有信息,那么就用“-”代替
        for pos in name:
          if data[pos] == "":
            data[pos] = "-"
        tickets = []
        cont = []
        cont.append(data)
        for x in cont:
          tmp = []
          for y in name:
            if y == "from_station_name":
              s = color.green(chezhan_names[data["from_station_name"]])
              tmp.append(s)
            elif y == "to_station_name":
              s = color.red(chezhan_names[data["to_station_name"]])
              tmp.append(s)
            elif y == "start_time":
              s = color.green(data["start_time"])
              tmp.append(s)
            elif y == "arrive_time":
              s = color.red(data["arrive_time"])
              tmp.append(s)
            elif y == "station_train_code":
              s = color.yellow(data["station_train_code"])
              tmp.append(s)
            else:
              tmp.append(data[y])
          tickets.append(tmp)
        for ticket in tickets:
          table.add_row(ticket)
      print(table)

那么我们程序就成功啦!!!

运行结果

但是在编译器里面Prettytable的格子没有对齐,不要担心,我们到终端运行一下脚本,就可以看到很好看的输出啦:

终端运行结果

完成!!!下面是完整代码

main.py


    # -*- coding: utf-8 -*-
    import re,requests,datetime,time,json
    from prettytable import PrettyTable
    from colorama import init,Fore
    from stationinfo import chezhan_code,chezhan_names
    init(autoreset=False)
    class Colored(object):
      def yeah(self,s):
        return Fore.LIGHTCYAN_EX + s + Fore.RESET
      def green(self,s):
        return Fore.LIGHTGREEN_EX + s + Fore.RESET
      def yellow(self,s):
        return Fore.LIGHTYELLOW_EX + s + Fore.RESET
      def white(self,s):
        return Fore.LIGHTWHITE_EX + s + Fore.RESET
      def blue(self,s):
        return Fore.LIGHTBLUE_EX + s + Fore.RESET
    def showTicket(html):
      html = json.loads(html)
      table = PrettyTable([" 车次 ","出发车站","到达车站","出发时间","到达时间"," 历时 ","商务座"," 一等座","二等座","高级软卧","软卧","动卧","硬卧","软座","硬座","无座","其他","备注"])
      for i in html['data']['result']:
        name = [
              "station_train_code",
              "from_station_name",
              "to_station_name",
              "start_time",
              "arrive_time",
              "lishi",
              "swz_num",
              "zy_num",
              "ze_num",
              "dw_num",
              "gr_num",
              "rw_num",
              "yw_num",
              "rz_num",
              "yz_num",
              "wz_num",
              "qt_num",
              "note_num"
            ]
        data = {
              "station_train_code": '',
              "from_station_name": '',
              "to_station_name": '',
              "start_time": '',
              "arrive_time": '',
              "lishi": '',
              "swz_num": '',
              "zy_num": '',
              "ze_num": '',
              "dw_num": '',
              "gr_num": '',
              "rw_num": '',
              "yw_num": '',
              "rz_num": '',
              "yz_num": '',
              "wz_num": '',
              "qt_num": '',
              "note_num": ''
            }
        #将各项信息提取并赋值
        item = i.split('|')                 #使用“|”进行分割
        data["station_train_code"] = item[3]        #获取车次信息,在3号位置
        data["from_station_name"]  = item[6]        #始发站信息在6号位置
        data["to_station_name"]   = item[7]        #终点站信息在7号位置
        data["start_time"]     = item[8]        #出发时间在8号位置
        data["arrive_time"]     = item[9]        #抵达时间在9号位置
        data["lishi"]        = item[10]       #经历时间在10号位置
        data["swz_num"]       = item[32] or item[25] #特别注意,商务座在32或25位置
        data["zy_num"]       = item[31]       #一等座信息在31号位置
        data["ze_num"]       = item[30]       #二等座信息在30号位置
        data["gr_num"]       = item[21]       #高级软卧信息在21号位置
        data["rw_num"]       = item[23]       #软卧信息在23号位置
        data["dw_num"]       = item[27]       #动卧信息在27号位置
        data["yw_num"]       = item[28]       #硬卧信息在28号位置
        data["rz_num"]       = item[24]       #软座信息在24号位置
        data["yz_num"]       = item[29]       #硬座信息在29号位置
        data["wz_num"]       = item[26]       #无座信息在26号位置
        data["qt_num"]       = item[22]       #其他信息在22号位置
        data["note_num"]      = item[1]        #备注信息在1号位置
        color = Colored()
        data["note_num"] = color.white(item[1])
        #如果没有信息,那么就用“-”代替
        for pos in name:
          if data[pos] == "":
            data[pos] = "-"
        tickets = []
        cont = []
        cont.append(data)
        for x in cont:
          tmp = []
          for y in name:
            if y == "from_station_name":
              s = color.green(chezhan_names[data["from_station_name"]])
              tmp.append(s)
            elif y == "to_station_name":
              s = color.yeah(chezhan_names[data["to_station_name"]])
              tmp.append(s)
            elif y == "start_time":
              s = color.green(data["start_time"])
              tmp.append(s)
            elif y == "arrive_time":
              s = color.yeah(data["arrive_time"])
              tmp.append(s)
            elif y == "station_train_code":
              s = color.yellow(data["station_train_code"])
              tmp.append(s)
            else:
              tmp.append(data[y])
          tickets.append(tmp)
        for ticket in tickets:
          table.add_row(ticket)
      print(table)
    def main():
      date     = input("请输入时间:\n")
      from_station = chezhan_code[input("请输入起始站点:\n")]
      to_station  = chezhan_code[input("请输入目的站点:\n")]
      url     = "https://kyfw.12306.cn/otn/leftTicket/queryZ?"
      headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5702.400 QQBrowser/10.2.1893.400"
      }
    url=url+"leftTicketDTO.train_date="+date+"&leftTicketDTO.from_station="+from_station+"&leftTicketDTO.to_station="+to_station+"&purpose_codes=ADULT"
      #print(url) 已经检查过生成的URL是正确的
      #request请求获取主页
      r = requests.get(url,headers=headers)
      r.raise_for_status()  #如果发送了一个错误的请求,会抛出异常
      r.encoding = r.apparent_encoding
      showTicket(r.text)
      #print(r.text)
    main()

stationinfo.py


    import re,requests
    url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971"
    response = requests.get(url,verify=False)
    #将车站的名字和编码进行提取
    chezhan = re.findall(r'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)
    chezhan_code = dict(chezhan)
    chezhan_names = dict(zip(chezhan_code.values(),chezhan_code.keys()))
    #print(chezhan_names)

到此这篇关于教你用Python实现12306余票查询的文章就介绍到这了,更多相关python实现12306余票查询内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 教你用python实现12306余票查询

本文链接: https://lsjlt.com/news/129465.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 教你用python实现12306余票查询
    python实现12306余票查询 我们说先在浏览器中打开开发者工具(F12),尝试一次余票的查询,通过开发者工具查看发出请求的包 余票查询界面 可以看到红框框中的URL就是我们向...
    99+
    2024-04-02
  • python实现12306火车票查询器
    12306火车票购票软件大家都用过,怎么用Python写一个命令行的火车票查看器,要求在命令行敲一行命令来获得你想要的火车票信息,下面通过本文学习吧。 Python火车票查询器 接口设置 先给这个小应...
    99+
    2022-06-04
    火车票 查询器 python
  • Python脚本实现12306火车票查询系统
    最近我看到看到使用python实现火车票查询,我自己也实现了,感觉收获蛮多的,下面我就把每一步骤都详细给分享出来。(注意使用的是python3) 首先我将最终结果给展示出来: 在cmd命令行执行:pytho...
    99+
    2022-06-04
    查询系统 火车票 脚本
  • Python 实现的12306抢票脚本
    Python12306抢票脚本 本脚本使用一个类来实现所有代码,大体上分为以下几个模块及其步骤:- 初始化对象属性(在抢票前进行的属性初始化,包括初始化浏览器模拟对象,个人信息等)。- 建立模拟浏览器,模拟浏览器进行cookie等存储。...
    99+
    2023-01-30
    脚本 Python
  • python爬虫实现最新12306抢票
    1.环境 python 3.7谷歌浏览器chromedriver.exe(浏览器驱动程序,要与浏览器版本对应,并将其添加到环境变量或放到当前py文件所在目录下) 2.相关模块 tim...
    99+
    2024-04-02
  • Python实现12306自动抢火车票功能
    目录一、效果展示二、代码详解1 导入库2 确定好购票基本信息3 登录123064 模拟滑动滑块5 处理疫情特殊要求6 点击购票并填写出发地、目的地、出发时间7 锁定车票大家有没有这种...
    99+
    2024-04-02
  • 如何使用python爬虫实现最新12306抢票
    这篇文章将为大家详细讲解有关如何使用python爬虫实现最新12306抢票,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.环境python 3.7谷歌浏览器chromedriver.exe(浏览器驱动程...
    99+
    2023-06-26
  • Python如何实现12306自动抢火车票功能
    这篇文章将为大家详细讲解有关Python如何实现12306自动抢火车票功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、效果展示在正式进入代码讲解之前,先来看下本文的实现效果。如果不是为了演示效果,直...
    99+
    2023-06-22
  • 使用Python实现火车票查询系统(带界面)
    目录导语一、运行环境二、代码展示三、效果展示导语 周末、假期来了,七夕也快到了,又到一年中最一票难求的时候了! 那些假期想回家、过节异地恋的小可爱们,能准时抢到回家(约会对象)的城市...
    99+
    2024-04-02
  • 教你使用mongoose实现多集合关联查询
    目录关联查询(一对一)关联查询(一对多)1.聚合查询方式:2.虚拟字段查询方式总结在使用node开发后端项目的时候,通常会选择mongodb作为数据库,而使用mongodb通常是选择...
    99+
    2024-04-02
  • Python使用面向对象方式创建线程实现12306售票系统
    目前python 提供了几种多线程实现方式 thread,threading,multithreading ,其中thread模块比较底层,而threading模块是对thread做了一些包装,可以更加方便...
    99+
    2022-06-04
    线程 面向对象 方式
  • 教你用Python查看茅台股票交易数据的详细代码
    我突然很好奇,你说那些什么18几年的茅台真的是18几年就开始酿的吗?还有就是一个月要卖那么多,货是怎么供过来的?最后就是,一瓶那么贵,那一个月赚多少?好多的疑问啊,就用Python揭...
    99+
    2024-04-02
  • python如何实现查询
    这篇文章主要为大家展示了“python如何实现查询”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“python如何实现查询”这篇文章吧。查询排序和查询都是好基友,长的数据结构里面(字典,列表)里面...
    99+
    2023-06-16
  • Python利用wxPython制作股票价格查询工具
    目录效果如下所示简介源代码源代码说明效果如下所示 简介 在当今信息时代,金融市场是一个引人注目的话题。作为普通人,我们也可以通过使用 Python 和 wxPython 库编写一个...
    99+
    2023-05-19
    Python wxPython实现股票价格查询工具 Python wxPython股票价格查询 Python wxPython 查询工具
  • python中如何实现查询
    这篇文章主要介绍python中如何实现查询,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!查询1) 查询函数的参数当我们想要知道某个函数会接收哪些参数的时候,可以使用下面方法查询。im...
    99+
    2024-04-02
  • 教你用Python实现Excel表格处理
    目录一、文件二、代码三、分析四、pd.ExcelFile五、总结一、文件 一个测试有两个sheet页的Excel测试文件 test.xlsx 二、代码 import panda...
    99+
    2024-04-02
  • 利用python实现万年历的查询
    今天要用python做一个小功能,那就是实现万年历的查询。 首先看一下整体感觉 实现代码: def is_leap_year(year): if year/4==0 an...
    99+
    2024-04-02
  • 利用Python实现命令行版的火车票查看器
    接口设计 一个应用写出来最终是要给人使用的,哪怕只是给你自己使用。所以,首先应该想想你希望怎么使用它?让我们先给这个小应用起个名字吧,既然及查询票务信息,那就叫它tickets好了。我们希望用户只要输入出发...
    99+
    2022-06-04
    命令行 火车票 查看器
  • 一文教会你用mybatis查询数据库数据
    目录一、新建数据库和表二、新建maven项目,添加mybatis依赖三、新建实体类、接口(Mapper)四、新建实现类(使用.xml映射文件)五、新建全局配置文件(mybatis-c...
    99+
    2024-04-02
  • Python实现天气查询软件
    目录一、背景二、工具三、代码解读四、完整代码一、背景 某天下班淋雨成了落汤鸡,发了个朋友圈感慨一下啊,然后...... 夜深人静之时,突然收到了来自学妹的Py文件,运行之后发现事情并...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作