Python 获取车票信息
提示:该代码仅供学习使用,切勿滥用!!!
先来一个git地址:https://gitee.com/wang_li/li_wang
效果图:
逻辑:
1.获取Json文件的内容 2.根据信息生成URL 3.获取URL的内容,根据时间进行分析,如果有票则发送邮件,如果没有,则继续监听
1.定义Json文件
内容如下:
{ "_Nodes" : "定义起始站", "from_address" : "成都东", "_Nodes" : "定义终点站", "to_address" : "遂宁", "_Nodes" : "定义车次", "departure_date" : "2018-12-30", "_Nodes" : "定义时间检查区间", "start_time" : "09:00", "_Nodes" : "定义时间结束区间", "stop_time" : "12:00", "_Nodes" : "定义列车类型 [ D:动车 Z:直达 T:特快 K:快速 A:全部 ]", "type" : "A", "_Nodes" : "定义是否发送邮件 true为发送 false为不发送", "send_mail" : "false", "_Nodes" : "如果上述定义为true,则下面则定义邮箱的信息包括,SMTP 和 认证信息", "mail_smtp" : "smtp.qq.com", "user_name" : "to_user@qq.com", "user_password" : "password", "mail_subject" : "仅仅是为了好玩", "_Nodes" : "将信息发送给谁", "mail_to_address" : "user1@qq.com;user2@163.com", "_Nodes" : "有票时,提示的最大次数,当有间隔时,则重新计数 , 这里最大值为100", "send_mail_max" : 3, "_Nodes" : "刷新间隔时间,单位:秒", "interval_time" : 30 }
2.Python代码处理Json文件并且返回结果
代码如下:
#!/usr/bin/env python3 import requests import json import time import sys import email.mime.text import smtplib #解析json文件 def Dealwith_jsonfile(jsonfile) : return_dirct = {} #定义json标题 json_title = ['from_address' , 'to_address' , 'departure_date' , 'start_time' , 'stop_time' , 'type' , 'send_mail' , 'mail_smtp' , 'user_name' , 'user_password' , 'mail_subject', 'mail_to_address' , 'send_mail_max','interval_time'] #读取文件 open_json_file = open(jsonfile , 'rb') #初始化send_mail参数 send_mail_on = 0 #开启try except 捕获json错误的信息 try: dict_json_file = json.load(open_json_file) #查询是否开启发送邮件 if 'true' == dict_json_file['send_mail'] : send_mail_on = 1 # 0 为不开启,则不需要记录smtp/username/password/send_mail的信息 if 0 == send_mail_on : for title_configure in json_title : if 'mail_smtp' == title_configure or 'user_name' == title_configure or 'user_password' == title_configure or 'send_mail_max' == title_configure or 'mail_subject' == title_configure or 'mail_to_address' == title_configure: continue else : return_dirct[title_configure] = dict_json_file[title_configure] else : for title_configure in json_title : return_dirct[title_configure] = dict_json_file[title_configure] #关闭文件 open_json_file.close() print(return_dirct) return return_dirct except Exception as e: print("处理Json文件失败,详情如下:") print(e) if __name__ == "__main__" : Dealwith_jsonfile("go_gome.json")
执行的结果如下:
{'from_address': '成都东', 'to_address': '遂宁', 'departure_date': '2019-01-04', 'start_time': '09:30', 'stop_time': '12:00', 'type': 'D', 'send_mail': 'true', 'mail_smtp': 'smtp.qq.com', 'user_name': '2081795560@QQ.COM', 'user_password': 'idfqdnnrfjttbjbe', 'mail_subject': '仅仅是为了好玩', 'mail_to_address': '2859413527@QQ.COM', 'send_mail_max': 2, 'interval_time': 10}
3.获取站别ID
网址:https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9085
具体内容如下:
通过分析得到,名词的后一位就是站别ID
Python获取站别ID如下:
#!/usr/bin/env python3 import requests def Get_Address_resolution(from_address,to_address , Address_type) : return_station_name = [] # 站点信息可以在12306网站上找到 station_name_url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9085' #获取网页信息 station_information = requests.get(station_name_url).text #以 | 分割 list_station_information = station_information.split("|") # 获取from_address 和 to_address 地址的ID if 1 == Address_type : address_com = 1 elif 2 == Address_type : address_com = -1 else : return return_station_name for address in from_address , to_address : try: if list_station_information.index(address): return_station_name.append( list_station_information[list_station_information.index(address) + address_com]) except Exception as e: print(e) return return_station_name if __name__ == "__main__" : print(Get_Address_resolution('成都东','遂宁',1)) print(Get_Address_resolution('ICW', 'NIW', 2))
执行结果如下:
['ICW', 'NIW'] ['成都东', '遂宁']
3.获取实际URL
通过分析,我们可以得知,每次请求网页,实际上实在请求一个数据包,例如:
我们只需要将数据拼接上就可以了
代码如下:
#!/usr/bin/env python3 def Generate_Url () : try: station_code = ['ICW', 'NIW'] #获取最新的地址解析时间(此信息也是固定的) return_url = "https://kyfw.12306.cn/otn/leftTicket/queryA?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT" \ %('2019-01-03' ,station_code[0] , station_code[1] ) return return_url except Exception as e: print("生成URL失败") print(e) if __name__ == "__main__" : print(Generate_Url())
https://kyfw.12306.cn/otn/leftTicket/queryA?leftTicketDTO.train_date=2019-01-03&leftTicketDTO.from_station=ICW&leftTicketDTO.to_station=NIW&purpose_codes=ADULT
综合代码
#!/usr/bin/env python3 import requests import json import time import sys import email.mime.text import smtplib #解析json文件 def Dealwith_jsonfile(jsonfile) : return_dirct = {} #定义json标题 json_title = ['from_address' , 'to_address' , 'departure_date' , 'start_time' , 'stop_time' , 'type' , 'send_mail' , 'mail_smtp' , 'user_name' , 'user_password' , 'mail_subject', 'mail_to_address' , 'send_mail_max','interval_time'] #读取文件 open_json_file = open(jsonfile , 'rb') #初始化send_mail参数 send_mail_on = 0 #开启try except 捕获json错误的信息 try: dict_json_file = json.load(open_json_file) #查询是否开启发送邮件 if 'true' == dict_json_file['send_mail'] : send_mail_on = 1 # 0 为不开启,则不需要记录smtp/username/password/send_mail的信息 if 0 == send_mail_on : for title_configure in json_title : if 'mail_smtp' == title_configure or 'user_name' == title_configure or 'user_password' == title_configure or 'send_mail_max' == title_configure or 'mail_subject' == title_configure or 'mail_to_address' == title_configure: continue else : return_dirct[title_configure] = dict_json_file[title_configure] else : for title_configure in json_title : return_dirct[title_configure] = dict_json_file[title_configure] #关闭文件 open_json_file.close() return return_dirct except Exception as e: print("处理Json文件失败,详情如下:") print(e) #抓取城市名称对应的ID def Get_Address_resolution(from_address,to_address , Address_type) : #定义返回列表 return_station_name = [] # 站点信息可以在12306网站上找到 station_name_url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9085' #获取网页信息 station_information = requests.get(station_name_url).text #以 | 分割 list_station_information = station_information.split("|") # 获取from_address 和 to_address 地址的ID if 1 == Address_type : address_com = 1 elif 2 == Address_type : address_com = -1 else : return return_station_name for address in from_address , to_address : try: if list_station_information.index(address): return_station_name.append( list_station_information[list_station_information.index(address) + address_com]) except Exception as e: print(e) return return_station_name # try: # if list_station_information.index(from_address) : # return_station_name.append(list_station_information[list_station_information.index(from_address) + 1]) # except Exception as e: # print(e) # # try: # if list_station_information.index(to_address): # return_station_name.append(list_station_information[list_station_information.index(to_address) + 1]) # except Exception as e: # print(e) # # #将ID返回回去 # return return_station_name # # #代码和上述一致,可以合并为到一块 # elif 2 == Address_type : # try: # if list_station_information.index(from_address) : # return_station_name.append(list_station_information[list_station_information.index(from_address) - 1]) # except Exception as e: # print(e) # # try: # if list_station_information.index(to_address): # return_station_name.append(list_station_information[list_station_information.index(to_address) - 1]) # except Exception as e: # print(e) # # #将ID返回回去 # return return_station_name #生成URL连接 def Generate_Url (operation_parameters) : try: station_code = Get_Address_resolution(operation_parameters['from_address'],operation_parameters['to_address'],1) #获取最新的地址解析时间(此信息也是固定的) return_url = "https://kyfw.12306.cn/otn/leftTicket/queryA?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT" \ %(operation_parameters['departure_date'] ,station_code[0] , station_code[1] ) return return_url except Exception as e: print("生成URL失败") print(e) #爬取是否有票 def Crawling_Informations (url , operation_parameters) : #初始化检查失败参数 check_failed = 0 #初始化票send-mail次数 send_mail_number = {} #定义无限循环 while True: if check_failed > 10 : print("连续10次抓取失败,程序退出") break try: #获取内容并且转换为json crawling_text = requests.get(url).text crawling_json = json.loads(crawling_text) #定义空的列表用于存放票务信息 checkmessageall = [] #便利json文件的['data']['result']信息 for crawling_list in crawling_json['data']['result'] : checkmessage = [] #将票务信息按 | 分割 for split_list_json in crawling_list.split('|'): #排除长度问20字符的行 if len(split_list_json) > 20: pass else: #将其他值压进checkmessage checkmessage.append(split_list_json) #将整个checkmessage 押进checkmessageall checkmessageall.append(checkmessage) #开始处理我们爬过来的票务信息 for dealwithforlist in checkmessageall: # 计算列车类型 train_type = operation_parameters['type'] # 判断 [ D:动车 Z:直达 T:特快 K:快速 A:全部 ] 如果都不是的话,默认设置为A 全部 if train_type != 'D' and train_type != 'Z' and train_type != 'T' and train_type != 'K' and train_type != 'A' : train_type = 'A' # 开始匹配列车类型 if train_type in dealwithforlist[dealwithforlist.index('预订') + 2] or train_type == 'A' : #获取设置的开始时间和结束时间 start_time = operation_parameters['start_time'] stop_time = operation_parameters['stop_time'] # 判断开始时间是否大于结束时间 if stop_time <= start_time : print("开始时间不能超过结束时间") sys.exit(-1) # 开始匹配我们的 开始时间 和 结束时间 if (start_time <= dealwithforlist[dealwithforlist.index('预订') + 7] ) and (stop_time >= dealwithforlist[dealwithforlist.index('预订') + 7] ) : # 判断是否有票 if 'Y' == (dealwithforlist[dealwithforlist.index('预订') + 10]): print("有票") print(dealwithforlist) # 判断是否发送邮件 if 'true' == operation_parameters['send_mail']: #获取邮件发送最大次数 send_mail_max = operation_parameters['send_mail_max'] # 如果没有邮件发送计数,则重新生成 if (dealwithforlist[dealwithforlist.index('预订') + 2]) not in send_mail_number: send_mail_number[dealwithforlist[dealwithforlist.index('预订') + 2]] = 0 # 判断发送邮件 if (send_mail_number[dealwithforlist[dealwithforlist.index('预订') + 2]]) <= send_mail_max : Send_Mail_Only_You_Yan(dealwithforlist , operation_parameters) pass if send_mail_number[dealwithforlist[dealwithforlist.index('预订') + 2]] <= 1200 : send_mail_number[dealwithforlist[dealwithforlist.index('预订') + 2]] = send_mail_number[dealwithforlist[dealwithforlist.index('预订') + 2]] + 1 else: print("没有票") print(dealwithforlist) #将sned_mail_number至0 send_mail_number[dealwithforlist[dealwithforlist.index('预订') + 2]] = 0 # 获取间隔时间 interval_time = operation_parameters['interval_time'] #定义睡眠时间 time.sleep(interval_time) check_failed = 0 except Exception as e: print(e) check_failed = check_failed + 1 def Send_Mail_Only_You_Yan (dealwithforlist , operation_parameters): #获取票的信息 network_list_info_station_address = Get_Address_resolution(dealwithforlist[dealwithforlist.index('预订') + 3],dealwithforlist[dealwithforlist.index('预订') + 4],2) network_list_info_train_number = dealwithforlist[dealwithforlist.index('预订') + 2] network_list_info_start_time = dealwithforlist[dealwithforlist.index('预订') + 7] network_list_info_stop_time = dealwithforlist[dealwithforlist.index('预订') + 8] network_list_info_run_time = dealwithforlist[dealwithforlist.index('预订') + 9] network_list_info_date = dealwithforlist[dealwithforlist.index('预订') + 11] local_list_info_start_address = operation_parameters['from_address'] local_list_info_to_address = operation_parameters['to_address'] #获取邮件信息 local_list_info_mail_smtp = operation_parameters['mail_smtp'] local_list_info_mail_user = operation_parameters['user_name'] local_list_info_mail_password = operation_parameters['user_password'] local_list_info_mail_subject = operation_parameters['mail_subject'] local_list_info_mail_to_address = operation_parameters['mail_to_address'] HOST = local_list_info_mail_smtp SUBJECT = local_list_info_mail_subject TO = local_list_info_mail_to_address FROM = local_list_info_mail_user msg = email.mime.text.MIMEText( """ <html> <head> <title>仅仅是为了好玩</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <table style="padding: 1px;background-color: #2300f9;"> <tr> <th style="background-color: white">车次</th> <th style="background-color: white">需求出发站</th> <th style="background-color: white">需求到达站</th> <th style="background-color: white">车票出发站</th> <th style="background-color: white">车票到达站</th> <th style="background-color: white">时间</th> <th style="background-color: white">发车时间</th> <th style="background-color: white">到达时间</th> <th style="background-color: white">历时</th> </tr> <tr> <td style="background-color: white">%s</td> <td style="background-color: white">%s</td> <td style="background-color: white">%s</td> <td style="background-color: white">%s</td> <td style="background-color: white">%s</td> <td style="background-color: white">%s</td> <td style="background-color: white">%s</td> <td style="background-color: white">%s</td> <td style="background-color: white">%s</td> </tr> </table> </body> </html> """ %(network_list_info_train_number ,local_list_info_start_address ,local_list_info_to_address , network_list_info_station_address[0] , network_list_info_station_address[1] ,network_list_info_date , network_list_info_start_time , network_list_info_stop_time , network_list_info_run_time ), "html","utf-8") msg['Subject'] = SUBJECT msg['From'] = FROM msg['TO'] = TO server = smtplib.SMTP_SSL(HOST,') server.login(local_list_info_mail_user,local_list_info_mail_password) server.sendmail(FROM,TO.split(';'),msg.as_string()) server.quit if __name__ == "__main__" : # #解析json文件 # operation_parameters = Dealwith_jsonfile("go_gome.json") # # #生成URL连接 # url = Generate_Url(operation_parameters) # # #开始查询票票 # Crawling_Informations(url , operation_parameters) Crawling_Informations(Generate_Url(Dealwith_jsonfile("go_gome.json")) , Dealwith_jsonfile("go_gome.json"))
Python 获取车票信息的更多相关文章
- python 获取对象信息
当我们拿到一个对象的引用时,如何知道这个对象是什么类型.有哪些方法呢? 使用type() 首先,我们来判断对象类型,使用type()函数: 基本类型都可以用type()判断: >>> ...
- 用python获取服务器硬件信息[转]
#!/usr/bin/env python # -*- coding: utf-8 -*- import rlcompleter, readline readline.parse_and_bind(' ...
- 用python获取ip信息
1.138网站 http://user.ip138.com/ip/首次注册后赠送1000次请求,API接口请求格式如下,必须要有token值 import httplib2 from urllib.p ...
- python获取对象信息
获取对象信息 拿到一个变量,除了用 isinstance() 判断它是否是某种类型的实例外,还有没有别的方法获取到更多的信息呢? 例如,已有定义: class Person(object): def ...
- python获取机器信息脚本(网上寻找的)
获取机器信息(待测试) # -*- coding: UTF-8 -*- import psutil import json import os import socket import struct ...
- python获取的信息列表微信公共平台和用户头像
转载注明原文地址:http://blog.csdn.net/btyh17mxy/article/details/25207889 只写模拟登陆的方式获取微信从信息和头像库列表公共平台, - 相关后,功 ...
- 关于Python 获取windows信息收集
收集一些Python操作windows的代码 (不管是自带的or第三方库)均来自网上 1.shutdown 操作 定时关机.重启.注销 #!/usr/bin/python #-*-coding:utf ...
- Python - 获取帮助信息
1- Python Manuals 自带CHM格式的Python Manuals存放在\Python<x.x>\Doc\目录下.可以在IDLE界面下按F1键或点击help选项下Python ...
- python 获取SLB信息 更换证书
首先安装阿里云SDK pip install aliyun-python-sdk-core pip install aliyun-python-sdk-slb 可以配合jenkins传递参数 #获取s ...
随机推荐
- C++/CLI
[C++/CLI] A C++/CLI application or component uses extensions to C++ syntax (as allowed by the C++ Sp ...
- 9. maps
C++有vertor,java有HashMap,C语言想使用则需要自行封装,不同的类型还需要再封装,特别麻烦. 看看Go语言的map的使用方法:var member map[string]int,创建 ...
- Eclipse安装TestNG插件
TestNG按照其文档的定义是: TestNG是一个测试框架,其灵感来自JUnit和NUnit的,但引入了一些新的功能,使其功能更强大,使用更方便. TestNG是一个开源自动化测试框架;TestNG ...
- 什么是HTML?
html是很多人编程的入门领域.作为初学者,不管你是在哪里学的,学校,视频教程,网络教程等等……它们都会告诉你HTML即:超文本标记语言(Hyper Text Markup Language).但第一 ...
- UDP广播 MAC地址
enduser_setup.start() ListenPort = wifi.setmode(wifi.STATIONAP) wifi.sta.autoconnect() clientid = wi ...
- JS——按钮点击事件累加注册问题
最近在工作上遇到一个点击事件累加的问题,为元素添加点击事件效果,但是总是效果失败,最后发现点击事件被执行了多次,上网查了一下,下边就是解决这个问题的几种思路 案列引自 踮起脚尖眺望6 $(" ...
- Python播放、关闭音乐代码
1.安装pygame:win + r :打开控制台输入:pip install pygame 2.#导入 import time import pygame 3.设置音乐绝对路径 #音乐路径 file ...
- 使用SQL语句查询表及表字段类型说明
今天突然遇到有人要数据库表及表字段说明,数据库表太多又不能一个个表去找,就想想SQL是否能直接查询出来. 经过查询资料,加上一些自己的一些调整写了一个sql语句,在此记录一下,以方便日后查找使用. S ...
- 获得32位UUID字符串和指定数目的UUID
在common包中创建类文件UUIDUtils.java package sinosoft.bjredcross.common; import java.util.UUID; public class ...
- mysql 索引及索引创建原则
是什么 索引用于快速的查询某些特殊列的某些行.如果没有索引, MySQL 必须从第一行开始,然后通过搜索整个表来查询有关的行.表越大,查询的成本越大.如果表有了索引的话,那么 MySQL 可以很快的确 ...