Python爬虫之爬取车票信息

Python爬虫之爬取所有火车站的站台信息

前面我写过一篇关于火车站站台的查询,这篇基于站台的查询写火车车票余额信息查询……

一、信息获取:

获取请求地址: 

  • 在浏览器菜单中找到Web开发者模式,打开网络监视器(Ctrl+Shift+E),或者F12(Fn+F12)打开网络监视器

  • 在网络监视器中选择XHR请求,然后刷新车票查询页面 

 

可以看到车票查询请求地址:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2019-06-14&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=XAY&purpose_codes=ADULT

获取车票信息格式: 

  • 选择网络监视器中的响应 

 我将此处信息选取一段复制下来

 可以看出这里有每趟车次的票务信息内容,可以用每一个“|”进行分割

  • 用“\n”替换“|” 

为了方便观察信息所在位置,我用“\n”替换了“|”,并设置显示行号

 

每一个行号对应所需要的信息

 经过我的尝试,我发现所需信息要在行号信息基础上减1

        checi=ilist[3]                                  #车次
        chufa=stations[ilist[6]]["cn"]           #出发站
        daoda=stations[ilist[7]]["cn"]          #到达站
        ftime=ilist[8]                                   #出发时间
        dtime=ilist[9]                                  #到达时间
        ydeng=ilist[31]                               #一等座
        edeng=ilist[30]                               #二等座
        ywo=ilist[28]                                   #硬卧
        rwo=ilist[23]                                    #软卧
        yzuo=ilist[29]                                  #硬座
        wzuo=ilist[26]                                  #软座

二、爬取代码:

import re
import json
import shelve
import requests
import datetime
import prettytable as pt
from colorama import Fore,init

init(autoreset = False)

#获取全部车站信息    
with shelve.open("db") as db:#shelve序列化
    stations={}
    if not stations:
        url="https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9102"
        txt=requests.get(url).text   
        inf=txt[:-2].split("@")[1:]
        for record in inf:
            rlist=record.split("|")
            stations[(rlist[2])]={"cn":rlist[1],"id":rlist[2],"qp":rlist[3],"jp":rlist[4]}
        db["stations"]=stations

#车站信息
def getcode(t):
    while 1:
        s1=input("%s站:"%t)
        r1=[]
        for id,station in stations.items():
            if s1 in station.values():
                r1.append((id,station))
        if r1:
            break
        print("没有这个车站!")
        print("请重新输入!")
    if len(r1)==1:
        sid=r1[0][0]
	
    else:
        #print(r1)
        print("你输入的条件比较模糊,请在以下站中进行选择!")
        for i in range(len(r1)):
            print(i+1,r1[i][1]["cn"])#i代表所在元组,1代表元组后1位所对应的具体选项
        sel=int(input("你的选择:"))-1
        sid=r1[sel][0]
	    
    return sid
fromid=getcode("出发")
toid=getcode("到达")
  
#日期
def date():
    while 1:
        from_date=input("请输入出发日期(输入格式2019-01-01):")
        now=datetime.date.today()
        last=now+datetime.timedelta(days=14)
        tra_date=datetime.date(int(from_date[:4]),int(from_date[5:7]),int(from_date[8:]))
        
        if tra_date>=now and tra_date<=last:
            return tra_date
            break
        else:
            print("输入错误,请输入未来15内天的日期进行查询!")
            print("请重新输入!")
from_date=date()
tianshu=input("请输入要查询的天数(15天内):").strip()
for i in range(int(tianshu)):
    train_date=from_date+datetime.timedelta(days=i)
    qurl="https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT".format(from_date,fromid,toid)
    
    json_result=requests.get(qurl).json()['data']['result']
    #print(qurl)

    print("您输入的查询条件是:出发站%s,到达站%s"%(stations[fromid]["cn"],stations[toid]["cn"]))
    #ainf=requests.get(qurl).json()["data"]["result"]  
    #车次信息  
    #print(ainf[0],len(ainf))
    
    result=[]
    for i in json_result:
        ilist=i.split("|")
        checi=ilist[3]
        chufa=stations[ilist[6]]["cn"]
        daoda=stations[ilist[7]]["cn"]
        ftime=ilist[8]
        dtime=ilist[9]
        ydeng=ilist[31]
        edeng=ilist[30]
        ywo=ilist[28]
        rwo=ilist[23]
        yzuo=ilist[29]
        wzuo=ilist[26]
        beizhu=ilist[1]
        result.append((checi,chufa,daoda,ftime,dtime,ydeng,edeng,rwo,ywo,yzuo,wzuo,beizhu))
    
    #print(result)
    
    #车次信息制表打印   
    def f1(alist):     
        tb = pt.PrettyTable()
        tb.junction_char = "*"
        tb.field_names=["车次","出发站","到达站","出发时间","到达时间","一等座","二等座","软卧","硬卧","硬座","无座","备注"]
        for i in alist:
            tb.add_row(["%-5s"%i[0],Fore.LIGHTRED_EX+"%-5s"%i[1]+Fore.RESET,"%-5s"%i[2],Fore.LIGHTRED_EX+i[3]+Fore.RESET,i[4],i[5],i[6],i[7],i[8],i[9],i[10],i[11]])
        print(tb)

    #列车分车型    
    gt=[]
    lc=[]
    for i in result:
        if i[6]:
            gt.append(i)
        else:
            lc.append(i)

    #循环打印       
    while 1:
        cxing=input("请选择车型:1.高铁 2.列车 3.返回全部页面 4.退出\n")
        if cxing=="1":
            f1(gt)
        elif cxing=="2":     
            f1(lc)
        elif cxing=="3":
            f1(result)  
        else :
            break

三、执行结果: 

出发站:西安
到达站:北京
请输入出发日期(输入格式2019-01-01):2019-06-14
请输入要查询的天数(15天内):1
您输入的查询条件是:出发站西安,到达站北京

 

 

 

 

  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值