今天就和大家一起来讨论一下python实现12306余票查询(pycharm+python3.7),一起来感受一下python爬虫的简单实践

我们说先在浏览器中打开开发者工具(F12),尝试一次余票的查询,通过开发者工具查看发出请求的包

余票查询界面

可以看到红框框中的URL就是我们向12306服务器发出的请求,那么具体是什么呢?我们来看看
https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2019-01-21&leftTicketDTO.from_station=CDW&leftTicketDTO.to_station=SZQ&purpose_codes=ADULT
可以看到发出请求的几个字段:

leftTicketDTO.train_date:查询的日期
leftTicketDTO.from_station:查询的出发地
leftTicketDTO.to_station:查询的目的地
purpose_codes:不太清楚这个字段是用来做什么的,就默认吧

可以从我们递交的URL请求看出,我们输入的成都,深圳都变成了对应的编号,比如,成都(CDW)、深圳(SZQ),所以当我们程序进行输入的时候要进行一下处理,12306的一个地方存储着这些城市名与编码对应的文档:

https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971

站点编码对应

下面我们就编写一个小程序,将这些城市名与编号提取出来:

'''
想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!
'''
import re,requests
url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971"
response = requests.get(url,verify=False)
#将车站的名字和编码进行提取
chezhan = re.findall(r'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)
chezhan_code = dict(chezhan)
#进行交换
chezhan_names = dict(zip(chezhan_code.values(),chezhan_code.keys()))
#打印出得到的车站字典
print(chezhan_names)

得到的打印结果如下(只截取部分显示):

{'VAP': '北京北', 'BOP': '北京东', 'BJP': '北京', 'VNP': '北京南', 'BXP': '北京西', 'IZQ': '广州南', 'CUW': '重庆北', 'CQW': '重庆', 'CRW': '重庆南', 'CXW': '重庆西', 'GGQ': '广州东', 'SHH': '上海', 'SNH': '上海南', 'AOH': '上海虹桥', 'SXH': '上海西', 'TBP': '天津北', 'TJP': '天津', 'TIP': '天津南', 'TXP': '天津西', 'XJA': '香港西九龙', 'CCT': '长春', 'CET': '长春南', 'CRT': '长春西', 'ICW': '成都东', 'CNW': '成都南', 'CDW': '成都', 'CSQ': '长沙', 'CWQ': '长沙南',}

接下来我们就动手开始程序的主要代码编写:

def main():date     = input("请输入时间(如2019-01-22):\n")from_station = chezhan_code[input("请输入起始站点:\n")]to_station  = chezhan_code[input("请输入目的站点:\n")]url     = "https://kyfw.12306.cn/otn/leftTicket/queryZ?"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"}url=url+"leftTicketDTO.train_date="+date+"&leftTicketDTO.from_station="+from_station+"&leftTicketDTO.to_station="+to_station+"&purpose_codes=ADULT"#print(url) 已经检查过生成的URL是正确的#request请求获取主页r = requests.get(url,headers=headers)r.raise_for_status()  #如果发送了一个错误的请求,会抛出异常r.encoding = r.apparent_encodingshowTicket(r.text)

用户输入时间、起始站点、目的站点,然后通过get来请求,然后我们对返回的网页信息进行解析。我们现将上面代码的r.text进行打印,看看我们请求之后,返回了什么样的信息,然后决定我们应该如何解析

运行结果

这样看着不方便,我们粘贴到记事本中,进行详细的分析:

请求返回的结果信息

可以与12306显示的信息进行对比,K829是车次,CDW与BJQ是出发地和目的地,10:10是出发时间,06:13是到达时间,44:21是历时时间,20190123为查询的日期,剩下的就是一系列票的各种信息。

下面就是对这些返回的信息进行解析,其实这也是python爬虫的关键,就是解析!!!

我们先把信息转化为json格式,可以看到都是用“|”隔开的,那么我们就用split函数分割出来,下面是主要功能代码:

'''
想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!
'''
def showTicket(html):html = json.loads(html)table = PrettyTable([" 车次 ","出发车站","到达车站","出发时间","到达时间"," 历时 ","商务座"," 一等座","二等座","高级软卧","软卧","动卧","硬卧","软座","硬座","无座","其他","备注"])for i in html['data']['result']:name = ["station_train_code","from_station_name","to_station_name","start_time","arrive_time","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"]data = {"station_train_code": '',"from_station_name": '',"to_station_name": '',"start_time": '',"arrive_time": '',"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]       #高级软卧信息在21号位置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()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(chezhan_names[data["from_station_name"]])tmp.append(s)elif y == "to_station_name":s = color.red(chezhan_names[data["to_station_name"]])tmp.append(s)elif y == "start_time":s = color.green(data["start_time"])tmp.append(s)elif y == "arrive_time":s = 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)

那么我们程序就成功啦!!!

运行结果

但是在编译器里面Prettytable的格子没有对齐,不要担心,我们到终端运行一下脚本,就可以看到很好看的输出啦:

终端运行结果

完成!!!下面是完整代码

'''
想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!
'''
# -*- coding: utf-8 -*-
import re,requests,datetime,time,json
from prettytable import PrettyTable
from colorama import init,Fore
from stationinfo import chezhan_code,chezhan_names
init(autoreset=False)
class Colored(object):def yeah(self,s):return Fore.LIGHTCYAN_EX + s + Fore.RESETdef 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","to_station_name","start_time","arrive_time","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"]data = {"station_train_code": '',"from_station_name": '',"to_station_name": '',"start_time": '',"arrive_time": '',"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]       #高级软卧信息在21号位置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()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(chezhan_names[data["from_station_name"]])tmp.append(s)elif y == "to_station_name":s = color.yeah(chezhan_names[data["to_station_name"]])tmp.append(s)elif y == "start_time":s = color.green(data["start_time"])tmp.append(s)elif y == "arrive_time":s = color.yeah(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     = input("请输入时间:\n")from_station = chezhan_code[input("请输入起始站点:\n")]to_station  = chezhan_code[input("请输入目的站点:\n")]url     = "https://kyfw.12306.cn/otn/leftTicket/queryZ?"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"}
url=url+"leftTicketDTO.train_date="+date+"&leftTicketDTO.from_station="+from_station+"&leftTicketDTO.to_station="+to_station+"&purpose_codes=ADULT"#print(url) 已经检查过生成的URL是正确的#request请求获取主页r = requests.get(url,headers=headers)r.raise_for_status()  #如果发送了一个错误的请求,会抛出异常r.encoding = r.apparent_encodingshowTicket(r.text)#print(r.text)
main()

stationinfo.py

import re,requests
url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8971"
response = requests.get(url,verify=False)
#将车站的名字和编码进行提取
chezhan = re.findall(r'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)
chezhan_code = dict(chezhan)
chezhan_names = dict(zip(chezhan_code.values(),chezhan_code.keys()))
#print(chezhan_names)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值

Python爬虫实战之12306抢票开源相关推荐

  1. Python爬虫实战之12306抢票

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

  2. python 12306抢票_Python爬虫实战:12306抢票开源!

    今天就和大家一起来讨论一下python实现12306余票查询(pycharm+python3.7),一起来感受一下python爬虫的简单实践 我们说先在浏览器中打开开发者工具(F12),尝试一次余票的 ...

  3. 爬虫实战篇---12306抢票爬虫

    12306抢票爬虫 先直接上一下效果图吧: 图片上信息是抢票成功后的界面 1.技术路线 selenium + chromedriver 2.思路分析 (1).模拟浏览器登录抢票界面,手动进行登录 (2 ...

  4. python爬虫抢火车票_如何用python写一个简单的12306抢票软件|python 爬火车票 教程...

    python 如果抓取验证码图片 类似12306的登录验证码图片 这个以前做次.最大的麻烦是码的识别算法的识别率太低.12306那种网站登陆错3次就限制你20分钟.所以除非你有33%以上的识别率否则不 ...

  5. python实例100例百度文库-18个Python爬虫实战案例(已开源)

    目录 爬虫小工具 文件下载小助手 爬虫实战 笔趣看小说下载 VIP视频下载 百度文库文章下载_rev1 百度文库文章下载_rev2 <帅啊>网帅哥图片下载 构建代理IP池 <火影忍者 ...

  6. 干货 | 18个Python爬虫实战案例(已开源)

    目录 爬虫小工具 文件下载小助手 爬虫实战 笔趣看小说下载 VIP视频下载 百度文库文章下载_rev1 百度文库文章下载_rev2 <帅啊>网帅哥图片下载 构建代理IP池 <火影忍者 ...

  7. 18个Python爬虫实战案例(已开源)

    目录 爬虫小工具 文件下载小助手 爬虫实战 笔趣看小说下载 VIP视频下载 百度文库文章下载_rev1 百度文库文章下载_rev2 <帅啊>网帅哥图片下载 构建代理IP池 <火影忍者 ...

  8. 12306 抢票 python + selenium + chrome (二) 基础准备的软件和材料

    我使用的 vmware 14 + ubuntu 16  +  PyCharm  开发环境 12306抢票 python+selenium+chrome 实现一 12306抢票 python+selen ...

  9. 【python自动化测试】京东|淘宝|秒杀12306抢票程序揭秘!一起薅羊毛吧【含源码】

    相信老铁们应该也看过很多这样的视频或者帖子:python自动秒杀的程序,京东,淘宝,大麦网抢票,秒杀抢购抢茅台,12306抢票,还有python薅羊毛的,感觉好像需求挺大的,很多人感兴趣.我也看了一些 ...

最新文章

  1. 威纶通触摸屏与mysql_威纶通 与 信捷XC\XD系列PLC 通讯
  2. BIO-NIO-AIO
  3. Twitter的分布式自增ID算法snowflake (Java版)
  4. Apache Camel简化SOA实施进程
  5. python将ros下bag文件的所有topic解析为csv格式
  6. python实践心得体会_“Python自然语言实践”——总结(一),实战
  7. 文件操作(二) 其他总结
  8. 推荐40个优秀的免费CSS工具
  9. IPC生产者与消费者模型加线程
  10. Pannellum:实例之为全景图添加标题和作者
  11. module.exports,exports,export和export default,import与require区别与联系
  12. 你想成为什么级别的程序员?
  13. matplotlib.pyplot 标记出曲线上最大点和最小点的位置
  14. 20%的美国Z世代每天刷TikTok超过5小时;多特瑞中国首家旗舰店落户上海 | 美通社头条...
  15. uvc摄像头代码解析5
  16. 【第59篇】MetaFormer实际上是你所需要的视觉
  17. Neil Young:谈游戏ARPDAU及榜单排名意义
  18. (二)GL 简单绘制
  19. 微信查询所有关注该公众号的用户
  20. 即时通讯(四)---初始化融云

热门文章

  1. Android Canvas绘制丘比特之箭
  2. 用CSS实现阴阳八卦图等图形
  3. MVC中集成Hangfire定时任务
  4. 多张图片怎么同时修改dpi?教你一键批量修改图片dpi
  5. oracle sql中( ),Oracle SQL中的函数
  6. 孙悟空这个农村人(搞笑)
  7. 计算机利用公式计算实发工资怎么弄,如何在excel 表中 添加税收计算程序?excle中计算税收的公式...
  8. 华东院进入华为智慧战略 其他院怎么办
  9. 2019小程序发展趋势
  10. 在Centos8上部署Django环境(Nginx+mysql+uwsgi)