目录
一、效果展示
二、代码实现
import re
import requests
import pandas as pd
from pprint import pprint
from stations import stations
while(True):
from_station=input('请输入起始站:')
to_station=input('请输入目的地:')
train_date=input('请输入乘车日期(格式:2024-01-20):')
url='https://kyfw.12306.cn/otn/leftTicket/queryE?'
data={
'leftTicketDTO.train_date':train_date,
'leftTicketDTO.from_station':stations[from_station],
'leftTicketDTO.to_station':stations[to_station],
'purpose_codes':'ADULT',
}
header={
'Cookie':'_uab_collina=170522976484937999585538; JSESSIONID=1752FBD2805CA520347421618B8252D0; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; _jc_save_wfdc_flag=dc; _jc_save_toDate=2024-01-15; _jc_save_fromStation=%u4E0A%u6D77%2CSHH; _jc_save_toStation=%u957F%u6C99%2CCSQ; route=495c805987d0f5c8c84b14f60212447d; BIGipServerotn=4074176778.50210.0000; _jc_save_fromDate=2024-01-20',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
}
response=requests.get(url=url,params=data,headers=header)
response.encoding='utf-8'
result=response.json()['data']['result']
lis=[]
for index in result:
index_list=index.replace('有','yes').replace('无','no').split('|')
Num=index_list[3]
if 'G' in Num:
start_time = index_list[8]
end_time = index_list[9]
use_time = index_list[10]
top = index_list[32]
first = index_list[31]
second = index_list[30]
dit={
'Num': Num,
'start_time':start_time,
'end_time':end_time,
'use_time':use_time,
'top':top,
'first':first,
'second':second,
'rw': '-',
'yw': '-',
'yz': '-',
'wz': '-',
}
else:
start_time = index_list[8]
end_time = index_list[9]
use_time = index_list[10]
rw=index_list[23]
yw=index_list[28]
yz=index_list[29]
wz=index_list[26]
dit = {
'Num':Num,
'start_time': start_time,
'end_time': end_time,
'use_time': use_time,
'rw': rw,
'yw': yw,
'yz': yz,
'wz': wz,
'top': '-',
'first': '-',
'second': '-',
}
lis.append(dit)
content=pd.DataFrame(lis)
print(content)
q=input('是否继续查询(Y/N):')
if q=='Y' or q=='y':
continue
elif q=='N' or q=='n':
break
其中有一个stations文件,文件有点大,后面有讲到怎么获取。有需要可以在评论区留言,单独发。
三、步骤
1.我们先打开12306官网,随便输入出发地、到达地和出发日期,点击查询。
2.在查询界面检查,随便找一个时间点的网络信息,再点击响应。可以在result中看到车辆信息。也就是我们要找的信息。
3.在标头查看url,有几个参数,其中出发地(leftTicketDTO.from_station=SJP)和到达地(leftTicketDTO.to_station=CSQ)都是用的字母表达,所以需要新建一个py文件保存stations信息。
4.获取stations信息:进入12306首页,检查-网络-有个station_name_new的文件,我们可以访问这个文件的url地址,看到每个城市信息,再通过下面代码爬取。因为城市名是中文,不能直接爬取,需要用到unicode编码,其中u代表使用这个编码,\u4e00和\u9fa5正好对应中文的第一个字和最后一个字,最后通过pprint用字典的形式输出出来。
import re
import requests
from pprint import pprint
url="https://www.12306.cn/index/script/core/common/station_name_new_v10037.js"
response=requests.get(url)
r=response.text
#print(r)
station=re.findall(u'([\u4e00-\u9fa5]+)\\|([A-Z]+)',r)
pprint(dict(station))
5.再看主程序,得到url后,因为需要访问响应的数据,需要加上cookie,再通过json获取响应中的result.
6.获取result后,要从result中获取我们需要的信息,因为数据都是以'|'进行分割,用到split函数,分割一行数据后形成一个列表。这里replace可以先不看,后面有解释
7.发现列表中,火车名字都在列表的第4列,使用Num保存
8.因为高铁和快车的座位不一样,需要区分。区别在于高铁的名字含有G
9.再在列表中找到高铁的出发时间,结束时间,用时,商务座,一等座,二等座并保存,通过字典保存高铁数据。快车同理,最后结合保存。
10.把这些数据整合,用一个列表保存字典,最后通过pandas展示出来。因为展示出来‘有’,‘无’文字不对应,所以需要替换成英文。在分割成列表那里加入replace。