python自动查询12306余票并发送邮箱提醒脚本


Posted in Python onMay 21, 2018

由于车票难抢,有时需要的车票已经售空,而我们需要捡漏,便可使用这个脚本。

具体实现了,自动查询某一车票的余票数量,当数量产生变化时,将自动发送QQ邮件到对于的邮箱进行提醒。

其中,发送邮箱的部分详情可参考我上一篇博文:Python 发送邮件 (smtp) QQ邮箱

脚本使用了python + selenium + chrome webdriver,需要先配置好三者的环境

具体使用时候,需自行改变代码中的

邮箱信息、出发站、到达站、车次、日期、以及到相应查询页面中找到对应车票的html id:

在相应查询页面中按F12,弹出开发者模式,点击python自动查询12306余票并发送邮箱提醒脚本按钮,再点击对应车票的框,python自动查询12306余票并发送邮箱提醒脚本python自动查询12306余票并发送邮箱提醒脚本,复制相应的id号到代码中对应处。

代码如下:

#coding:utf8 
from selenium import webdriver 
from selenium.webdriver.common.keys import Keys 
 
import time 
from smtplib import SMTP_SSL 
from email.header import Header 
from email.mime.text import MIMEText 
 
from_station = 'SH' 
to_station = 'NJ' 
train_num = 'G14' 
train_date = '2018-02-14' 
 
ZYid = 'ZY_5l00000G1441' #通过浏览器找到要查询车票的三个id 
ZEid = 'ZE_5l00000G1441' 
WZid = 'WZ_5l00000G1441' 
 
def send_email(train_date, train_num, one_num, two_num, wz_num): #函数中邮箱信息改为自己的 
 email_from = "123456@qq.com" 
 email_to = "654321@qq.com" 
 hostname = "smtp.qq.com" 
 login = "123456@qq.com" 
 password = "xddflwjfkkfkbidf" 
 subject = "train_tickets" 
 text = ("日期:%s 车次:%s 一等座:%s 二等座:%s 无座:%s "%(train_date, train_num, one_num, two_num, wz_num)) 
   
 smtp = SMTP_SSL(hostname) 
 smtp.login(login, password) 
 
 msg = MIMEText(text, "plain", "utf-8") 
 msg["Subject"] = Header(subject, "utf-8") 
 msg["from"] = email_from 
 msg["to"] = email_to 
 
 smtp.sendmail(email_from, email_to, msg.as_string()) 
 smtp.quit() 
 
driver = webdriver.Chrome() 
driver.get('https://kyfw.12306.cn/otn/index/init') 
 
elem = driver.find_element_by_id("fromStationText") 
elem.clear() 
elem.send_keys(from_station) 
elem.send_keys(Keys.ENTER) #写入始发站 
 
elem = driver.find_element_by_id("toStationText") 
elem.clear() 
elem.send_keys(to_station) 
elem.send_keys(Keys.ENTER) #写入终点站 
 
js = "document.getElementById('train_date').removeAttribute('readonly')" #去除日期栏只读属性 
driver.execute_script(js) 
 
elem=driver.find_element_by_id("train_date") 
elem.clear() 
elem.send_keys(train_date) #写入乘车日期 
elem.click() 
 
elem=driver.find_element_by_id("dc") #选择单程 
elem.click() 
 
elem=driver.find_element_by_id("a_search_ticket") #开始查询 
try: 
 elem.click()  
except Exception: 
 time.sleep(2) 
 
query_times = 0 
onetickets_last = 0 
twotickets_last = 0 
wztickets_last = 0 
 
