快过年了,Python实现12306查票以及自动购票....

news2024/9/25 9:32:01

嗨害大家好鸭!我是小熊猫~

明天就是2023年啦~

还有谁像我小熊猫一样没有回家的?

这次康康能不能12306抢票回家!!!

在这里插入图片描述

Python实现12306查票以及自动购票

[代码来源]: 青灯教育-自游老师

[环境使用]:

  • Python 3.8
  • Pycharm

谷歌浏览器

谷歌驱动

[模块使用]:

requests   ---> pip install requests  数据请求模块
prettytable ---> pip install prettytable 打印好看一些
selenium  ---> pip install selenium==3.141.0  模拟人的行为去操作浏览器
json ---> 内置模块 不需要安装

所用素材:点击此处跳转文末名片获取

city.json文件

win + R 输入cmd 输入安装命令 pip install 模块名 (如果你觉得安装速度比较慢, 你可以切换国内镜像源)


模块安装问题:

- 如何安装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的选项 点击确定, 重启即可生效

一点小TIPS:

12306 每天只能退票三次

查票
购票

建议谷歌或者火狐…


爬虫采集数据思路:

一. 分析数据来源
车票信息:来源哪个数据包 <车票信息请求那个网站url地址可以得到>
开发者工具:F12

二. 代码实现步骤:
1. 发送请求, 对于刚刚分析得到url地址发送请求
在这里插入图片描述

2. 获取数据, 获取服务器返回响应数据, response
3. 解析数据, 提取我们想要车次信息

python就业可以找哪方面的工作?

需求是什么样子, 需要学习什么内容?

大数据专业/数据分析师 —> 除非你的公司里有爬虫工程师或者有后台数据
核心编程 + 高级开发 + 数据分析 + 爬虫
爬虫工程师:
核心编程 + 高级开发 + 爬虫
开发工程师:
核心编程 + 高级开发 + 全栈开发

在这里插入图片描述


导入模块

# 导入数据请求模块  ---> 第三方模块 需要 在cmd里面进行 pip install requests
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’,

# 确定请求网址 ---> 如果对于长链接, 我们是可以分段写 ? 后面都是属于请求参数

在这里插入图片描述

请求参数

data = {
    'leftTicketDTO.train_date': date,
    'leftTicketDTO.from_station': from_station,
    'leftTicketDTO.to_station': to_station,
    'purpose_codes': 'ADULT',
}

请求头

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 = 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)

👇问题解答 · 源码获取 · 技术交流 · 抱团学习请联系👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/131545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

构造函数和原型

1、概述 在典型的 OOP 的语言中&#xff08;如 Java&#xff09;&#xff0c;都存在类的概念&#xff0c;类就是对象的模板&#xff0c;对象就是类的实例&#xff0c;但在 ES6之前&#xff0c; JS 中并没用引入类的概念。ES6&#xff0c; 全称 ECMAScript 6.0 &#xff0c;201…

计算机组成原理实验——三、存储器实验

一、实验目的 1.掌握存储器的工作原理和接口。 2.掌握存储器的实现方法和初始化方法。 3.掌握RISC-V中存储器的存取方式。 二、实验内容 1.利用vivado IP核创建6432的ROM&#xff0c;并在 系数文件中设置数据为123489ab&#xff1b; 2.利用vivado IP核创建6432的RAM&#xf…

猿如意---初学者的一盏明灯---程序员的宝藏app

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​ &#x1f4e3;系列专栏&#xff1a;我的CSDN活动之旅 &#x1f4ac;总结&#xff1a;希望你看完…

Rabbit客户端操作不同交换机[包含延迟类型]

文章目录一&#xff1a;direct-直投交换机0.0: 说明 --- 只有队列和交换机绑定&#xff0c;且routing key路由键一致才会收到消息1.1: 先后创建两个队列1.2: 队列绑定Direct交换机&#xff0c;和routing key1.3: 未指明路由键&#xff1a;1.4: 指明路由键1.5: 两个队列绑定一个…

Python中基本输入和输出

文章目录前言一、使用input()函数输入二、使用print()函数输出前言 从我们接触第一个Python程序开始&#xff0c;就一直在使用 print() 函数向屏幕上输出一些字符&#xff0c;如下图代码所示&#xff1a; print() 函数就是Python的基本输出函数。那既然有输出&#xff0c;肯定…

[牛客复盘] 牛客2022跨年场 20221212

[牛客复盘] 牛客2022跨年场 20221212 一、本周周赛总结二、 A 猜群名1. 题目描述2. 思路分析3. 代码实现三、B 分赃1. 题目描述2. 思路分析3. 代码实现四、C 翻卡牌1. 题目描述2. 思路分析3. 代码实现五、D ygg的分数运算1. 题目描述2. 思路分析3. 代码实现六、E 摇色子1. 题目…

