马上暑假集训结束,又要开学了,暑假集训老师让我们交暑假的学习成果~~虽然制作了几个小的网络爬虫的东西软件,什么淘宝,京东,天气,图片爬取的....但还是想要交个更好的,毕竟还是有成绩的。。。爬取12306功能是实现了,但是图形界面看到一位博主模仿12306把图形界面写的那么好看,我就搬过来,不停的修改,一直有个BUG错,两个py文件调用其中一个函数返回的列表居然是空的!!!然而打印那个列表有正确的数据!!难受,网上也搜索了问题,也自己试了一下,感觉方法没错。。。。就是有问题

还是回归正题吧,这里直说爬取12306功能的到实现,以及展示,图形界面(升级版)点击传送门:https://blog.csdn.net/memory_qianxiao/article/details/81987185

环境:python3.6 (虽然目前最新版是3.7 但是一些库还没与3.7调试好,可能会出问题)编译器用你自己喜欢的就好~

第三方库:requests(网页请求),re(正则提取信息),datetime(日期时间),time,json(把数据转字典),prettytable(使输出美观),colorama(上色)

先放一张效果图镇楼!!

当你打开12306网址进行查票的时候,查询了后可以看到结果:

然后按F12,我们可以看到查票的网址:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2018-08-22&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=HZH&purpose_codes=ADULT

但是你会惊讶的发现,请求网址里面没有我们输入的成都和杭州!这里我就不拐弯了,因为12306把输入的车站名字,转换成对应的车站代码了,比如上面的成都和杭州就转成了CDW,HZH。所以当我们程序输入的时候需要处理一下输入,把输入的车站转换成对应的车站代码。

在12306里面有所有车站和车站对应的代码:访问这个网址:https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971

发现密密麻麻的车站和对应的车站代码,所以这里我们要用正则提取车站和车站代码,把对应车站和代码关联起来,同时在把key和values交换关联一下,建立起来键值对。对输入的汉字转换成代码,同时也可以把代码转换成汉字。

这里贴出代码:

