Python实现12306自动查票程序
2018-01-04 00:15
435 查看
这是在网上扒拉过来的,原文链接:http://blog.csdn.net/An_Feng_z/article/details/78631290目前时间2018/01/04文中各种接口均为可用,亲测[b]↓↓↓↓↓以下正文↓↓↓↓↓[/b]首先在买票前我们需要先确认是否有票,那么进行正常的查票,打开12306查票网站输入出发地和目的地进行搜索。那么一般在看到这个页面的时候我们能想到的获取车次及相关信息的方式是什么呢?对于零基础的同学而言第一时间就会想到在源代码里面找,但这里事实上源代码里面根本没有相关内容,因为该请求是采用的js中ajax异步请求的方式动态加载的,并不包含在源代码里面,所以我们只能够通过抓包的方式来查看浏览器与服务器的数据交互情况,我用的是谷歌浏览器所以打开开发者工具的快捷键是
F12(crtl+alt+i),此时只要是浏览器和服务器发生数据交互都会在下面列表框显示出来,我们再次点击查询按钮。然后我们点击查询按钮以后浏览器向服务器发起了两次请求,那么我们来通过返回值分析下那个请求才是真正获取到车次相关数据的请求,以便我们用Python来模拟浏览器操作。第一次请求:很明显第一次请求返回的值没有我们需要的车次信息。第二次请求:第二次请求里面看到了很多数据,虽然我们暂时还没看到车次信息,但是我们发现它有个特性,就是有个列表的值里面有6个元素,而刚好我们搜索出来的从西安到达州的车辆也是6条数据,所以这两者肯定有一定关系,那么我们先用Python来获取到这些数据再进行下一步分析。#-*-coding:utf-8-*-
importurllib2
importssl
ssl._create_default_https_context=ssl._create_unverified_context
defgetList():
req=urllib2.Request('https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-07-10&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=CSQ&purpose_codes=ADULT')
req.add_header('User-Agent','Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/59.0.3071.115Safari/537.36')
html=urllib2.urlopen(req).read()
returnhtml
printgetList()
首先定义一个函数来获取车次列表信息。[/code]
从抓包数据中获取到该请求的。
url:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-07-10&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=CSQ&purpose_codes=ADULT为了防止被12306检测到屏蔽我们的请求那么我们可以简单的增加个头信息来模拟浏览器的请求。
url:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-07-10&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=CSQ&purpose_codes=ADULT
为了防止被12306检测到屏蔽我们的请求那么我们可以简单的增加个头信息来模拟浏览器的请求。
req.add_header(‘User-Agent’,’Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/59.0.3071.115Safari/537.36’)
F12(crtl+alt+i),此时只要是浏览器和服务器发生数据交互都会在下面列表框显示出来,我们再次点击查询按钮。
importurllib2
importssl
ssl._create_default_https_context=ssl._create_unverified_context
defgetList():
req=urllib2.Request('https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-07-10&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=CSQ&purpose_codes=ADULT')
req.add_header('User-Agent','Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/59.0.3071.115Safari/537.36')
html=urllib2.urlopen(req).read()
returnhtml
printgetList()
首先定义一个函数来获取车次列表信息。[/code]
从抓包数据中获取到该请求的。
url:
url:
为了防止被12306检测到屏蔽我们的请求那么我们可以简单的增加个头信息来模拟浏览器的请求。
req.add_header(‘User-Agent’,’Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/59.0.3071.115Safari/537.36’)
其中的
ssl._create_default_https_context=ssl._create_unverified_context
是因为12306采用的是https协议,而ssl证书是它自己做的并没有得到浏览器的认可,所以Python默认是不会请求不受信任的证书的网站的,我们可以通过这行代码来关闭掉证书的验证。
那么我们先来看看能不能正常获取到我们想要的信息。
返回的数据是json格式,但是Python标准数据类型中没有json这个类型,所以对于Python而言它就是个字符串,如果要非常方便的操作这个json我们就可以借助Python中的json这个包来把json这个字符串变成dict类型,然后通过dict的键值对操作方法把列表取出来并进行返回。
importurllib2
importssl
importjson
ssl._create_default_https_context=ssl._create_unverified_context
defgetList():
req=urllib2.Request('https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-07-10&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=CSQ&purpose_codes=ADULT')
req.add_header('User-Agent','Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/59.0.3071.115Safari/537.36')
html=urllib2.urlopen(req).read()
dict=json.loads(html)
result=dict['data']['result']
returnresult
最终返回的是一个list数据,我们先把这个数据for出来再看看每一条数据都有些什么东西。
printi
for出来之后我们先来看看第一条数据是什么样的:
|预定|76000G131805|G1318|ICW|IZQ|ICW|CWQ|07:54|18:54|11:00|N|UHESFcaIDeX22Z0zWfqttDuZXJFuWPdIa148i6TNk5spIqfp|20170710|3|W2|01|16|0|0|||||||||||无|无|无||O0M090|OM9
其实我们稍微留一下就会发现里面有包含G1318,07:54,18:54,无这样的车次信息的,只不过看起来比较乱,但是他们都有一个特点,每个数据都是由|这个符号分开的,所以我们可以通过用|分割看看能发现什么呢?
foriingetList():
fornini.split('|'):
printn
break
foriingetList():
fornini.split('|'):
print'[%s]%s'%(c,n)
c+=1
c=0
break
#索引3=车次
#索引8=出发时间
#索引9=到达时间
先找到出发站和到达站的参数分别是:leftTicketDTO.from_station=CDWleftTicketDTO.to_station=CSQ然而通过查找和分析我并没有发现这两个参数有规律,那么也就是说这两个值是在之前的请求里面就已经获取到了的,通过检查网页源代码没有找到,那么又只能通过抓包的方式来找。
在抓包过程中找到了一个包的返回值是附带有各城市的代号的,url如下:
foriincons.station_names.split('@'):
ifi:
tmp=i.split('|')
station[tmp[1]]=tmp[2]
\#printstation
train_date=raw_input('请输入出发时间')
from_station=station[raw_input('请输入出发城市')]
to_station=station[raw_input('请输入到达城市')]
到这里就已经能够通过输入“时间,城市”获取相应的车次信息了
相关文章推荐
- python实现的ftp自动上传下载程序(支持目录递归操作)----转
- python 实现自动上传文件到百度网盘(附程序源码及实现过程)
- python+soket实现 TCP 协议的客户/服务端中文(自动回复)聊天程序
- python之12306自动查票
- Python案例之QQ空间自动登录程序实现
- python自动登录12306并自动点击验证码完成登录的实现源代码
- python自动12306抢票软件实现代码
- 基于Python 3.4 实现的12306查票器
- Python实现博客日志自动提交程序
- Python实现的一个自动售饮料程序代码分享
- python编写小程序,模拟实现自动按下键盘
- python实现自动重启本程序的方法
- Python脚本生成的exe文件自动升级程序实现方法
- 自动求导程序的设计与实现(Python)
- python实现12306抢票及自动邮件发送提醒付款功能
- python实现微信小程序自动回复
- Python突破12306最后一道防线,实现自动抢票(附源码)
- python实现自动重启本程序的方法
- Python实现的一个自动售饮料程序代码分享
- Python_猜数字游戏_初次尝试(遗留问题:猜错后程序自动循环执行未实现)---加入循环搞定