近期好多人私信我,能不能需要分享完整代码。为了帮助大家,我以及将代码整理和教学视频我已经上传了CSDN,欢迎私信交流,共同学习共同进步:代码及视频下载地址 求给五星好评,谢谢啦
前面已经介绍了实现登录12306(https://blog.csdn.net/zjt980452483/article/details/81167765),如果想实现免输入验证码的话,可以借助一些打码平台,这个部分大家可以去自行了解。本人已经实现过,准确率还是蛮高的,但是因为需要按次数收费,所以后面废弃了这部分代码。
简单说一下打码的思路:联系打码平台,告诉他们需要验证坐标型验证码。客服就会将相应的API文档发给你,将其中的py文件拷贝至项目路径中,根据文档中提示信息修改内容。然后从12306网站获取登录的验证码,存放在指定路径下,并将该路径和图片文件名写入打码平台提供的py文档中。运行程序后,会自动将图片发回至打码平台。平台会将正确的结果以字符串的形式反馈回来,稍作调整就可以使用了。
余票查询
这一部分,是由 user_input() 函数和 check() 两个函数组成。 user_input() 接收用户输入的信息(出发地、目的地和出发日),将 user_input() 的反馈结果传给check() ,然后打印出查询结果。这不一部分我使用未登录的状态进行查票,模拟浏览器上的操作如下:
这部分代码是在第一节基础上继续完善,补充部分的完整的代码如下:
import time
from station import stationDic,stationList
import redef User_input():print "++++++++++ 输入查询日期:++++++++++ "while True:print "参考样式\"2010-01-01\""train_date = raw_input()# 检查输入时间格式是否正确try:time.strptime(train_date, "%Y-%m-%d")if re.match("^2018-\d\d-\d\d$",train_date):breakelse:print '格式有误,重新输入'except ValueError:print '格式有误,重新输入'print "++++++++++ 输入出发站 ++++++++++"while True:print "参考样式\"北京\" 、\"北京西\""from_station = raw_input()if from_station in stationDic.keys():breakelse:print "未检索到站名,请重新输入"print "++++++++++ 输入到达站 ++++++++++"while True:to_station = raw_input()if to_station in stationDic.keys():breakelse:print "为检索到站名,请重新输入"# 返回车站汉字形式return train_date,from_station,to_stationdef check(data,from_station,to_station):# print data,from_station,to_station# 获取12306车次查询信息req = urllib2.Request('https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT'%(data,from_station,to_station))req.headers = headershtml = opener.open(req).read()result = loads(html)train_count = len(result['data']['result'])now_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))print "查询到的结果有: ",train_countstation = []for i in range(train_count):station.append(result['data']['result'][i])secretStrTmp = []for i in range(train_count):message = result['data']['result'][i]messageList = message.split('|')# 取出每个列表中第一个值,后续下单会用到count = 0secretStrTmp.insert(count,messageList[0])count += 1# 打印每条车次信息的详细情况if messageList[0] != 'null':print u'''车次:\033[41;1m%s\033[0m''' %( messageList[3]),print "出发站:%s 到达站:%s" %(stationList[from_station], stationList[to_station]),print u'''出发时间:%s 到达时间:%s 历时:%s 高级软卧:\033[1;32;1m %-10s \033[0m 软卧:\033[1;32;1m %-10s \033[0m 硬卧:\033[1;32;1m %5s \033[0m 软座:\033[1;32;1m %5s \033[0m 硬座:\033[1;32;1m %5s \033[0m 无座:\033[1;32;1m %5s \033[0m'''\%( messageList[8], messageList[9], messageList[10],messageList[21], messageList[23], messageList[28], messageList[24], messageList[29], messageList[26]),# print " 火车始发站:%s 终点站:%s"%(stationList[messageList[4]], stationList[messageList[5]])# 此处手动在站点字典中添加“九龙”信息print ' 'return stationtrain_date,from_station,to_station = User_input()
station= check(train_date,stationDic[from_station],stationDic[to_station])
其中" from station import stationDic,stationList "所提及的 station,是为我自定义station.py文件,用于存放12306提供全国铁路网所有车站名及车站识别码,因为里面的内容过长,这里只贴出部分内容的截图和获取方法,完整内容既可以从浏览器中下载,也从我提供的源代码中找到
从浏览器中获取station信息的方法如下:
一、输入搜索条件
定义函数 user_input() 接收用户输入的参数,返回对应的字符串用于后续查询条件
1.输入查询日期
print "++++++++++ 输入查询日期:++++++++++ "while True:print "参考样式\"2010-01-01\""train_date = raw_input()# 检查输入时间格式是否正确try:time.strptime(train_date, "%Y-%m-%d")if re.match("^2018-\d\d-\d\d$",train_date):breakelse:print '格式有误,重新输入'except ValueError:print '格式有误,重新输入'
利用 time.strptime() 检验用户输入的时间格式,要求必须是“2018-07-25”;利用while死循环和异常的特点,直到检测到输入正确的结果才跳出循环
2.输入出发站
print "++++++++++ 输入出发站 ++++++++++"while True:print "参考样式\"北京\" 、\"北京西\""from_station = raw_input()if from_station in stationDic.keys():breakelse:print "未检索到站名,请重新输入"print "++++++++++ 输入到达站 ++++++++++"while True:to_station = raw_input()if to_station in stationDic.keys():breakelse:print "为检索到站名,请重新输入"# 返回车站汉字形式return train_date,from_station,to_station
此处需要将用户输入的车站名,输入到station文件中stationDic字典中进行检查,如果存在,则说明输入合格.
注意,此处返回的直接是用户输入的中文字符串。后面有的地方需要将地名转换成响应的识别码如 北京北:bjb;