time.sleep(2)  
while(1): 
 query_times = query_times+1 
 text="" 
 try: 
  driver.find_element_by_id("query_ticket").click() #根据查询键是否可以找到,以判断页面显示正确与否 
 except Exception: 
  driver.refresh() 
  time.sleep(5); 
  print("bug"); 
  continue 
 
 print("第%d次查询:"%(query_times)) 
 time.sleep(5) 
 
 try: 
  text = driver.find_element_by_id(ZYid).text 
 except Exception: 
  driver.refresh() 
  time.sleep(5); 
  print("bug") 
  continue 
 if not(driver.find_element_by_id(ZYid).text): 
  driver.find_element_by_id("query_ticket").click() 
  
 text = driver.find_element_by_id(ZYid).text #查询一等座余票 
 if(text == "有" or text == "无"): 
  onetickets_now = text 
  print("%s 一等座 : %s"%(train_num, onetickets_now)) 
  if(onetickets_now != onetickets_last): 
   onetickets_last = onetickets_now 
   #send_email(train_date, train_num, onetickets_last, twotickets_last, wztickets_last) 
 else: 
  onetickets_now = text 
  print("%s 一等座剩余票数 : %s"%(train_num, onetickets_now)) 
  if(onetickets_now != onetickets_last): 
   onetickets_last = onetickets_now 
   #send_email(train_date, train_num, onetickets_last, twotickets_last, wztickets_last) 
 
 text = driver.find_element_by_id(ZEid).text #查询二等座余票 
 if(text == "有" or text == "无"): 
  twotickets_now = text 
  print("%s 二等座 : %s"%(train_num, twotickets_now)) 
  if(twotickets_now != twotickets_last): 
   twotickets_last = twotickets_now 
   send_email(train_date, train_num, onetickets_last, twotickets_last, wztickets_last) 
 else: 
  twotickets_now = text 
  print("%s 二等座剩余票数 : %s"%(train_num,twotickets_now)) 
  if(twotickets_now != twoticketstwotickets_old): 
   twotickets_last = twotickets_now 
   send_email(train_date, train_num, onetickets_last, twotickets_last, wztickets_last) 
 
 text = driver.find_element_by_id(WZid).text #查询无座余票 
 if(text == "有" or text == "无"): 
  wztickets_now = text 
  print("%s 无座 : %s"%(train_num, wztickets_now)) 
  if(wztickets_now != wztickets_last): 
   wztickets_last = wztickets_now 
   send_email(train_date, train_num, onetickets_last, twotickets_last, wztickets_last) 
 else: 
  wztickets_now = text 
  print("%s 无座剩余票数 : %s"%(train_num, wztickets_now)) 
  if(wztickets_now != wztickets_last): 
   wztickets_last = wztickets_now 
   send_email(train_date, train_num, onetickets_last, twotickets_last, wztickets_last) 
 print("")

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python的多态性实例分析
Jul 07 Python
Python代码实现KNN算法
Dec 20 Python
pandas将DataFrame的列变成行索引的方法
Apr 10 Python
对python多线程中互斥锁Threading.Lock的简单应用详解
Jan 11 Python
python利用selenium进行浏览器爬虫
Apr 25 Python
解决Mac下使用python的坑
Aug 13 Python
python批量处理txt文件的实例代码
Jan 13 Python
计算Python Numpy向量之间的欧氏距离实例
May 22 Python
在pycharm中关掉ipython console/PyDev操作
Jun 09 Python
keras实现调用自己训练的模型,并去掉全连接层
Jun 09 Python
基于Python 函数和方法的区别说明
Mar 24 Python
python中filter,map,reduce的作用
Jun 10 Python
python利用smtplib实现QQ邮箱发送邮件
May 20 #Python
用Python下载一个网页保存为本地的HTML文件实例
May 21 #Python
Python读取本地文件并解析网页元素的方法
May 21 #Python
详解Python中的四种队列
May 21 #Python
Python实现的当前时间多加一天、一小时、一分钟操作示例
May 21 #Python
Python自定义函数实现求两个数最大公约数、最小公倍数示例
May 21 #Python
Python基于递归和非递归算法求两个数最大公约数、最小公倍数示例
May 21 #Python
You might like
ThinkPHP的MVC开发机制实例解析
2014/08/23 PHP
CodeIgniter基于Email类发邮件的方法
2016/03/29 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
html数组字符串拼接的最快方法
2009/09/16 Javascript
javascript中callee与caller的用法和应用场景
2010/12/08 Javascript
基于jquery的多功能软键盘插件
2012/07/25 Javascript
别了 JavaScript中的isXX系列
2012/08/01 Javascript
js,jquery滚动/跳转页面到指定位置的实现思路
2014/06/03 Javascript
向JavaScript的数组中添加元素的方法小结
2015/10/24 Javascript
Jsonp 关键字详解及json和jsonp的区别,ajax和jsonp的区别
2015/12/30 Javascript
Node.js的文件权限及读写flag详解
2016/10/11 Javascript
Angular组件化管理实现方法分析
2017/03/17 Javascript
canvas简单快速的实现知乎登录页背景效果
2017/05/08 Javascript
JQuery实现折叠式菜单的详细代码
2020/06/03 jQuery
[57:59]完美世界DOTA2联赛循环赛 Ink Ice vs LBZS BO2第一场 11.05
2020/11/05 DOTA
[06:57]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD 选手采访
2021/03/11 DOTA
python中matplotlib的颜色及线条控制的示例
2018/03/16 Python
django js实现部分页面刷新的示例代码
2018/05/28 Python
Python中出现IndentationError:unindent does not match any outer indentation level错误的解决方法
2020/04/18 Python
django 微信网页授权认证api的步骤详解
2019/07/30 Python
如何在python中实现随机选择
2019/11/02 Python
Python基础之字符串常见操作经典实例详解
2020/02/26 Python
Python爬取你好李焕英豆瓣短评生成词云的示例代码
2021/02/24 Python
python实现控制台输出颜色
2021/03/02 Python
Finishline官网:美国一家领先的运动品牌鞋类、服装零售商
2016/07/20 全球购物
兰蔻英国官网:Lancome英国
2019/04/30 全球购物
在Java开发中如何选择使用哪种集合类
2016/08/09 面试题
Java程序员面试90题
2013/10/19 面试题
酒店工作职员求职简历的自我评价
2013/10/23 职场文书
2014大学生党员评议个人总结
2014/09/22 职场文书
党的群众路线教育实践活动查摆剖析材料
2014/10/10 职场文书
2015年教育实习工作总结
2015/04/24 职场文书
学校远程教育工作总结
2015/08/11 职场文书
python实现商品进销存管理系统
2022/05/30 Python
Redis唯一ID生成器的实现
2022/07/07 Redis
微软发布Windows 11今年最大更新22H2(附 ISO 镜像官方下载)
2022/09/23 数码科技