12306火车票余票查询&Python实现邮件发送
查询余票接口
打开12306官网,并进入余票查询页面,同时开启chrome浏览器F12控制台,以北京到上海为例,搜索2018年10月1日的余票信息,点击搜索按钮,可以在控制台发送了一条GET请求,请求结果以json字符串的形式放回,里面有查询到的余票信息。
通过python-requests来请求一下这个接口,比较意外的是这个接口并没有校验header信息,因此我们不用添加header。在测试中发现虽然12306官网主页提供了证书下载,但是这个https请求并不是必须校验证书,将requests方法中的verify参数设置为False取消校验也能正常返回结果。
import requests
url = 'https://kyfw.12306.cn/otn/leftTicket/queryA?leftTicketDTO.train_date=2018-10-01&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT'
requests.packages.urllib3.disable_warnings()
r = requests.get(url,verify=False).json()
yupiao = r['data']['result']
print(yupiao)
返回的json每一个元素就是一条火车线路,包含始发站代码,终点站代码,发车时间,每种座位的余票等信息,通过” | “分隔,需要注意的是每种座位的余票数量与网页展示的位置前后顺序并不是一一对应的,这个花了不少时间来确定每个对应关系。
将上一步返回结果放入循环中,每一个元素按照” | “符号分割,并从分割后的列表中依次取出需要的内容(城市代码,时间,车次,作为余票等信息)。
import requests
from tabulate import tabulate
#查询余票
def query():
url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2018-06-05&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT'
requests.packages.urllib3.disable_warnings()
r = requests.get(url,verify=False).json()
yupiao = r['data']['result']
table_header = ['车次','始发站','终点站','始发时间','到站时间','历时','商务特等座','一等座','二等座','高级软卧','软卧','动卧','硬卧','软座','硬座','无座'] #表格头
table_data = [] #数据添加至列表,作为表格的主体内容
for i in yupiao:
a = i.split('|') #分割字符串,a是个列表
is_null = a[0] #判断是否有票
train_code = a[3] #车次
start_city_code = a[4] #始发站城市代码
end_city_code = a[5] #终点站城市代码
start_time = a[8] #终点站开始时间
end_time = a[9] #终点站到达时间
total_time = a[10] #总共历时
shangwutedeng = a[32] #商务特等座
yideng = a[31] #一等座
erdeng = a[30] #二等座
gaojiruanwo = a[21] #高级软卧
ruanwo = a[23] #软卧
dongwo = a[33] #动卧
yingwo = a[28] #硬卧
ruanzuo = a[24] #软座
yingzuo = a[29] #硬座
wuzuo = a[26] #无座
#添加到元组
yupiao_tuple = (train_code,start_city_code,end_city_code,start_time,end_time,total_time,shangwutedeng,yideng,erdeng,gaojiruanwo,ruanwo,dongwo,yingwo,ruanzuo,yingzuo,wuzuo)
table_data.append(yupiao_tuple)
print(tabulate(table_data,headers=table_header,tablefmt='grid'))
在上面代码中使用了tabulate库,它可以把结果输出成易读的表格样式
参数化准备
再回头看之前请求的URL,这个GET请求有四个请求参数,分别代表如下:
leftTicketDTO.train_date --> 乘车日期
leftTicketDTO.from_station --> 始发站代码(例如北京北:VAP)
leftTicketDTO.to_station --> 终点站代码(例如上海虹桥:AOH)
purpose_codes --> 车票类型(普通票:ADULT,学生票:0X00)
第一个和第四个参数好填写,始发站和终点站代码我们现在并没有对应的表,不知道每个站点对应的代码,在网站上找一下。我们在页面上手动修改始发站和终点站的时候发现并没有发送新的https请求,可以猜测所有的站点信息应该是在一个js文件里面,然后通过页面的js方法来选择不同的站名,现在F12控制台切换至JS模块下,刷新这个余票查询页面。
python 发送邮件
import smtplib
from email.mime.text import MIMEText
# 第三方 SMTP 服务
mail_host = "smtp.163.com" # SMTP服务器
mail_user = "username" # 用户名
mail_pass = "passwd" # 密码
sender = 'user@163.com' # 发件人邮箱(最好写全, 不然会失败)
receivers = ['to_someone@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
content = '邮件内容!'
title = '邮件主题' # 邮件主题
message = MIMEText(content, 'plain', 'utf-8') # 内容, 格式, 编码
message['From'] = "{}".format(sender)
message['To'] = ",".join(receivers)
message['Subject'] = title
try:
smtpObj = smtplib.SMTP_SSL(mail_host, 465) # 启用SSL发信, 端口一般是465
smtpObj.login(mail_user, mail_pass) # 登录验证
smtpObj.sendmail(sender, receivers, message.as_string()) # 发送
print("mail has been send successfully.")
except smtplib.SMTPException as e:
print(e)
注意: 如果出现此以下报错信息,看下邮件主题是否为test,网易不允许这个也是奇葩
smtplib.SMTPDataError: (554, b'DT:SPM 163 smtp10,DsCowAA3h9_QbgZXI9_fCQ--.713S2 1460039376,please see http://mail.163.com/help/help_
12306火车票余票查询&Python实现邮件发送的更多相关文章
- 火车车次查询-余票查询--Api接口
1.来自12306的火车车次数据 使用12306网站的接口,查询余票.此接口采集自 这里. 全国火车站代号字典,下载 . 火车票余票查询 http://dynamic.12306.cn/otsquer ...
- Python大法之从火车余票查询到打造抢Supreme神器
本文作者:i春秋作家——阿甫哥哥 系列文章专辑:https://bbs.ichunqiu.com/forum.php?mod=collection&action=view&ctid=9 ...
- 12306微信小程序上线 提供余票查询暂不支持购票
12306微信小程序正式上线,如图所示,目前小程序提供余票查询.时刻表查询和正晚点查询三大功能,用户可在这里随时查看剩余车票以及列车时刻表.而且小程序支持用户添加行程,方便出行. 目前这款小程序还不支 ...
- 用Python实现邮件发送Hive明细数据
代码地址如下:http://www.demodashi.com/demo/12673.html 一.需求描述 客户需要每周周一接收特定的活动数据,生成Excel或是CSV文件,并通过邮件发送给指定接收 ...
- Python 基于Python实现邮件发送
基于Python实现邮件发送 by:授客 QQ:1033553122 测试环境: Python版本:Python 2.7 注:需要修改mimetypes.py文件(该文件可通过文章底部的网盘分 ...
- java抓取12306火车余票信息
最近在弄一个微信的公众帐号,涉及到火车票查询,之前用的网上找到的一个接口,但只能查到火车时刻表,12306又没有提供专门的查票的接口.今天突然想起自己直接去12306上查询,抓取查询返回的数据包,这样 ...
- python SMTP邮件发送(转载)
Python SMTP发送邮件 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. py ...
- python实现邮件发送完整代码(带附件发送方式)
实例一:利用SMTP与EMAIL实现邮件发送,带附件(完整代码) __author__ = 'Administrator'#coding=gb2312 from email.Header import ...
- python实现邮件发送
实例补充: #**************************利用STMP自动发送邮件******************************import smtplibsmtp = smtp ...
随机推荐
- 转:后置处理器JSON Extractor 提取json的多个值
json串 []表示对象组成的数组,{}表示对象. 对象里包含多个 "属性":属性值.属性值可以是值,或数组,或对象. JSON Extractor使用json path表达式匹配 ...
- heartrbeat实现web服务器高可用
今天的内容是用heartbeat实现web服务器高可用 一.简介: heartbeat的工作原理:heartbeat最核心的包括两个部分,心跳监测部分和资源接管部分,心跳监测可以通过网络链路和串口进行 ...
- MySql数据类型及对应存储空间
整数型数据类型 类型名称 说明 存储需求 TINYINT 很小的正数 1个字节 SMALLINT 小正数 2个字节 MEDIUMINT 中等大小的正数 3个字节 INT(INTEGER) 普通大小的正 ...
- GIT上面有的分支,本地却无法检出,也看不到该分支
正常情况在gitlib上面可以看到代码里面有develop的分支 然而本地在查看所有分支的时候却报错 #查看所有的分支 git branch -a 这种情况是没有更新远程分支的索引,所以这样是看不到的 ...
- 【零基础】彻底搞懂51单片机各种型号(ATMEL系列)
零.前言 初学者开始学习51单片机时往往先是一愣,说好51单片机啊,咋个型号是AT89C52,这个S52又是咋回事?上学的时候大都懵懵懂懂就这么用着,但始终没整明白,所以今天我们就彻底搞明白这些“51 ...
- Nginx-HTTP之框架的初始化
http 框架的初始化与 nginx-rtmp 框架的初始化类似: Nginx-rtmp之配置项的管理 1. ngx_http_module_t ngx_http_module 核心模块定义了新的模块 ...
- JVM | 分代垃圾回收策略的基本概念以及过程
一.为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对 ...
- 前端知识点回顾之重点篇——CSS中的BFC
BFC布局(Block Formatting Contexts) 来源:https://www.cnblogs.com/lzbk/p/6057097.html 块级格式化上下文是页面中的一块渲染区域, ...
- C++ STL——deque
目录 一 deque容器 1.1 deque容器基本概念 1.2 deque构造函数 1.3 deque赋值操作 1.4 deque大小操作 1.5 deque双端插入和删除操作 1.6 deque数 ...
- 初步理解js作用域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...