Python实现12306自动查票程序
这是在网上扒拉过来的,原文链接: http://blog.csdn.net/An_Feng_z/article/details/78631290
目前时间2018/01/04 文中各种接口均为可用,亲测
↓ ↓ ↓ ↓ ↓ 以下正文 ↓ ↓ ↓ ↓ ↓
首先在买票前我们需要先确认是否有票,那么进行正常的查票,打开12306查票网站输入出发地和目的地进行搜索。
那么一般在看到这个页面的时候我们能想到的获取车次及相关信息的方式是什么呢?对于零基础的同学而言第一时间就会想到在源代码里面找,但这里事实上源代码里面根本没有相关内容,因为该请求是采用的js中ajax异步请求的方式动态加载的,并不包含在源代码里面,所以我们只能够通过抓包的方式来查看浏览器与服务器的数据交互情况,我用的是谷歌浏览器所以打开开发者工具的快捷键是
F12(crtl+alt+i),此时只要是浏览器和服务器发生数据交互都会在下面列表框显示出来,我们再次点击查询按钮。
然后我们点击查询按钮以后浏览器向服务器发起了两次请求,那么我们来通过返回值分析下那个请求才是真正获取到车次相关数据的请求,以便我们用Python来模拟浏览器操作。
第一次请求:
很明显第一次请求返回的值没有我们需要的车次信息。
第二次请求:
第二次请求里面看到了很多数据,虽然我们暂时还没看到车次信息,但是我们发现它有个特性,就是有个列表的值里面有6个元素,而刚好我们搜索出来的从西安到达州的车辆也是6条数据,所以这两者肯定有一定关系,那么我们先用Python来获取到这些数据再进行下一步分析。
# -*- coding: utf-8 -*-
import urllib2
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
def getList():
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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36')
html = urllib2.urlopen(req).read()
return html
print getList()
首先定义一个函数来获取车次列表信息。
从抓包数据中获取到该请求的。
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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36’)
其中的
ssl._create_default_https_context =ssl._create_unverified_context
是因为12306采用的是https协议,而ssl证书是它自己做的并没有得到浏览器的认可,所以Python默认是不会请求不受信任的证书的网站的,我们可以通过这行代码来关闭掉证书的验证。
那么我们先来看看能不能正常获取到我们想要的信息。
事实证明我们的操作没有问题,接下来先拿到包含有6条数据的这个列表再说。
返回的数据是json格式,但是Python标准数据类型中没有json这个类型,所以对于Python而言它就是个字符串,如果要非常方便的操作这个json我们就可以借助Python中的json这个包来把json这个字符串变成dict类型,然后通过dict的键值对操作方法把列表取出来并进行返回。
# -*- coding: utf-8 -*-
import urllib2
import ssl
import json
ssl._create_default_https_context = ssl._create_unverified_context
def getList():
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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36')
html = urllib2.urlopen(req).read()
dict = json.loads(html)
result = dict['data']['result']
return result
最终返回的是一个list数据,我们先把这个数据for出来再看看每一条数据都有些什么东西。
for i in getList():
print i
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,无这样的车次信息的,只不过看起来比较乱,但是他们都有一个特点,每个数据都是由|这个符号分开的,所以我们可以通过用|分割看看能发现什么呢?
for i in getList():
for n in i.split('|'):
print n
break
可以看到所有的值都打印出来了,我们再在前面加上一个序号就能清楚到看到每个序号所对应的值到底是什么了,比如有辆火车硬座还剩3张票,软卧还剩8张票,那我们就查看哪个序号对应的值是3哪个序号对应的值是8就搞清楚了哪个序号是代表什么座次或者其他参数了。
c = 0
for i in getList():
for n in i.split('|'):
print '[%s] %s' %(c,n)
c += 1
c = 0
break
#索引3=车次
#索引8=出发时间
#索引9=到达时间
到了这里不知道同学们有没有发现一个问题,就是我用的这个函数只能够获取到从长沙到成都的数据,而别人不一定是买这个方向的火车,所以我们还得搞清楚请求的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
先找到出发站和到达站的参数分别是:
- leftTicketDTO.from_station=CDW
- leftTicketDTO.to_station=CSQ
然而通过查找和分析我并没有发现这两个参数有规律,那么也就是说这两个值是在之前的请求里面就已经获取到了的,通过检查网页源代码没有找到,那么又只能通过抓包的方式来找。
在抓包过程中找到了一个包的返回值是附带有各城市的代号的,url如下:
https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9018
那么我们把这里面的城市数据复制出来单独新建一个cons.py的文件保存起来。
然后我们通过把参数做成通过输入出发城市和到达城市就可以直接在这个数据里面匹配到相应的城市代号,代码如下:
station = {}
for i in cons.station_names.split('@'):
if i:
tmp = i.split('|')
station[tmp[1]] = tmp[2]
\#print station
train_date = raw_input('请输入出发时间')
from_station = station[raw_input('请输入出发城市')]
to_station = station[raw_input('请输入到达城市')]
到这里就已经能够通过输入“时间,城市”获取相应的车次信息了
那么我们再进行一些简单的判断,就能实现检查相应的时间,地点,车次是否有余票了。同时再结合登录,购票等流程,通过自动判断是否有票,如果无票就继续刷新,直到有票之后自动登录下单后通过短信或者电话等方式全自动联系购票人手机就可以了。
Python实现12306自动查票程序的更多相关文章
- python之12306自动查票
一.导读 本篇文章所采用的技术仅用于学习.研究,任何其他用途请自行承担后果. 12306自动查票使用到的python库主要是splinter,同时也涉及到查票的城市编码,具体的城市编码请在网络上搜 ...
- 利用Python实现12306爬虫--查票
在上一篇文章(http://www.cnblogs.com/fangtaoa/p/8321449.html)中,我们实现了12306爬虫的登录功能,接下来,我们就来实现查票的功能. 其实实现查票的功能 ...
- Python写一个自动点餐程序
Python写一个自动点餐程序 为什么要写这个 公司现在用meican作为点餐渠道,每天规定的时间是早7:00-9:40点餐,有时候我经常容易忘记,或者是在地铁/公交上没办法点餐,所以总是没饭吃,只有 ...
- Python实例--12306的抢票功能
基础知识学习 目标: 通过python程序实现自动登录下单功能 知识点: Selenium + 云打码 + Python 学习链接: 1. Python学习--Selenium模块 2. Python ...
- python+selenium实现自动抢票
使用说明 程序运行开始,需要输入出发地,目的地,出发时间,乘客信息,车次:乘客信息和车次可以输入多个 刚刚开始学习爬虫,selenium仅仅是解放了双手,运行效率不是很高: 程序运行时会打开chrom ...
- python网课自动刷课程序-------selenium+chromedriver
python的强大之处就在于有许多已经写好的功能库提供,这些库强大且易用,对于写一些有特定功能的小程序十分方便. 现在就用pyhton的selenium+谷歌游览器写一个可以自动刷课的程序,以智慧树上 ...
- 基于selenium+java的12306自动抢票
import java.util.concurrent.TimeUnit; import org.openqa.selenium.By;import org.openqa.selenium.Keys; ...
- vue+node+mongoDB火车票H5(七)-- nodejs 爬12306查票接口
菜鸟一枚,业余一直想做个火车票查票的H5,前端页面什么的已经写好了,node+mongoDB 也写了一个车站的接口,但 接下来的爬12306获取车次信息数据一直卡住,网上的爬12306的大部分是pyt ...
- 利用Python攻破12306的最后一道防线
各位同学大家好,我是强子,好久没跟大家带来最新的技术文章了,最近有好几个同学问我12306自动抢票能否实现,我就趁这两天有时间用Python做了个12306自动抢票的项目,在这里我来带着大家一起来看看 ...
随机推荐
- Matlab的BP神经网络工具箱及其在函数逼近中的应用
1.神经网络工具箱概述 Matlab神经网络工具箱几乎包含了现有神经网络的最新成果,神经网络工具箱模型包括感知器.线性网络.BP网络.径向基函数网络.竞争型神经网络.自组织网络和学习向量量化网络.反馈 ...
- Goroutine通信与thread in java间的通信
// This file contains the implementation of Go channels. // Invariants: // At least one of c.sendq ...
- 983. Minimum Cost For Tickets
网址:https://leetcode.com/problems/minimum-cost-for-tickets/ 参考:https://leetcode.com/problems/minimum- ...
- 李航《统计学习方法》CH02
CH02 感知机 前言 章节目录 感知机模型 感知机学习策略 数据集的线性可分性 感知机学习策略 感知机学习算法 感知机学习算法 感知机学习算法的原始形式 算法的收敛性 感知机学习算法的对偶形式 导读 ...
- 2015-11-03 ado.net3
DataReader和DateSet区别: 1. DataReader是一行一行的读,且只能向前读.DateSet是一次性读取出来放到内存中,所以,DataReader读取速度更快,占用内存更低. 2 ...
- 【Python】Part I 设置Python环境
01 设置Python环境 02 破解WingIDE (1)下载专业版wingide http://wingware.com/downloads/wing-pro/6.0.11-1/binaries& ...
- 保存cookie状态封装
from urllib import request, parsefrom urllib.error import HTTPError,URLError#保存cookiefrom http impor ...
- CSS可见区域全局居中
top:$(document).scrollTop() + ($(document).height() - $(document).scrollTop())/2,
- springboot解决文件上传大小限制
(1)在配置文件(application.properties)加入如下代码 springboot2.0以下配置为: spring.http.multipart.maxFileSize = 10Mb ...
- 有关@NgModule装饰器巩固
declarations —— 该应用所拥有的组件. imports —— 导入 BrowserModule 以获取浏览器特有的服务,比如 DOM 渲染.无害化处理和位置(location). pro ...