2024-06-25
Python
00

目录

技术准备
代码实现过程
实现步骤
1. 准备工作
2. 用户输入信息
3. 发送查询请求
4. 数据展示
完整代码
获取12306城市名称的映射数据

技术准备

  1. Python基础知识

    • 熟悉Python语言基础和流程控制。
    • 掌握使用第三方库(如Requests和PrettyTable)进行网络请求和数据展示。
  2. 12306城市编码数据

    • 准备城市名称到对应站点代码的映射数据,通常保存在JSON文件中。 获取城市名称映射的数据代码放到文章底部了
  3. 数据展示

    • 使用PrettyTable库,将查询结果以表格形式清晰展示。

代码实现过程

  • 发送请求 :模拟浏览器对url地址发送请求。
  • 获取数据 :获取服务器返回响应数据。
  • 解析数据 :提取我们想要的信息。
  • 查询功能 :根据输入不同的城市,以及时间点,获取不同的车次。

实现步骤

1. 准备工作

首先,我们需要准备城市名称到对应站点代码的映射数据。这些数据通常从12306的官方接口或者其他公开资源获取,并存储在一个JSON文件中。

python
import json # 读取城市数据文件 f = open('city.json', encoding='utf-8') city_data = json.loads(f.read())

2. 用户输入信息

接下来,用户将输入出发城市、到达城市和出发日期等信息,作为查询条件。

python
from_city = input('请输入你要出发的城市:') to_city = input('请输入你要到达的城市:') date = input('请输入出发的时间(格式:yyyy-mm-dd):')

3. 发送查询请求

构建12306查询火车票信息的URL,并发送GET请求获取数据。

python
import requests # 构造查询URL url = f'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={date}&leftTicketDTO.from_station={city_data[from_city]}&leftTicketDTO.to_station={city_data[to_city]}&purpose_codes=ADULT' # 模拟伪装 ---> headers 请求头 headers = { 'Cookie': 'JSESSIONID=1C2EB5610C84DAEB06A3915467B3FECC', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' } # 发送请求 request = requests.get(url=url, headers=headers) # 检查请求是否成功 if request.status_code == 200: # 响应数据 data = request.json() if data['status']: # 判断查询是否成功 tickets = data['data']['result'] else: print('查询失败,请检查输入的城市和日期。') else: print('请求失败,请稍后重试。')

4. 数据展示

使用PrettyTable库将查询到的火车票信息以表格形式显示。

python
# 创建表格对象 tb = pt.PrettyTable() # 输出的时候的表头 tb.field_names = [ '序号', '车次', '出发时间', '到达时间', '耗时', '特等座', '一等座', '二等座', '软卧', '硬卧', '硬座', '无座' ] # 添加一个序号 page = 0 # for循环遍历,把列表的元素一个一个提取出来 for i in request.json()['data']['result']: # 先用 split 分割,再用列表取值 index = i.split('|') num = index[3] # 车次 start_time = index[8] # 出发时间 end_time = index[9] # 到达时间 use_time = index[10] # 耗时 topGrade = index[32] # 特等座 first_class = index[31] # 一等座 second_class = index[30] # 二等座 soft_sleeper = index[23] # 软卧 hard_sleeper = index[28] # 硬卧 hard_seat = index[29] # 硬座 no_seat = index[26] # 无座 # 添加每行输出的内容 tb.add_row( [page, num, start_time, end_time, use_time, topGrade, first_class, second_class, soft_sleeper, hard_sleeper, hard_seat, no_seat]) page += 1 print(tb)

完整代码

python
# 导入数据请求模块 import requests # 导入 prettytable,可以以表格形式显示数据 import prettytable as pt import json # 读取文件,城市字母文件 f = open('city.json', encoding='utf-8') city_data = json.loads(f.read()) # 输入内容 from_city = input('请输入你要出发的城市:') to_city = input('请输入你要到达的城市:') date = input('请输入出发的时间(格式:yyyy-mm-dd):') '''发送请求:模拟浏览器对URL地址发送请求''' # 确定请求连接 url = f'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={date}&leftTicketDTO.from_station={city_data[from_city]}&leftTicketDTO.to_station={city_data[to_city]}&purpose_codes=ADULT' # 模拟伪装 ---> headers 请求头 headers = { 'Cookie': 'JSESSIONID=1C2EB5610C84DAEB06A3915467B3FECC', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' } # 发送请求 request = requests.get(url=url, headers=headers) # 检查请求是否成功 if request.status_code == 200: # 响应数据 data = request.json() if data['status']: # 判断查询是否成功 tickets = data['data']['result'] else: print('查询失败,请检查输入的城市和日期。') else: print('请求失败,请稍后重试。') '''解析数据:提取我们想要的信息''' # 创建表格对象 tb = pt.PrettyTable() # 输出的时候的表头 tb.field_names = [ '序号', '车次', '出发时间', '到达时间', '耗时', '特等座', '一等座', '二等座', '软卧', '硬卧', '硬座', '无座' ] # 添加一个序号 page = 0 # for循环遍历,把列表的元素一个一个提取出来 for i in request.json()['data']['result']: # 先用 split 分割,再用列表取值 index = i.split('|') num = index[3] # 车次 start_time = index[8] # 出发时间 end_time = index[9] # 到达时间 use_time = index[10] # 耗时 topGrade = index[32] # 特等座 first_class = index[31] # 一等座 second_class = index[30] # 二等座 soft_sleeper = index[23] # 软卧 hard_sleeper = index[28] # 硬卧 hard_seat = index[29] # 硬座 no_seat = index[26] # 无座 # 添加每行输出的内容 tb.add_row( [page, num, start_time, end_time, use_time, topGrade, first_class, second_class, soft_sleeper, hard_sleeper, hard_seat, no_seat]) page += 1 ''' # 获取列表的索引数值,方便取值 a = 0 for j in index: print(j, a, sep='--') a += 1 ''' print(tb)

获取12306城市名称的映射数据

python
import requests import json import re url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js" r = requests.get(url=url).text city = re.findall('@[a-z]+\|([\u4e00-\u9fa5]+)\|([a-zA-Z]+)', r) result = {} for item in city: result[item[0]] = item[1] json_string = json.dumps(result, ensure_ascii=False) print(json_string)

本文作者:柯南

本文链接:

版权声明:©2024 柯南 All rights reserved.