脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - 基于Python实现火车票抢票软件

基于Python实现火车票抢票软件

2022-07-24 12:26嗨!栗子同学 Python

每年的节假日一到,大家头疼的总时同一个问题:你买到回家的票了吗?尤其是大型的节日:国庆、春节等。本文将利用Python编写一个火车票抢票软件,感兴趣的可以了解一下

导语

每年的节假日一到,大家头疼的总时同一个问题:你买到回家的票了吗?

尤其是大型的节日:”比如国庆、春节......“

数以亿计的人口迁移,让车票成了一年里最难买到的那张票。

跨站买票、买短途票上车补票、准点捡漏等已是老生常谈的技巧。随着互联网的发展,抢票软件成为购票热门渠道。抢票软件的到底靠谱嘛?能抢到票嘛?

近日,小编给大家就正式编写一款Python实现查票以及自动购票抢票的小程序给大家,希望大家如愿!

环境准备

1)运行环境:Python 3 、Pycharm、谷歌浏览器、谷歌驱动 。

2)模块准备: 

requests ---> pip install requests (数据请求模块)

prettytable ---> pip install prettytable (打印好看一些 )

selenium ---> pip install selenium==3.141.0 (模拟人的行为去操作浏览器)

json ---> 内置模块 不需要安装

PS小编有话说:(新手看过来)

模块安装问题:

如果安装python第三方模块:

1. win + R 输入 cmd 点击确定, 输入安装命令 pip install 模块名 (pip install requests) 回车

2. 在pycharm中点击Terminal(终端) 输入安装命令

安装失败原因:

失败一: pip 不是内部命令

解决方法: 设置环境变量

失败二: 出现大量报红 (read time out)

解决方法: 因为是网络链接超时,  需要切换镜像源

  • 清华:https://pypi.tuna.tsinghua.edu.cn/simple
  • 阿里云:https://mirrors.aliyun.com/pypi/simple/
  • 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
  • 华中理工大学:https://pypi.hustunique.com/
  • 山东理工大学:https://pypi.sdutlinux.org/
  • 豆瓣:https://pypi.douban.com/simple/

例如:pip3 install -i https://pypi.doubanio.com/simple/ 模块名

失败三: cmd里面显示已经安装过了, 或者安装成功了, 但是在pycharm里面还是无法导入

解决方法: 可能安装了多个python版本 (anaconda 或者 python 安装一个即可) 卸载一个就好

或者你pycharm里面python解释器没有设置好。

如何配置pycharm里面的python解释器?

1. 选择file(文件) >>> setting(设置) >>> Project(项目) >>> python interpreter(python解释器)

2. 点击齿轮, 选择add

3. 添加python安装路径

pycharm如何安装插件?

1. 选择file(文件) >>> setting(设置) >>> Plugins(插件)

2. 点击 Marketplace  输入想要安装的插件名字 比如:翻译插件 输入 translation / 汉化插件 输入 Chinese

3. 选择相应的插件点击 install(安装) 即可

4. 安装成功之后 是会弹出 重启pycharm的选项 点击确定, 重启即可生效

项目思路

12306 每天只能退票三次

查票

购票

建议谷歌或者火狐....

爬虫采集数据思路:

一. 分析数据来源

车票信息, 来源那个数据包 <车票信息请求那个网站url地址可以得到>

开发者工具  1  2

二. 代码实现步骤:

1. 发送请求, 对于刚刚分析得到url地址发送请求

https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2022-07-02&leftTicketDTO.from_station=CSQ&leftTicketDTO.to_station=SHH&purpose_codes=ADULT

2. 获取数据, 获取服务器返回响应数据, response

3. 解析数据, 提取我们想要车次信息

