Pojie1999.0909 发表于 2018-1-17 18:36

Python打造刷火车票工具邮件通知自己

本帖最后由 Pojie1999.0909 于 2018-1-18 08:26 编辑

准备环境
win10操作系统、python3.6、python库
docopt、requests、pyinstaller
效果
http://img.blog.csdn.net/20180117172936922?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0dTX19fX19fXw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
http://img.blog.csdn.net/20180117172952864?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0dTX19fX19fXw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


开始
懒得写了,,贴代码

#coding:utf-8
"""命令行火车票查看器

Usage:
    tk [-gdtkz] <from> <to> <date>

Options:
    -h,--help 显示帮助菜单
    -g      高铁
    -d      动车
    -t      特快
    -k      快速
    -z      直达

Example:
    tk 石家庄 昌黎 2016-10-10
    tk -dg 石家庄 昌黎 2016-10-10
"""
'''
Created on 2018年1月17日

@author: DELL
'''
import smtplib
from email.mime.text import MIMEText
import time
from stations import stations as sta
from docopt import docopt
import requests

def sendMail(subject,body):
    try:
      """发送邮件"""
      msg = MIMEText(body)
      msg["Subject"] = subject
      msg["From"] = "的qq邮箱"#from
      msg["To"] = "的qq邮箱"#to
   
      s = smtplib.SMTP_SSL("smtp.qq.com", 465)
      s.login("你的qq邮箱","你的qq邮箱授权码")#这里的第二个参数为qq邮箱授权码,不要填你的密码
      s.sendmail("你的qq邮箱",["的qq邮箱",],msg.as_string())#from,to,msg
      s.quit()
      print("刷到票拉!邮件发送成功!")
    except Exception as e:
      print("刷到票拉!可是邮件发送失败~~"+e.message)

class TrainCollection:
    header = '车次 车站 时间 历时 一等 二等 软卧 硬卧 硬座 无座'.split() #23软卧 24软座26无座 28硬卧 29硬座 30二等 31一等 32商务特等

    def __init__(self,available_trains,options,fromto):
      """查询到的火车班次集合
      :param available_trains:一个列表,包含可获得的火车班次,每个火车班次是一个字典
      :param options:查询的选项,如高铁,动车,etc...
      """
      self.available_trains = available_trains
      self.options = options
      self.fromto = fromto

    #def _get_duration(self,raw_train):
    #    duration = raw_train.get('lishi').replace(':','小时')+'分'

    @property
    def trains(self):
      train_no = self.available_trains
      initial = train_no.lower()
      if not self.options or initial in self.options:
            train = [
                train_no,
                '\n'.join(, self.fromto]),
                '\n'.join(, self.available_trains]),
                self.available_trains,
                self.available_trains,
                self.available_trains,
                self.available_trains,
                self.available_trains,
                self.available_trains,
                self.available_trains
            ]
            yield train
    """
    def pretty_print(self):
      pt = PrettyTable()
      pt._set_field_names(self.header)
      for train in self.trains:
            pt.add_row(train)
      print(pt)
    """
   
    def CanISendMessage(self):
      flag = False
      for train in self.trains:
            if train=='有' or train=='有':
                return True
      return flag

def checkIt():
    url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(date,from_station,to_station)
    """测试
    print(url)
    html = urlopen(url)
    print(html.read())
    temp = json.loads(html.read())
    print(temp)
    print(type(temp))
    print(temp["data"])
    print(temp["data"]["result"])
    """
    headers = {
      "Accept-Encoding": "gzip, deflate, br",
      "Accept-Language": "zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3",
      "Connection": "Keep-Alive",
      "Cookie": "JSESSIONID=A9C5372008A2D67B84E8EABF0F040B7A; RAIL_DEVICEID=MBKbxqbUfDzzIpo2brgvh_2cPdBFvBQVpXv2Kj43TpRT7ARJkdxFoKdhk4Blw8JQi63NCxMhXtxxR3FVMuhhnTVcKJKExL4rrMG6V_jNCOhEpR9bukvfJKf609zJbLB6r8lhCZk2kcOktpO0MJ1_mONunAQSp1Mu; RAIL_EXPIRATION=1516446126590; route=6f50b51faa11b987e576cdb301e545c4; BIGipServerotn=401605130.64545.0000; acw_tc=AQAAAMsuNmmy6gMAPZPvfGHGldIGyAY9; _jc_save_toStation=%u660C%u9ECE%2CCLP; _jc_save_wfdc_flag=dc; _jc_save_toDate=2018-01-17; _jc_save_fromDate=2018-02-11; _jc_save_fromStation=%u77F3%u5BB6%u5E84%2CSJP",
      "Host": "kyfw.12306.cn",
      "If-Modified-Since": "0",
      "Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299",
      "X-Requested-With": "XMLHttpRequest",
      "Cache-Control": "no-cache"
      }
    print (url)
    r = requests.get(url,headers=headers,verify=False)
    print(r.text)
    result = r.json()['data']['result']
    result_len = len(result)
    print(result)
   
    #获取参数
    options = ''.join([
      #使用生成器表达式
      key for key,value in arguments.items() if value is True
    ])
    fromto = (
      arguments['<from>'],
      arguments['<to>']
    )
   
    for i in range(result_len):
      #print(result.split('|'))
      if(TrainCollection(result.split('|'),options,fromto)):
            sendMail("乞丐刷票 - by cgsthtm", "大人!有回家的车票啦!终于可以回家啦~~快去抢啊!!")

def cli():
    """接受命令行输入参数"""
    while True:
      checkIt()
      time.sleep(60)#每60秒执行一次

arguments = docopt(__doc__)
from_station = sta.get(arguments["<from>"])
to_station = sta.get(arguments["<to>"])
date = arguments["<date>"]

if __name__ == "__main__":
    cli()
   



""" test
msg = MIMEText("the body of the email is here")

msg["Subject"] = "An Email Alert"
msg["From"] = ""
msg["To"] = ""

s= smtplib.SMTP('smtp.qq.com')
s.send_message(msg)
s.quit()
"""


Removeformat
注意
改成你自己的邮箱账号和授权码

http://img.blog.csdn.net/20180117173038484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0dTX19fX19fXw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
http://img.blog.csdn.net/20180117173057071?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0dTX19fX19fXw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

用法


顺便加上昨天忘记上传的附件





Pojie1999.0909 发表于 2018-1-17 18:39

查询频率,一分钟查询一次
如果有硬座或硬卧就发邮件通知自己
不想限制硬座硬卧的自己改吧

Pojie1999.0909 发表于 2018-1-22 08:07

一米阳光几度暖 发表于 2018-1-22 00:20
from stations import stations as sta
ImportError: No module named 'stations'我是了下,报错,请 ...

stations是一个py文件,把这个附件下载放到tks.py同级目录下就好啦

nxl415 发表于 2018-1-17 18:54

谢谢,分给你
i

While_Shark 发表于 2018-1-17 18:56

支持支持,太厉害了

shghe 发表于 2018-1-17 18:56

就算查到了,等你去买的时候什么都没了

葫芦炒鸡蛋 发表于 2018-1-17 18:57

不明觉厉

yjw554300 发表于 2018-1-17 19:01

你就不能写简单一点吗。

zrw931103 发表于 2018-1-17 19:01

邮件通知到你,也没了吧。。。直接变成买的不好麽

xlxxb 发表于 2018-1-17 19:21

谢谢你的分享

普罗米修修斯 发表于 2018-1-17 19:28

谢谢楼主分享
页: [1] 2 3 4
查看完整版本: Python打造刷火车票工具邮件通知自己