import re,requests
#访问12306存有的所有车站
url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971'
response = requests.get(url, verify=False)
#提取车站名字和代码
stations = re.findall(r'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)
station_codes=dict(stations)
#把车站名字和代码,交换一下,重新建立键值对
station_names=dict(zip(station_codes.values(),station_codes.keys()))

这里我们打印一下结果:由于很长,我就截取一部分,可以看见建立了字典。

到时候就能够对输入的数据进行转化。

接下来是重点:是功能的实现

创建三个函数

主函数:入口     请求的网址我们需要传入三个参数,起点,终点,时间,在上面网址我标红了。

def main():#调用系统本地时间date=time.strftime("%Y-%m-%d",time.localtime())#调用上面处理所有车站的代码,需要当做第三方库引入,待会完整版代码展示from_station=station_codes[input("请输入起始站:\n")]to_station=station_codes[input("请输入目地站:\n")]url="https://kyfw.12306.cn/otn/leftTicket/query?"headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5702.400 QQBrowser/10.2.1893.400"}#time=entry_time.get()#start=entry_start.get()#end=entry_end.get()url=url+'leftTicketDTO.train_date='+date+'&leftTicketDTO.from_station='+from_station+'&leftTicketDTO.to_station='+to_station+'&purpose_codes=ADULT'html=getHtmltext(url,headers)showTicket(html)

请求网址以及数据的返回:

def getHtmltext(url,headers):r=requests.get(url,headers=headers)r.raise_for_status()r.encoding=r.apparent_encodingreturn r.text

展示票的函数:里面有颜色,也可以把颜色去掉,因为在pycharm里面,用了也不会显示颜色,只有在dos窗口就可以显示颜色。这里需要说一下prettytable,它能够是输出的数据美观化,具体用法,请百度~其实展示票的函数可以不要这么长的代码的,几十行就可以的,只是为了模仿12306对没有票的用-代替美观化的。

这里面我们要说一下请求网址返回的数据:

虽然数据看起来确实比较乱,不过发现里面是双重字典,我们提取里面的信息先转成json,然后for i in html['data']['result']这种遍历提取里面所有的信息,然后有很多||符号,所以用split('|')分割。就把对应的数据取出来。里面是一个列表,车次在3号位置,始发站信息在6号位置,出发时间信息在8号位置,抵达时间在9号位置......

def showTicket(html):html=json.loads(html)table=PrettyTable(["车次","出发/到达车站","出发/到达时间","历时","商务座","一等座","二等座","高级软卧","软卧","动卧","硬卧","软座","硬座","无座","其他","备注"])for i in html['data']['result']:name = ["station_train_code","from_station_name",'start_time',"lishi","swz_num","zy_num","ze_num","gr_num","rw_num","dw_num","yw_num","rz_num","yz_num","wz_num","qt_num","note_num"]data={"station_train_code": '',"from_station_name": '',"to_station_name": '','start_time': '','end': '',"lishi": '',"swz_num": '',"zy_num": '',"ze_num": '',"dw_num": '',"gr_num": '',"rw_num": '',"yw_num": '',"rz_num": '',"yz_num": '',"wz_num": '',"qt_num": '',"note_num": ''}item = i.split('|')#用"|"进行分割data['station_train_code'] = item[3]#车次在3号位置data['from_station_name'] = item[6]#始发站信息在6号位置data['to_station_name'] = item[7]#终点站信息在7号位置data['start_time'] = item[8]#出发时间信息在8号位置data['arrive_time'] = item[9]#抵达时间在9号位置data['lishi'] = item[10]#经历时间在10号位置data['swz_num'] = item[32] or item[25]# 特别注意:商务座在32或25位置data['zy_num'] = item[31]#一等座信息在31号位置data['ze_num'] = item[30]#二等座信息在30号位置data['gr_num'] = item[21]#高级软卧信息在31号位置data['rw_num'] = item[23]#软卧信息在23号位置data['dw_num'] = item[27]#动卧信息在27号位置data['yw_num'] = item[28]#硬卧信息在28号位置data['rz_num'] = item[24]#软座信息在24号位置data['yz_num'] = item[29]#硬座信息在29号位置data['wz_num'] = item[26]#无座信息在26号位置data['qt_num'] = item[22]#其他信息在22号位置data['note_num'] = item[1]#备注在1号位置color = Colored()#创建Colored对象data["note_num"]=color.white(item[1])#如果没有信息用'-'代替for pos in name:if data[pos]=='':data[pos]='-'tickets=[]cont=[]cont.append(data)for x in cont:tmp = []for y in name:if y == "from_station_name":s = color.green(station_names[data['from_station_name']])+ '\n' +color.red(station_names[data["to_station_name"]])tmp.append(s)elif y == "start_time":s = color.green(data['start_time']) + '\n' + color.red(data["arrive_time"])tmp.append(s)elif y == "station_train_code":s = color.yellow(data['station_train_code'])tmp.append(s)else:tmp.append(data[y])tickets.append(tmp)for ticket in tickets:table.add_row(ticket)print(table)

在上面数据有color的,只是为了更方便看,但是编译器显示不出来,所以可以去掉。

接下来贴出完整代码:


#
import requests,re,datetime,time,json,datetime
from tkinter import*
from tkinter import messagebox
from prettytable import PrettyTable
#这个库是自己写的,把所有车站提取出来的.py文件,我也会放在下面。
from stationsInfo import station_codes,station_names
from colorama import init,Fore,Back,Style
def getHtmltext(url,headers):r=requests.get(url,headers=headers)r.raise_for_status()r.encoding=r.apparent_encodingreturn r.text
init(autoreset=False)
class Colored(object):#  前景色:红色  背景色:默认def red(self, s):return Fore.LIGHTRED_EX + s + Fore.RESET#  前景色:绿色  背景色:默认def green(self, s):return Fore.LIGHTGREEN_EX + s + Fore.RESETdef yellow(self, s):return Fore.LIGHTYELLOW_EX + s + Fore.RESETdef white(self,s):return Fore.LIGHTWHITE_EX + s + Fore.RESETdef blue(self,s):return Fore.LIGHTBLUE_EX + s + Fore.RESET
def showTicket(html):html=json.loads(html)table=PrettyTable(["车次","出发/到达车站","出发/到达时间","历时","商务座","一等座","二等座","高级软卧","软卧","动卧","硬卧","软座","硬座","无座","其他","备注"])for i in html['data']['result']:name = ["station_train_code","from_station_name",'start_time',"lishi","swz_num","zy_num","ze_num","gr_num","rw_num","dw_num","yw_num","rz_num","yz_num","wz_num","qt_num","note_num"]data={"station_train_code": '',"from_station_name": '',"to_station_name": '','start_time': '','end': '',"lishi": '',"swz_num": '',"zy_num": '',"ze_num": '',"dw_num": '',"gr_num": '',"rw_num": '',"yw_num": '',"rz_num": '',"yz_num": '',"wz_num": '',"qt_num": '',"note_num": ''}item = i.split('|')#用"|"进行分割data['station_train_code'] = item[3]#车次在3号位置data['from_station_name'] = item[6]#始发站信息在6号位置data['to_station_name'] = item[7]#终点站信息在7号位置data['start_time'] = item[8]#出发时间信息在8号位置data['arrive_time'] = item[9]#抵达时间在9号位置data['lishi'] = item[10]#经历时间在10号位置data['swz_num'] = item[32] or item[25]# 特别注意:商务座在32或25位置data['zy_num'] = item[31]#一等座信息在31号位置data['ze_num'] = item[30]#二等座信息在30号位置data['gr_num'] = item[21]#高级软卧信息在31号位置data['rw_num'] = item[23]#软卧信息在23号位置data['dw_num'] = item[27]#动卧信息在27号位置data['yw_num'] = item[28]#硬卧信息在28号位置data['rz_num'] = item[24]#软座信息在24号位置data['yz_num'] = item[29]#硬座信息在29号位置data['wz_num'] = item[26]#无座信息在26号位置data['qt_num'] = item[22]#其他信息在22号位置data['note_num'] = item[1]#备注在1号位置color = Colored()#创建Colored对象data["note_num"]=color.white(item[1])#如果没有信息用'-'代替for pos in name:if data[pos]=='':data[pos]='-'tickets=[]cont=[]cont.append(data)for x in cont:tmp = []for y in name:if y == "from_station_name":s = color.green(station_names[data['from_station_name']])+ '\n' +color.red(station_names[data["to_station_name"]])tmp.append(s)elif y == "start_time":s = color.green(data['start_time']) + '\n' + color.red(data["arrive_time"])tmp.append(s)elif y == "station_train_code":s = color.yellow(data['station_train_code'])tmp.append(s)else:tmp.append(data[y])tickets.append(tmp)for ticket in tickets:table.add_row(ticket)print(table)
def main():date=time.strftime("%Y-%m-%d",time.localtime())from_station=station_codes[input("请输入起始站:\n")]to_station=station_codes[input("请输入目地站:\n")]url="https://kyfw.12306.cn/otn/leftTicket/query?"headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5702.400 QQBrowser/10.2.1893.400"}#time=entry_time.get()#start=entry_start.get()#end=entry_end.get()url=url+'leftTicketDTO.train_date='+date+'&leftTicketDTO.from_station='+from_station+'&leftTicketDTO.to_station='+to_station+'&purpose_codes=ADULT'print(url)html=getHtmltext(url,headers)showTicket(html)
main()

stationinfo:

import re,requestsurl = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971'
response = requests.get(url, verify=False)
stations = re.findall(r'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)
station_codes=dict(stations)
station_names=dict(zip(station_codes.values(),station_codes.keys()))

python 3爬取 12306余票相关推荐

  1. Python爬虫学习(七)执行定时任务爬取12306余票信息发送邮件通知

    分析 我们输入的上海,北京都变成了对应的编号,比如,上海(SHH).北京(BJP),所以当我们程序进行输入的时候要进行一下处理,12306的一个地方存储着这些城市名与编码对应的文档: GET请求: h ...

  2. 爬取12306余票信息返回“网络可能存在问题,请您重试一下!”

    增加Cookie,这是因为request.get()它就是独立的一次访问,没有携带前几个访问请求反馈后的状态.不敲门就进别人屋,主人肯定会生气 相当于把每次请求看成了独立浏览器去完成的,没有保存上一次 ...

  3. 12306车站信息爬取(3)——余票信息的查询(内含prettytable和colorama模块)

    12306车站信息定向爬虫-可实现查询功能 这个程序可实现由键盘输入出发站.到达站.出发日期以及需要查询的天数,首先将全部代码给出,然后我会分块对该代码进行讲解.在此之前,先说一下思路: 1.首先从1 ...

  4. python + selenium 爬取12306所有车站车次数据

    python + selenium 驱动谷歌浏览器 实现模拟人工爬取车次数据,特别注意 谷歌版本和驱动器版本. 驱动获取地址:https://blog.csdn.net/weixin_44186072 ...

  5. python爬取12306实现按车次查询余票

    前言 本篇博客想写很久了,以前抢票时不知道你们有没有这种情况,比如你想买郑州到长春k926这个车次的票,但是车票买完了抢不到票,于是我就想多买几站看没有票,其实也贵不了多少.也就是说我想多买几站买这个 ...

  6. Python爬虫实战之12306抢票

    12306抢票 前言 一.爬虫是什么? 二.使用步骤 1.引入库 2.爬虫代码 3.城市编码 4.主程序 总结 前言 提示:用python实现简单的12306余票查询 提示:以下是本篇文章正文内容,下 ...

  7. python爬火车票_python爬取12306火车余票程序(一)

    首先说一下大体的流程,简单的流程图如下: 1.获取URL 打开12306余票查询的 网页链接,浏览器(我用的chrome)按F12来分析请求.输入要查询的起始地点和时间后点击查询,可以看到右侧抓到的链 ...

  8. 2021最新 python爬取12306列车信息自动抢票并自动识别验证码(三)购票篇

    项目前言 tiebanggg又来更新了,项目--[12306-tiebanggg-master]注:本项目仅供学习研究,如若侵犯到贵公司权益请联系我第一时间进行删除:切忌用于一切非法途径,否则后果自行 ...

  9. 2021最新python爬取12306列车信息自动抢票并自动识别验证码

    项目描述 项目前言 tiebanggg又来更新了,项目--[12306-tiebanggg-master]注:本项目仅供学习研究,如若侵犯到贵公司权益请联系我第一时间进行删除:切忌用于一切非法途径,否 ...

最新文章

  1. ArcGIS License Manager 更新
  2. 观星(计算几何/凸包/多边形面积)
  3. 【程序设计】编程语言的抽象层次
  4. 女大学生毕业相亲程序员,吃了一顿大排档,一看车钥匙后犹豫了!
  5. C++头文件和源文件,编译过程
  6. [Web Chart系列之五] 4. 实战draw2d(Raphael)之取消Chrome中Label Text 全部选中
  7. 基于FPGA----VGA显示跳动的小白框设计
  8. 一行命令开启VNC 和windows之间复制粘贴功能
  9. Unique Binary Search Trees,Unique Binary Search Trees2 生成二叉排序树
  10. ConfuserEx
  11. 职称论文发表教育期刊《中小学教育》杂志简介及投稿须知
  12. [NISACTF 2022]上
  13. imx6 android gadget,imx6q安卓启动失败显示Suspending console(s)(已解决)
  14. 京东价格监控软件开发技术探讨七:如何获取京东商品评价信息
  15. 计算机网络-数据交换技术
  16. 【自然语言处理】【向量表示】PairSupCon:用于句子表示的成对监督对比学习
  17. 成长了,记录一下,增值税发票识别写入excel文件里
  18. 利用棋盘格图案完成相机标定
  19. 【标签】那些想读的书
  20. 脚本---perl与python的比较

热门文章

  1. OSI七层模型及其功能
  2. 平流式沉淀池流量计算_沉淀池设计计算(平流式
  3. Recsys2021 | 基于Transformer的会话推荐
  4. 1194C语言实验——余弦
  5. JAMA发表备受期待的22nd Century SPECTRUM(R)极低尼古丁含量香烟III期研究结果
  6. android 绘图之Path与Paint详解
  7. 无人驾驶特斯拉如何布局?
  8. 人生需看11个小故事
  9. 网络图片转换为文件类型
  10. abs 三种功能及代码详解 matlab函数