前言
由于经常会遇到没票等现象,所以需要使用软件进行抢票,但由于一些软件有优先级问题,对于不舍得花钱的我来讲,并不是很好的体验,所以想自己尝试写一个类似的功能。
环境/插件
- Python3.6
- urllib(用于请求数据)
- smtplib(发送邮件)
文件目录
GrabTicket文件夹
-
city.py(12306城市)
-
GrabTicket.py(入口文件)
-
GrabTicketOperation.py(主文件)
-
GrabTicketSmtp.py(发送邮件文件)
分析
首先我们打开12306余票查询窗口
上图红色框的地方,就是表示列车有无车票的地方,我们需要根据这里边的数据来判断。
这里边有一些需要注意的就是,里边表示有票的有字符串“有”和数字“2”,所以我们需要对这两种情况进行判断。
接下来我们使用浏览器的开发者工具,来检查看看是否有接口可以使用:
这里我们可以看出,12306的列车查询是使用接口调用的,我们再来看看接口返回的数据:
我们可以清晰的看到,我们需要的列车数据是在data里边的result里边的数组,所以后面,我们只需要获取这里边的数据来判断就可以了。
分析数据
首先,我们得先分析数据,得出我们需要的数据字段,所以我们先写一段程序用来分析:
【python学习qq裙:10667510 送入门学习资料,萌新程序媛大本营】
# 复制接口数据result里边的一条数据出来分析
results = ["null|23:00-06:00系统维护时间|6i000D312606|D3126|IOQ|NJH|IOQ|AOH|07:00|18:43|11:43|IS_TIME_NOT_BUY|qYF9CwzWBb4rPwv7Upcl6nOKai0yleG2FqmgmU4EFKXjmLhu|20180721|3|Q6|01|28|1|0|||||||有||||有|无|||O0M0O0|OMO|0"]
# 初始化数组键值
c = 0
# 对结果集进行循环
for i in results:
# 将数据拆分成新的数组,并进行循环
for n in i.split('|'):
# 输出数组中每一个的数据n,以及下标值c
print('[%s] %s' %( c,n ))
# 下标值+1
c += 1
# 重置下标值c
c = 0
# 多个数据换行
print('\n\t')
运行代码,我们来看看效果图:
测试多几次之后,我们可以得出我们需要的数据所在的位置,接下来我们修改下程序进行输出:
# 复制接口数据result里边的一条数据出来分析 results = ["null|23:00-06:00系统维护时间|6i000D312606|D3126|IOQ|NJH|IOQ|AOH|07:00|18:43|11:43|IS_TIME_NOT_BUY|qYF9CwzWBb4rPwv7Upcl6nOKai0yleG2FqmgmU4EFKXjmLhu|20180721|3|Q6|01|28|1|0|||||||有||||有|无|||O0M0O0|OMO|0"] j = 1 # 初始化数组下标值 c = 0 # 初始化列车数组的下标值 index = 0 # 初始化列车数组 trains = [] # 对结果集进行循环 for i in results: # 为列车数组新增一个空数组元素 trains.append([]) # 将数据拆分成新的数组,并进行循环 for n in i.split('|'): # 输出数组中每一个的数据n,以及下标值c print('[%s] %s' %( c,n )) # 将每一个数据依次放入到列车数组中 trains[index].append(n) # 下标值+1 c += 1 # 重置下标值c c = 0 # 多个数据换行 print('\n\t') # 列车数组下标值+1 index += 1 # 对处理好的列车数组进行循环遍历 for train in trains: # 打印我们所需要的数据 print('火车:%s' %(train[3])) print('出发地:%s' %(train[6])) print('目的地:%s' %(train[7])) print('发车时间:%s' %(train[8])) print('到达时间:%s' %(train[9])) print('历时时间:%s' %(train[10])) print('商务座/特等座:%s' %(train[32])) print('一等座:%s' %(train[31])) print('二等座:%s' %(train[30])) print('高级软卧:%s' %(train[21])) print('软卧:%s' %(train[23])) print('硬卧:%s' %(train[28])) print('硬座:%s' %(train[29])) print('无座:%s' %(train[26])) print('\n\t')
运行,我们来看看结果:
这里边就是我们的结果集了,我们去12306页面对照一下:
看,我们的数据能对的上,证明我们已经分析对了数据,接下来,我们就可以实现我们的爬虫代码了:
from urllib import request import ssl import json # 通过爬虫爬取数据 def getTrains(): # 请求地址 url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2018-07-21&leftTicketDTO.from_station=SZQ&leftTicketDTO.to_station=SHH&purpose_codes=ADULT' # 请求头 headers = { 'User-Agent': r'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36' } # 设置请求 req = request.Request(ur