抢票软件项目开发

news/2024/12/23 0:08:58/

项目需求分析

整个项目应实现:浏览器自动登录12306网站,查询余票,车票预订,到自动提交系统支付的功能。
具体包括:登录界面的cookie处理(保持登录界面)、登录时的验证码处理、余票查询、提交订单等部分。

分析:
借助工具fiddler,作为整个数据传输的记录环节。整个登录环节包括六个部分的验证才能实现。

用到的模块:
urllib.request:获取网页
re:正则
ssl:提供https支持
urllib.parse.urlencode:数据转换
http.cookiejar:cookie处理
datetime:日期函数
time:可作时间延迟

登录模块

cookie处理:

为保持登录界面的,需要提前进行cookie处理。
功能实现:

#建立cookie处理
print('cookie 处理中')
cjar=http.cookiejar.CookieJar()
opener=urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar))  #先声明使用cookiejar对象,再建立opener
urllib.request.install_opener(opener)  #将opener安装为全局

1.验证码处理

关键点:
如何进行验证码的识别?通过fiddler抓包分析可推出:验证码的每张图片都代表着一个"坐标值",并且每个坐标在一定的范围内变动。

验证码网址:
https://kyfw.12306.cn/passport/captcha/captcha-check

此过程进行的是Post请求,下面是需要提交的"报表数据":
answer :123,124
login_site:E
rand:sjrand
功能实现:

#验证码处理并验证
#验证码网址
yzmurl='https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand'
#验证码的处理,避免验证码出错,再次输入
while True:urllib.request.urlretrieve(yzmurl,'D:/爬虫工程师/yzm.png')yzm=input('请输入验证码,输入第几张图片即可')if (yzm!='regain'):break
#输入图片坐标位置格式:'1','2','3','4','5'
#验证码图片处理,图片序号转坐标
pat1='"(.*?)"'  #提取数字
allpic=re.compile(pat1).findall(yzm) #匹配所有图片数字位置
#定义数字转坐标函数
def getxy(pic):if(pic==1):xy=(30,40)      #横纵坐标在一定范围内变动,不是固定不变的if(pic==2):xy=(110,45)if(pic==3):xy=(190,45)if(pic==4):xy=(250,42)if(pic==5):xy=(36,110)if(pic==6):xy=(112,120)if(pic==7):xy=(190,120)if(pic==8):xy=(265,114)return xy  allpicpos=""
for i in allpic:thisxy=getxy(int(i))for j in thisxy:allpicpos=allpicpos+str(j)+","   #把坐标拼接起来,并以逗号作为分割#print(str(j))#print(thisxy)
#print(allpicpos)
#print(type(allpicpos))
allpicpos2=re.compile("(.*?).$").findall(allpicpos)[0]  #从开始一直匹配到最后为止,并且不包含最后一个字符串逗号
print(allpicpos2)
'''验证码的验证'''
yzmposturl='https://kyfw.12306.cn/passport/captcha/captcha-check'
yzmpostdata=urllib.parse.urlencode({'answer':allpicpos2,'login_site':'E','rand':'sjrand',}).encode('utf-8')
req1=urllib.request.Request(yzmposturl,yzmpostdata)
req1.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0')
req1data=urllib.request.urlopen(req1).read().decode('utf-8','ignore') #请求完成

2.账户密码处理

表单提交网址:
https://kyfw.12306.cn/passport/web/login

此过程进行的是post请求,下面为提交的表单数据:
username :xxxxxx@qq.com
password :xxxxxx
appid:otn
功能实现:

'''post账户密码验证'''
loginposturl='https://kyfw.12306.cn/passport/web/login'
loginpostdata=urllib.parse.urlencode({'username':'	xxxxxxxx@qq.com','password':'xxxxxxxxx','appid':'otn',
}).encode('utf-8')
req2=urllib.request.Request(loginposturl,loginpostdata)
req2.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0')
req2dta=urllib.request.urlopen(req2).read().decode('utf-8','ignore')

3.进一步验证:

验证网址:
https://kyfw.12306.cn/otn/login/userLogin
_json_att:" "

功能实现: 

