今年回家过年,不用担心买不到票。
虽然我不用抢票,但是还是研究了一下怎么抢票。
程序员嘛,就是要对一切问题进行解构,探索原理本质,寻找规律,将其自动化。。。
好了,言归正传,开始。
1.首先,打开12306网。选个自己要买的路段,我这里是随便选的。
然后点击查询。
image
2.按下F12,设置如红色框。然后重新点击查询,看看浏览器都发送了什么给服务器。
从下图看,是发送了两条。Python入门到精通学习教程请加219再加上539然后519内有大量学习教程,欢迎大家加入
image
3.分别点击发送的两条,查看返回结果。可以看到第二条里面有当前网页车票相关的信息。比如“有”就是显示在网页上面的车票后面的有字,“大连”就是出发站信息。于是,我们知道车票信息是在这里面。实际这是个json格式的数据。
image
image
4.继续查看这条请求访问的链接。如下。
image
于是,我们可以用requests库来模拟浏览器访问。很简单,具体写作如下:
import requests
def check():
response = requests.get('https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2018-01-13&leftTicketDTO.from_station=DLT&leftTicketDTO.to_station=DUT&purpose_codes=ADULT')
# print(response.text)
# print(response.json())
result = response.json()
return result['data']['result']
5.那么,如下图车票的有无信息是如何提取出来呢?
image
仔细观察发现,“有”“无”“-”信息是用“|”线来分割的。而且为了防止爬取,顺序是和网页显示不一样的。探究规律如下:
无座 26
软卧 23
硬座 29
硬卧 28
特等商务座 32
一等座 31
二等座 30
数字意思:软卧 23 意思是第23个字符内容对应的是软卧的有无票状态。
''' 无座 26 软卧 23 硬座 29 硬卧 28 特等商务座 32 一等座 31 二等座 30 '''
这里,我们选择硬座,如下编写:
nu = 0
for i in check():
# print(i)
tmp_list = i.split('|')
# print(tmp_list[2:]) #这里只是为了确定数字与座位类别的对应关系
# for n in tmp_list:
# print(nu,n)
# nu += 1
# nu = 0
if tmp_list[31] != '无' and tmp_list[31] != '-':
print("有票",tmp_list[3])
和上面的程序结合,运行如下:
image
6.与网页对比,结果一致。D7411因为没有票,所以被程序剔除。
image
7.到这里,可以证明程序是可以获取车票状态的。那么怎么通知给我呢?
可以通过发邮件的方式。
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr,formataddr
import smtplib
def _format_addr(s):
name,addr=parseaddr(s)
return formataddr((Header(name,'utf-8').encode(),addr))
sender_addr='[email protected]' #改成你自己邮箱
password='your_email'#改成你自己的密码
to_addr='[email protected]'#你要发送的地址
smtp_server='smtp.163.com'#这个要是用网易的邮箱就不用改
msg=MIMEText('车票信息','plain','utf-8')
msg['From']=_format_addr('<%s>'% sender_addr)
msg['To']=_format_addr('<%s>'%to_addr)
msg['Subject']=Header('test','utf-8').encode()
server=smtplib.SMTP(smtp_server,25)
server.login(sender_addr,password)
server.sendmail(sender_addr,[to_addr],msg.as_string())
server.quit()
8.但是邮件即时性不好,要是有票能自动打电话或者发短信就好了。
于是,找到了这样的服务。
image
“阿里大于”可以提供有偿的短息和语音服务。具体可以实现短信通知,或者电话通知,电话语音的内容是可以自己设置的。只要调用它给的api,然后把有票的列车信息作为参数传给它就可以了。当Python脚本检测到有票的时候,就会给阿里大于api发送哪些车有票等信息。阿里大于呢,会拨打我设置好的电话号码,通知我。这个电话是自动的,语音内容是将脚本传递给阿里大于的文本信息转为语言播放给电话前的我的。