代码展示

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import requests
# 导入漂亮的表格输出模块 ---> 第三方模块 需要 在cmd里面进行 pip install prettytable
import prettytable as pt
# 导入json
import json
# 导入selenium模块 ---> 第三方模块 需要 在cmd里面进行 pip install selenium==3.141.0
from selenium import webdriver
# 导入账号密码
from password import account, Password
# 导入selenium控制键盘
from selenium.webdriver.common.keys import Keys
# 创建浏览器 <打开浏览器>  浏览器驱动放在python安装目录里面就不需要添加路径
 
 
def get_ticket(num, from_station, to_station, date_key):
    driver = webdriver.Chrome()
    # 输入网址
    driver.get('https://kyfw.12306.cn/otn/resources/login.html')
    # 通过元素定位, 找到账号输入框 输入账号 send_keys() 发送或者输入内容
    driver.find_element_by_css_selector('#J-userName').send_keys(account)  # 通过 css 选择器查找元素
    # 通过元素定位, 找到密码输入框 输入密码 send_keys() 发送或者输入内容
    driver.find_element_by_css_selector('#J-password').send_keys(Password)  # 通过 css 选择器查找元素
    # 通过元素定位, 找到登陆按钮, 点击登陆
    driver.find_element_by_css_selector('#J-login').click()
    # 隐式等待
    driver.implicitly_wait(10)
    # 通过元素定位, 点击弹窗确定按钮 .表示class # 表示ID
    driver.find_element_by_css_selector('.modal-ft .btn').click()
    # 通过元素定位, 点击车票预定
    driver.find_element_by_css_selector('#link_for_ticket').click()
    # 通过元素定位, 点击键盘回车
    driver.find_element_by_css_selector('#fromStationText').send_keys(Keys.ENTER)
    # 通过元素定位, 清空输入框内容
    driver.find_element_by_css_selector('#fromStationText').clear()
    # 通过元素定位, 点击一下输入框
    driver.find_element_by_css_selector('#fromStationText').click()
    # 通过元素定位, 输入出发城市
    driver.find_element_by_css_selector('#fromStationText').send_keys(from_station)
    # 通过元素定位, 点击键盘回车
    driver.find_element_by_css_selector('#fromStationText').send_keys(Keys.ENTER)
    driver.find_element_by_css_selector('#toStationText').clear()
    driver.find_element_by_css_selector('#toStationText').click()
    driver.find_element_by_css_selector('#toStationText').send_keys(to_station)
    driver.find_element_by_css_selector('#toStationText').send_keys(Keys.ENTER)
    date = driver.find_element_by_css_selector('.inp-w #train_date')
    date.clear()
    date.send_keys(date_key)
    # 通过元素定位, 点击查询按钮
    driver.find_element_by_css_selector('#query_ticket').click()
    if num == 1:
        driver.find_element_by_css_selector(f'#queryLeftTable tr:nth-child({num}) a.btn72').click()
    elif num != 1:
        driver.find_element_by_css_selector(f'#queryLeftTable tr:nth-child({num + 1}) a.btn72').click()
        # #normalPassenger_0
    driver.find_element_by_css_selector('#normalPassenger_1').click()
 
    driver.find_element_by_css_selector('#submitOrder_id').click()
    driver.find_element_by_css_selector('#qr_submit_id').click()
    driver.find_element_by_css_selector('#qr_submit_id').click()
 
 
f = open('city.json', encoding='utf-8')
text = f.read()  # 读取文件
json_data = json.loads(text)
from_city = input('请输入你要出发城市: ')
to_city = input('请输入你要到达城市: ')
date = input('请输入你要出发的时间: ')
from_station = json_data[from_city]
to_station = json_data[to_city]
 
"""
发送请求, 模拟浏览器对于url地址发送请求
    快捷批量替换方法:
        选中内容, ctrl + R 输入正则表达式命令点击全部替换即可
        (.*?): (.*)
        '$1': '$2',
"""
# 确定请求网址 ---> 如果对于长链接, 我们是可以分段写 ? 后面都是属于请求参数
url = 'https://kyfw.12306.cn/otn/leftTicket/query'
# 请求参数 ---> 字典数据类型, 构建成完整键值对, 键值对与键值对之间要用逗号隔开
data = {
    'leftTicketDTO.train_date': date,
    'leftTicketDTO.from_station': from_station,
    'leftTicketDTO.to_station': to_station,
    'purpose_codes': 'ADULT',
}
# 请求头 ---> 伪装模拟浏览器的, 把python代码伪装成浏览器发送请求
headers = {
    # User-Agent: 用户代理, 表示浏览器基本身份标识
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36',
}
# 发送请求 ---> 返回数据 <Response [200]> 响应对象 200状态码表示请求成功
response = requests.get(url=url, params=data, headers=headers)
 
# 获取数据 response.json() 获取响应对象json字典数据
# 解析数据 ---> 根据数据类型以及你想要获取数据内容, 选择最合适提取方式 根据冒号左边的内容, 提取冒号右边内容
result = response.json()['data']['result']
 
