登录  | 加入社区

黑狼游客您好!登录后享受更多精彩

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

查看: 414|回复: 0

使用Python攻破12306的末了一道防线,包罗全套视频教程! ...

[复制链接]

384

主题

4

帖子

0

现金

黑狼菜鸟

Rank: 1

积分
0
发表于 2018-10-26 11:37:55 | 显示全部楼层 |阅读模式 来自 北京
wmtyO13FHy8GO73k.jpg Python 的概念

私信小编007即可获取Python视频教程获取方式以及各类PDF!
很久没跟各人带来最新的技能文章了,近来有好几个同砚问我12306主动抢票可否实现,我就趁这两天偶然间用Python做了个12306主动抢票的项目,在这里我来带着各人一起来看看到底怎样一步一步攻克万恶的12306。
我们要做12306抢票而官方又没有提供相应的接口(也不大概提供),那么我们就只能通过本身探求12306的数据包和买票流程来模仿欣赏器举动实现主动化操纵了,说直白一点就是爬虫,接下来进入正题,火线高能,请系好安全带~~
CPYXGUyoqYFZDQ4y.jpg

起首在买票前我们必要先确认是否有票,那么举行正常的查票,打开12306查票网站http://kyfw.12306.cn/otn/leftTicket/init 输入出发地和目标地举行搜刮。
l35WSQPNOwTP2QkS.jpg

那么一样平常在看到这个页面的时间我们能想到的获取车次及相干信息的方式是什么呢?对于零底子的同砚而言第一时间就会想到在源代码内里找,但这里究竟上源代码内里根本没有相干内容,由于该哀求是接纳的js中ajax异步哀求的方式动态加载的,并不包罗在源代码内里,以是我们只可以或许通过抓包的方式来检察欣赏器与服务器的数据交互环境,我用的是谷歌欣赏器以是打开开辟者工具的快捷键是F12。
cI27AEmzssoArW8g.jpg

留意选中红线框出来的那一个选项,此时只要是欣赏器和服务器发生数据交互都会在下面列表框表现出来,我们再次点击查询 按钮。
viwAAXI0G3roZ3dB.jpg

效果发现列表当中有了两个哀求,也就是说我们点击查询按钮以后欣赏器向服务器发起了两次哀求,那么我们来通过返回值分析下谁人哀求才是真正获取到车次相干数据的哀求,以便我们用Python来模仿欣赏器操纵。
第一次哀求:
XP806R38UWhp0WhI.jpg

很显着第一次哀求返回的值没有我们必要的车次信息。
第二次哀求:
mccz1cx0Hc5k4xA8.jpg

第二次哀求内里看到了许多数据,固然我们临时还没看到车次信息,但是我们发现它有个特性,就是有个列表的值内里有6个元素,而刚好我们搜刮出来的从长沙到成都的车辆也是6条数据,以是这两者肯定有肯定关系,那么我们先用Python来获取到这些数据再举行下一步分析:
# -*- coding: utf-8 -*-import urllib2import sslssl._create_default_https_context = ssl._create_unverified_contextdef getList(): req = urllib2.Request('http://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 htmlprint getList()起首界说一个函数来获取车次列表信息:
从抓包数据中获取到该哀求的url:http://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默认是不会哀求不受信托的证书的网站的,我们可以通过这行代码来关闭掉证书的验证
那么我们先来看看能不能正常获取到我们想要的信息 :
WPm5kS3sU4Bm5kPb.jpg

究竟证实我们的操纵没有题目,接下来先拿到包罗有6条数据的这个列表再说。
返回的数据是json格式,但是Python尺度数据范例中没有json这个范例,以是对于Python而言它就是个字符串,假如要非常方便的操纵这个json我们就可以借助Python中的json这个包来把json这个字符串酿成dict范例,然后通过dict的键值对操纵方法把列表取出来并举行返回。
# -*- coding: utf-8 -*-import urllib2import sslimport jsonssl._create_default_https_context = ssl._create_unverified_contextdef getList(): req = urllib2.Request('http://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 ifor出来之后我们先来看看第一条数据是什么样的:
|预订|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

vFvb3V3aVH3Q4VdA.jpg

可以看到全部的值都打印出来了,我们再在前面加上一个序号就能清晰到看到每个序号所对应的值到底是什么了,好比有辆火车硬座还剩3张票,软卧还剩8张票,那我们就检察哪个序号对应的值是3哪个序号对应的值是8就搞清晰了哪个序号是代表什么座次大概其他参数了。
c = 0for i in getList(): for n in i.split('|'): print '[%s] %s' %(c,n) c += 1 c = 0 break#索引3=车次#索引8=出发时间#索引9=到达时间

k3nn17b3n3Nmnnpb.jpg



到了这里不知道同砚们有没有发现一个题目,就是我用的这个函数只可以或许获取到从长沙到成都的数据,而别人不肯定是买这个方向的火车,以是我们还得搞清晰哀求的url当中的出发站和到达站的值是怎么来的。
http://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=CDWleftTicketDTO.to_station=CSQ然而通过查找和分析我并没有发现这两个参数有规律,那么也就是说这两个值是在之前的哀求内里就已经获取到了的,通过查抄网页源代码没有找到,那么又只能通过抓包的方式来找。
在抓包过程中找到了一个包的返回值是附带有各都会的代号的,url如下:
http://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9018

j1W8qjjmeMLQJiWf.jpg



那么我们把这内里的都会数据复制出来单独新建一个cons.py的文件生存起来
AFr9eCezqKrwrQfA.jpg



然后我们通过把参数做成通过输入出发都会和到达都会就可以直接在这个数据内里匹配到相应的都会代号,代码如下:
station = {}for i in cons.station_names.split('@'): if i: tmp = i.split('|') station[tmp[1]] = tmp[2]#print stationtrain_date = raw_input('请输入出发时间')from_station = station[raw_input('请输入出发都会')]to_station = station[raw_input('请输入到达都会')]到这里就已经可以或许通过输入时间,都会获取相应的车次信息了 。
S5KXJBCiCGZ4dkJV.jpg



那么我们再举行一些简朴的判定,就能实现查抄相应的时间,所在,车次是否有余票了。
同时再联合登录,购票等流程,通过主动判定是否有票,假如无票就继承革新,直到有票之后主动登录下单后通过短信大概电话等方式全主动接洽购票人手机就可以了,如下图:
IojeOR5ozcOccJad.jpg



由于涉及到的知识点太多,仅仅用笔墨的方式很难体现的八面见光,以是偶然间的同砚可以到我的讲堂做客,现场直播解说更加的生动易懂!




上一篇:Python快速天生词云图,这是最具体的教程,没有之一! ...
下一篇:步伐员之间的藐视链?我公布:​PHP​是天下上最好的语言 ...
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

 

QQ|申请友链|小黑屋|手机版|Hlshell Inc. ( 豫ICP备16002110号-5 )

GMT+8, 2024-5-20 15:53 , Processed in 0.054475 second(s), 47 queries .

HLShell有权修改版权声明内容,如有任何爭議,HLShell將保留最終決定權!

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表