'''第三个验证,get'''
loginposturl2="https://kyfw.12306.cn/otn/login/userLogin"
loginpostdata2 =urllib.parse.urlencode({
"_json_att":"",
}).encode('utf-8')
req2_2 = urllib.request.Request(loginposturl2,loginpostdata2)
req2_2.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0')
req2data_2=urllib.request.urlopen(req2_2).read().decode("utf-8","ignore")

4.接着,第四步验证:

验证网址:
https://kyfw.12306.cn/passport/web/auth/uamtk
appid :otn

网页数据:
{"result_message":"验证通过","result_code":0,"apptk":null,"newapptk":"ABjHqP-aejeNjN6ddNvCrNxNsb2MzejW3-VKQG5Z502ZObX5pl2220"} 
功能实现:

'''第四个验证post'''
loginposturl3="https://kyfw.12306.cn/passport/web/auth/uamtk"
loginpostdata3 =urllib.parse.urlencode({
"appid":"otn",
}).encode('utf-8')
req2_3 = urllib.request.Request(loginposturl3,loginpostdata3)
req2_3.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0')
req2data_3=urllib.request.urlopen(req2_3).read().decode("utf-8","ignore")
pat_req2='"newapptk":"(.*?)"'  #提取下一步验证需要的tk值
tk=re.compile(pat_req2,re.S).findall(req2data_3)[0]

5.第五步验证:

验证网址:
https://kyfw.12306.cn/otn/uamauthclient
tk :ABjHqP-aejeNjN6ddNvCrNxNsb2MzejW3-VKQG5Z502ZObX5pl2220
注意到:tk取值在上一个页面中!

功能实现: 

'''第五个验证'''
loginposturl4="https://kyfw.12306.cn/otn/uamauthclient"
loginpostdata4 =urllib.parse.urlencode({
"tk":tk,   #此处的tk值在上一步连接中
}).encode('utf-8')
req2_4 = urllib.request.Request(loginposturl4,loginpostdata4)
req2_4.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0')

6.最后登录到个人中心:

个人中心所在网址:
https://kyfw.12306.cn/otn/index/initMy12306
所在网页的数据包:

功能实现:

'''爬取个人中心'''
centerurl='https://kyfw.12306.cn/otn/index/initMy12306'
req3=urllib.request.Request(centerurl)
req3.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0')
req3data=urllib.request.urlopen(req3).read().decode("utf-8","ignore")
print('登录完成')

余票查询模块

车票页面网址:
https://kyfw.12306.cn/otn/leftTicket/init

数据隐藏在接口中,通过抓包分析得到对应的网址:
https://kyfw.12306.cn/otn/leftTicket/queryA?leftTicketDTO.train_date=2018-09-11&leftTicketDTO.from_station=NJH&leftTicketDTO.to_station=SHH&purpose_codes=ADULT 
接口页面对应的数据集:

webforms:
purpose_codes:ADULT
leftTicketDTO.train_date:2018-09-11
leftTicketDTO.to_station:SHH
leftTicketDTO.from_station:NJH
功能实现: 

'''查询余票,此步骤可放在第一步,也可放在登录后'''
#抓包分析得到三字码与站点之间的对应
areatocode={"上海":"SHH","北京":"BJP","南京":"NJH","杭州":"HZH"}
start1=input("请输入起始站:")  #:例如:"南京"
start=areatocode[start1]
to1=input("请输入到站:")
to=areatocode[to1]
isstudent=input("是学生吗?是:1,不是:0")  #例如:"0"
date=input("请输入要查询的乘车开始日期的年月,如2017-03-05:") #格式:2018-09-12
if(isstudent=="0"):student="ADULT"
else:student="0X00"
#构造查询页面网址
'''
https://kyfw.12306.cn/otn/leftTicket/queryA?leftTicketDTO.train_date=2018-09-11
&leftTicketDTO.from_station=NJH&leftTicketDTO.to_station=SHH&purpose_codes=ADULT
'''
url="https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date="+date+"&\
leftTicketDTO.from_station="+start+"&leftTicketDTO.to_station="+to+"&purpose_codes="+student
#date格式2018-09-10
context = ssl._create_unverified_context()
data=urllib.request.urlopen(url).read().decode("utf-8","ignore")
patrst01='"result":\[(.*?)\]'  #转义符,使之匹配正常的中括号
rst01=re.compile(patrst01).findall(data)[0]
allcheci=rst01.split(",")  #以逗号分隔,每一个逗号后面都是一个车次信息
checimap_pat='"map":({.*?})' #提取车次信息
checimap=eval(re.compile(checimap_pat).findall(data)[0])  #转为字典
print("车次\t出发站名\t到达站名\t出发时间\t到达时间\t一等座\t二等座\t硬座\t无座")
for i in range(0,len(allcheci)):try:thischeci=allcheci[i].split("|")#[3]---codecode=thischeci[3]#[6]---fromnamefromname=thischeci[6]fromname=checimap[fromname]#[7]---tonametoname=thischeci[7]toname=checimap[toname]#[8]---stimestime=thischeci[8]#[9]---atimeatime=thischeci[9]#[28]---yzyz=thischeci[31]#[29]---wzwz=thischeci[30]#[30]---zeze=thischeci[29]#[31]---zyzy=thischeci[26]print(code+"\t"+fromname+"\t"+toname+"\t"+stime+"\t"+atime+"\t"+str(zy)+"\t"+str(ze)+"\t\"+str(yz)+"\t"+str(wz))except Exception as err:pass
isdo=input("查票完成,请输入1继续…")
#isdo=1
if(isdo==1 or isdo=="1"):pass
else:raise Exception("输入不是1,结束执行")
print("Cookie处理中…")