# 实例化对象
tb = pt.PrettyTable()
tb.field_names = [
    '序号',
    '车次',
    '出发时间',
    '到达时间',
    '耗时',
    '特等座',
    '一等',
    '二等',
    '软卧',
    '硬卧',
    '硬座',
    '无座',
]
page = 0
lis = []
# for循环 就把列表里面元素一个一个提取出来
for index in result:
    # split() 字符串分割方法 --> 返回是列表
    content_list = index.split('|')
    #  根据列表索引位置提取内容
    num = content_list[3# 车次
    start_time = content_list[8# 出发时间
    end_time = content_list[9# 到达时间
    use_time = content_list[10# 耗时
    topGrade = content_list[25# 特等座
    if topGrade:
        pass
    else:
        topGrade = content_list[32]
    first_class = content_list[31# 一等
    second_class = content_list[30# 二等
    hard_sleeper = content_list[28# 硬卧
    hard_seat = content_list[29# 硬座
    no_seat = content_list[26# 无座
    soft_sleeper = content_list[23# 软卧
    dit = {
        '车次': num,
        '出发时间': start_time,
        '到达时间': end_time,
        '耗时': use_time,
        '特等座': topGrade,
        '一等': first_class,
        '二等': second_class,
        '软卧': soft_sleeper,
        '硬卧': hard_sleeper,
        '硬座': hard_seat,
        '无座': no_seat,
    }
    lis.append(dit)
    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
    # 更加方便直观查看 索引位置 ---> 列表可以通过索引位置取值
    # num = 0
    # for i in content_list:
    #     # i 列表里面元素, num 对应列表索引位置
    #     print(i, num)
    #     num += 1
    # break
print(tb)
 
 
num = input('请输入你想要购买车票序号: ')
 
get_ticket(num=int(num), from_station=from_city, to_station=to_city, date_key=date)

到此这篇关于基于Python实现火车票抢票软件的文章就介绍到这了,更多相关Python火车票抢票内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/xy258009/article/details/125955087

延伸 · 阅读

精彩推荐
  • Python学习Python爬虫前必掌握知识点

    学习Python爬虫前必掌握知识点

    这篇文章主要介绍了学习Python爬虫前,我们需要了解涉及爬虫的知识点,学习爬虫的知识点比较多,我们一起学习爬虫吧...

    互联网老辛10222021-10-06
  • Pythonpython3+selenium4实现切换窗口与iframe的方法

    python3+selenium4实现切换窗口与iframe的方法

    在自动化测试过程中,有时后会遇到元素定位方式没有问题,但是依旧抛出无法找到元素的异常的问题,有可能是由于当前焦点不在指定页面或iframe导致的...

    Tester_谜城4302021-11-14
  • Python海王小姐姐悄悄问我怎么在PC端登录多个微信

    海王小姐姐悄悄问我怎么在PC端登录多个微信

    这篇文章主要介绍了怎么在PC端登录多个微信号,众所周知pc端一般只能登陆一个微信号,可这年头谁还只有一个号,又不能同时用两台电脑,这篇文章带给你答...

    LexSaints6032021-12-23
  • PythonPython3.x对JSON的一些操作示例

    Python3.x对JSON的一些操作示例

    最近在学习python3,正巧遇到了一些json的操作,索性整理一下分享出来,下面这篇文章主要给大家介绍了关于Python3.x对JSON的一些操作,需要的朋友可以参考...

    RustFisher1842020-12-05
  • Python利用python程序生成word和PDF文档的方法

    利用python程序生成word和PDF文档的方法

    这篇文章主要给大家介绍了利用python程序生成word和PDF文档的方法,文中给出了详细的介绍和示例代码,相信对大家具有一定的参考价值,有需要的朋友们下...

    会心一击4352020-09-21
  • PythonOpenCV半小时掌握基本操作之腐蚀膨胀

    OpenCV半小时掌握基本操作之腐蚀膨胀

    这篇文章主要介绍了OpenCV基本操作之腐蚀膨胀,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    我是小白呀5492021-12-28
  • PythonPython操作mongodb数据库进行模糊查询操作示例

    Python操作mongodb数据库进行模糊查询操作示例

    这篇文章主要介绍了Python操作mongodb数据库进行模糊查询操作,结合实例形式分析了Python连接MongoDB数据库及使用正则表达式进行模糊查询的相关操作技巧,需要...

    shaomine9592021-03-03
  • Pythonpython使用response.read()接收json数据的实例

    python使用response.read()接收json数据的实例

    今天小编就为大家分享一篇python使用response.read()接收json数据的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    羽丶12572021-05-04