多线程生产者消费者——分别使用条件变量、信号量实现

生产者消费者 概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯&#xff0c;而通过阻塞队列来进行通讯&#xff0c;所以生产者生产完数据之后不用等待消费者处理&#xff0c;直接扔给阻塞队列&#xff0c;消费者不…

超好用!win10安装Eiseg标注软件及使用(CPU版本)

写在前面的话 众所周知&#xff0c;标注分割掩膜的软件一般使用labelme&#xff0c;但是一个一个点太麻烦了&#xff0c;工作量太大&#xff0c;&#xff0c;之前&#xff0c;我的思路就是先标少量的数据然后训练个初始模型&#xff0c;再用初始模型对剩下的图像预测掩膜&…

【闲聊杂谈】深入理解Spring Security设计原理

1、什么是Spring Security 顾名思义&#xff0c;Security的意思是安全&#xff0c;本质上就是一个很纯粹的权限管理框架&#xff0c;提供认证和授权两大核心功能。在目前主流的Spring生态中的项目&#xff0c;说到安全框架&#xff0c;基本上SpringSecurity是首选。当然&#…

代码随想录算法训练营第四天|24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点、160.链表相交、142.环形链表II

24. 两两交换链表中的节点 力扣题目链接(opens new window) 解析&#xff1a; 基础题&#xff0c;主要是要把握边界条件&#xff1a;由题可得&#xff0c;交换的节点两两一组&#xff0c;每交换完成一对&#xff0c;问题规模减2&#xff0c;也就是只剩一个或不剩节点时交换便结…

ArcGIS基础实验操作100例--实验28地形图配准

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验28 地形图配准 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&#x…

python中类的使用详解

目录 一.类的定义和使用方法 成员变量和成员方法 成员方法的定义语法和self关键字 小结 二.类和对象 小结 三.属性&#xff08;成员变量&#xff09;的赋值 构造方法&#xff1a;_ _init_ _() 小结 一.类的定义和使用方法 可以使用类去封装属性&#xff0c;并基于类创建…

一文弄懂Pytorch的DataLoader,Dataset,Sampler之间的关系

很多文章都是从DatasetDatasetDataset等对象自下网上进行介绍的&#xff0c;但是对于初学者而言&#xff0c;其实这并不好理解&#xff0c;因为有时候&#xff0c;会不自觉的陷入到一些细枝末节中去&#xff0c;而不能把握重点&#xff0c;所以本文将自上而下的对PytorchPytorc…

HCIP第四天

HCIP实验配置一&#xff0c;实验要求二&#xff0c;172.16.0.0/16地址的划分三&#xff0c;搭建拓扑图四&#xff0c;配置IP地址和环回地址五&#xff0c;宣告并配置缺省路由下放&#xff0c;使用NAT技术六&#xff0c;R5中心站点配置隧道和静态IP七&#xff0c;R6分支站点的配…

canvas在小程序里写小游戏

最近接了个小需求需要写个小游戏&#xff0c;由简单的帧动画加上碰撞相关的处理&#xff0c;组成。具体页面信息如下图 具体的游戏步骤&#xff0c;是通过长按按钮蓄力&#xff0c;松开时卡通人物跳起&#xff0c;卡通人物跳起碰撞到上面的元宝等元素的得分&#xff0c;这里我们…

笔试题之编写SQL分析门店销售情况

销售员、客户、产品 文章目录前言一、SQL题目二、解答方法&#xff08;一&#xff09;建表插入测试数据&#xff08;二&#xff09;第一题解答&#xff08;三&#xff09;第二题解答&#xff08;四&#xff09;第三题解答总结前言 分享本人遇到的笔试真题与解法&#xff0c;并…

MATLAB算法实战应用案例精讲-【人工智能】语义分割(附实战应用案例及代码)

前言 语义分割是一种典型的计算机视觉问题,其涉及将一些原始数据(例如,平面图像)作为输入并将它们转换为具有突出显示的感兴趣区域的掩模。许多人使用术语全像素语义分割(full-pixel semantic segmentation),其中图像中的每个像素根据其所属的感兴趣对象被分配类别ID。…

[ XSS-labs通关宝典 ] xss-labs 通关宝典之 less1 - less5

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

前端常见问题汇总(十)

一、HTTP1.0和HTTP2.0的区别 http1.0&#xff1a;每次请求都需要重新建立tcp连接&#xff0c;请求完后立即断开与服务器连接&#xff0c;这很大程度造成了性能上的缺陷&#xff0c;http1.0被抱怨最多的就是连接无法复用。 http1.1&#xff1a;引入了长连接&#xff08;keep-al…

麒麟系统虚拟机安装教程

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 1.首先得安装VM Ware软件。 2.打开VM Ware&#xff0c;点击“文件”->“新建虚拟机”。 3.进入新建虚拟机向导&#xff0c;点击下一步。如下图&…