后续操作陆续更新中:

 


http://www.ppmy.cn/news/918459.html

相关文章

c语言编写一个火车票,C语言-多线程抢火车票软件

//今晚内容:C语言-抢火车票软件 //讲课老师:范志军 QQ:208824435 #include #include HANDLE hMutex;//互斥锁变量 int a50;//设定50张车票 DWORD WINAPI Func(LPVOID lpParamter)//多线程的功能 { while(a>0) { WaitForSingleObject(hM…

【Python抢票神器】火车票枪票软件到底靠谱吗?实测—终极攻略。

导语 每年的节假日一到,大家头疼的总时同一个问题:你买到回家的票了吗? 尤其是大型的节日:”比如国庆、春节......“ 数以亿计的人口迁移,让车票成了一年里最难买到的那张票。 跨站买票、买短途票上车补票、准点捡漏…

火车票自动抢票新功能上线了!堪比抢票神器

端午节假日越来越近了,小编已开始频频收到好友们的助力抢票请求了。 假日出行回家已经迫不及待却抢不到火车票,各种加速软件层出不穷缺又抢不到十分尴尬,甚至还要花费一笔额外的加速费用…… 不过现在不用担心了,近日,…

欢迎随时回家——python制作一个火车票抢票版本(附完整代码,仅供学习参考)

嗨害大家好鸭~我是小熊猫🖤 今天教大家用Python制作一个12306查票程序脚本(仅供学习参考) 有什么python相关报错解答自己不会的、或者源码资料/模块安装/女装大佬精通技巧 都可以来这里:(https://jq.qq.com/?_wv1027…

火车票抢票软件哪个成功率高更靠谱?

火车票抢票软件哪个成功率高更靠谱?小编推荐使用去“哪儿网”;市场上最炫酷最全的“旅游、出行应用”,特价机票、酒店特价房预订;12,000条国内国际航线查询起落状态一览无遗、180天机票价格趋势实时查看;身边地图式酒店…

php写抢票脚本,火车票抢票python代码公开揭秘!

市场上很多火车票抢票软件大家应该非常熟悉,但很少有人研究具体是怎么实现的,所以觉得很神秘,其实很简单。下面使用Python模拟抢票程序,给大家揭秘抢票到底是怎么回事。 该代码仅供参考,主要用于大家沟通交流,禁止用于商业用途。 具体代码如下,可以修改成自己的12306用户…

火车票·自动抢票软件

本文介绍的是用Python语言实现 12306 自动预定列车票,也就是坊间常说的“抢票”,但个人觉得,这不算是“抢”,只不过是一定程度的自动化。 软件作者个人觉得还是很良心的,不喜互喷 火车票抢票软.zip - 蓝奏云文件大小…

如何用Python打造火车票抢票软件?

首先,让我们了解一下12306火车票的基本信息。12306是中国铁路客户服务中心的官方网站,旅客可以在该网站上查询火车票信息和购买火车票。但是由于火车票非常抢手,导致很多人在购票时遇到了困难。因此,我们可以使用Python编写一个自…