#写在前面,这个程序我已经弄出来了,但是因为黄牛泛滥以及懒人太多,整个程序的代码就不贴出来了,这里纯粹就是技术交流。
只做技术交流、、、、、
嗯,程序结束后,自己还是得手动付款。
废话不多说,下面就直接开始技术主要部分阐述。
先讲理论部分:首先我们需要代码实现一个浏览器功能,那么模块基本上可以确定urllib.parse、urllib.request,这两个包都是和网址有关的模块,那么咱们去登录一个网址,特别是有验证码这些的网址,我们登录进去是不是就行了?答案是对的,但是我们用代码实现的话,这个网址可能每次都有可能被代码去请求,那么服务器怎么知道我们是一个人,而不是多个浏览器不同的用户呢?
此时cookie就非常重要了,在代码中设置好cookie,那么对方服务器自然就知道我们是一个人,比较服务器都是这么区分的。python3中 cookie这个功能是封装在http.cookiejar这个模块之内。好了,代码如下:
# coding=utf-8 # author: Jason # time:2018/1/16 20:00:00 #version:1.0 import urllib.request as ul import urllib.parse as uz import http.cookiejar as cookielib from json import loads c=cookielib.LWPCookieJar()#先把cookie对象存储为cookiejar的对象 cookie = ul.HTTPCookieProcessor(c)#把cookiejar对象转换为一个handle opener = ul.build_opener(cookie)#建立一个模拟浏览器,需要handle作为参数 ul.install_opener(opener)#安装一个全局模拟浏览器,代表无论怎么访问都是一个浏览器操作而不是分开获取验证码等msg
好了,如此一来,我们代码的初步实现已经完成,接下来就是进入网络分析部分
首先可以使用google浏览器或者搜狗浏览器(本人用的搜狗),打开F12,也就是开发者模式,登录12306的登录地址 https://kyfw.12306.cn/otn/login/init
两个红圈中第二个是验证码来源,此时我们只需要记录这个网页(点进去)的详细情况,写入代码当中,python3中urllib.request这个模块打开既可
如此便是验证码来源,那么如何用代码捕捉呢?首先我们可以先乱输入密码,乱点验证码,然后我们直接点击登录
多了一个很奇妙的东西,此时,这里就是验证码验证的网址,那么我们是不是应该记录下来呢?很简单,到Headers里面就全都看得到了
上面那个是服务器验证网址,下面就是我们回复给他的东西,那么那个163,121其实就是我乱点的验证码坐标了。至于为啥是坐标,因为它是用鼠标去点图片,那么他只可能是记录坐标,除非他自己搞了一套人工智能验证图片,但基于他几年前就这么玩了,人工智能根本没有怎么开始,他自然只能是最原始的技术而已。
那么这代表了他是先验证验证码,那么验证密码的在哪?自然是需要验证码这关能过,那我们输一个正确的验证码,再写个错密码,登录
此时可以看到,和验证码一样的方法,我们的回复与验证都在这几个圈了,还记得上面验证码失败的时候回复给我们的code是不是有个数字?这个也很重要,那么可以看看我们的验证成功的验证码返回给我们的是什么东西
这次我们看到了,验证码成功,显示是4,好,那我们不就可以进行条件判断了么?
那么如何打开一个网址然后把我们点的东西一起发过去呢?上代码
headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'}#先写个头,表示我这是浏览器用户登录而不是代码登录,如果不写,代码默认用的签名之类的是编程语言的标识,这样对方服务器很容易就发现你是个脚本了
def get_code():#获取验证码的步骤 req = ul.Request('https://kyfw.12306.cn/passport/captcha/captcha-image"htmlcode">def main_(): get_code() code = input('输入验证码:') req = ul.Request('https://kyfw.12306.cn/passport/captcha/captcha-check') req.headers = headers data = { 'answer':code, 'login_site':'E', 'rand':'sjrand' } data = uz.urlencode(data).encode()#把字典转换为URL query string,此时是str,要把它变为byts。 html = opener.open(req,data= data).read().decode()#读取出来是byts格式,转换为‘utf-8(默认) print(html) result = loads(html) if result['result_code']=='4': print('验证码通过') rep = ul.Request('https://kyfw.12306.cn/passport/web/login') rep.headers = headers data = {'username':'这里就是你用户名', 'password':'这里就是你的密码', 'appid':'otn' } data = uz.urlencode(data).encode() #看到了吗,这就是你给服务器回复的东西 html1 = opener.open(rep,data = data ).read().decode() result1 = loads(html1) if result1['result_code'] == 0: print('账户密码验证通过') else: print(result1['result_message']) else: print('验证码校验失败,重来') if __name__ == '__main__': main_()此时,咱们就过了验证码密码这一关,后面是不是又要查票?那么同样的方法,我们就可以以此类推到最后一步,这里就不一一贴代码了
ps:查代码这几步的信息可是很重要喔,我们要把它记录好,并且这里面的信息包含了各种作为信息以及他们的顺序,多测试几次基本都能搞出来,这里就是提醒一点
找找规律,然后用split的方法完全就可以切割出来,然后一个循环,就可以得到第几个元素是我们要的,那么后面就可以标志判断返回值如果是无,就没票可以继续查询,直到有票就可以下一步;
那么有票的话,后面一样也是以此类推的方式,代码我就不重现了,很简单,我就把后面出现需要请求的网址都发出来供大家观摩
查询车票信息
url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ"htmlcode">req = ul.Request('https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest')#确定订单信息 req = ul.Request("https://kyfw.12306.cn/otn/confirmPassenger/initDc")#验证订单 req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs')#准备跨到下单中的过度 req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo')#检查订单信息 req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount')#信息提交给服务器,准备进入下单步骤 req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue')#正式进入下单步骤 req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime"https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue")#最后的结果回执,如果一切都顺利,那么票就已经订了。我一般是打印他返回的内容 ''' zreq = ul.Request("https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue") zreq.headers = headers data ={"REPEAT_SUBMIT_TOKEN":"%s"%numb, "_json_att": "", "orderSequence_no":orderId } data = uz.urlencode(data).encode() html = opener.open(zreq,data=data).read().decode() result = loads(html) print('代码全部过完,回去登录下是否搞定') print(result) print(result['data']['submitStatus']) if result['data']['submitStatus'] == True: print('购票成功') return True else: print('购票失败,重试其他列车') continue ''' 最终的回执代码详细 信息,读者可以自己尝试多次,得到自己的回复代码确认是否购票成功,因为result['data']['submitStatus']==True只不过是确认订单状态而已,这个被我改动过,你可以多次尝试最后的最后,火车票预订成功只有30分钟支付时间,所以我为了防止订好票但是我人不在,特意写了qq邮件通知
qq邮件通知:
def email():#这是我订票后给自己发邮件的函数 import smtplib from email.mime.text import MIMEText import time text = '已经为%s抢到票,速度登录12306付款,用户名:%s,密码:%s'%(NAME,username,password) msg = MIMEText(text, 'plain', 'utf-8') msg_From = '2059****16@qq.com' msg_To = '5043****75@qq.com'#是的,我有两个qq,一个发一个收 smtpSever = 'smtp.qq.com' # qq邮箱的smtp Sever地址 smtpPort = '465' # 开放的端口 sqm = 'q********eghe' # 在登录smtp时需要login中的密码应当使用授权码而非账户密码 msg['from'] = msg_From msg['to'] = msg_To msg['subject'] = 'Python自动邮件-%s' % time.ctime() smtp = smtplib smtp = smtplib.SMTP_SSL() ''' smtplib的connect(连接到邮件服务器)、login(登陆验证)、sendmail(发送邮件) ''' smtp.connect(smtpSever, smtpPort) smtp.login(msg_From, sqm) smtp.sendmail(msg_From, msg_To, str(msg)) # s = smtplib.SMTP("localhost") # s.send_message(msg) smtp.quit() print('邮件已发送~你可以安心去玩了') def emailforcode():#此函数是防止查询有票但12306账号掉线人不在无法订票的提醒 import smtplib from email.mime.text import MIMEText import time text = '%s账号下线,速度登录验证12306' % NAME msg = MIMEText(text, 'plain', 'utf-8') msg_From = '205****516@qq.com' msg_To = '50****75@qq.com' smtpSever = 'smtp.qq.com' # qq邮箱的smtp Sever地址 smtpPort = '465' # 开放的端口 sqm = 'qowa*******ghe' # 在登录smtp时需要login中的密码应当使用授权码而非账户密码 msg['from'] = msg_From msg['to'] = msg_To msg['subject'] = 'Python自动邮件-%s' % time.ctime() smtp = smtplib smtp = smtplib.SMTP_SSL() ''' smtplib的connect(连接到邮件服务器)、login(登陆验证)、sendmail(发送邮件) ''' smtp.connect(smtpSever, smtpPort) smtp.login(msg_From, sqm) smtp.sendmail(msg_From, msg_To, str(msg)) # s = smtplib.SMTP("localhost") # s.send_message(msg) smtp.quit() print('邮件已发送~')如此就大功告成了。
不能发完整的代码(本身目的就是为了技术交流而已,防止懒人盗码乱搞),但是我相信各位开发中的朋友们只要有逻辑,有开头,只要自己肯动手,都可以自己钻研出来,举一反三。毕竟我就是这样搞出来的,我从来都相信,只要肯学,都会学会,只要肯做,都可以做成。
总结
以上所述是小编给大家介绍的python实现12306抢票及自动邮件发送提醒付款功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】