自动化抢票 12306

2024-09-08 01:12
文章标签 自动化 抢票 12306

本文主要是介绍自动化抢票 12306,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自动化抢票 12306

1. 明确需求

明确采集的网站以及数据内容

  • 网址: https://kyfw.12306.cn/otn/leftTicket/init
  • 数据: 车次相关信息
2. 抓包分析

通过浏览器开发者工具分析对应的数据位置

  • 打开开发者工具
    • F12 或鼠标右键点击检查
  • 刷新网页
    • 点击下一页/下滑网页页面/点击搜索/查询按钮
    • 让网页相关数据内容加载出来 (整个网站数据内容重新加载一遍)
  • 通过关键字搜索找到对应数据位置
    • 需要什么数据就搜什么

数据包地址: https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2024-09-06&leftTicketDTO.from_station=IZQ&leftTicketDTO.to_station=SNQ&purpose_codes=ADULT

3. 代码实现步骤
1. 发送请求

模拟浏览器对于 url 地址发送请求

  • 模拟浏览器

    • 可以直接复制,使用请求标头中参数内容
    • 去哪里找: 开发者工具 -> 网络 -> 点击对应数据包 -> 标头 -> 请求标头(参数)
    • 怎么写: 使用字典接受数据内容 (构建完整的键值对)
  • 请求网址

    • 通过抓包分析找到链接地址,直接复制即可
  • 发送请求

    • 使用第三方模块: requests
      • 安装 requests 模块
        • win+r 输入 cmd 点击确定,输入安装命令: pip install requests
      • 导入 requests 模块
      • 请求方法: 开发者工具 -> 网络 -> 点击对应数据包 -> 标头 -> 常规
      • GET 请求参数: 查询参数 (直接在链接中就有)
2. 获取数据

获取服务器返回响应数据

  • 12306 的请求参数并不是简单的中文字符,而是对应的三字编码,我们需要找到对应的编码
    • 对网页分析发现,在一个 js 文件中可以获取
    • 在页面最后有 https://kyfw.12306.cn/otn/resources/js/framework/station_name.js 链接
3. 解析数据

提取我们需要的数据内容: 车次相关内容

4. 保存数据
  • 字典取值
    • 键值对取值: 根据冒号左边的内容 [“键”, 提取冒号右边的内容 [“值”]]

当然,下面我将重点介绍每个步骤的关键点,并附上相应的代码片段。

1. 获取站点编码

关键点:从 12306 的 JS 文件中解析站点的三字码。

代码片段:

def get_station_codes():code_url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js"response = requests.get(code_url)code_data = response.text[20:-2]  # 优化:去除尾部的双引号和换行符list_code = code_data.split("|")station_codes = dict(zip(list_code[1::5], list_code[2::5]))  # 优化:直接跳过索引获取站点名称和代码return station_codes

2. 用户输入

关键点:提示用户输入起始站、终点站和出发日期,然后转换为 12306 需要的编码。

代码片段:

def get_user_input(code_dic):from_station = input("输入起始站:\n")to_station = input("输入终点站:\n")time = input("输入时间,例如:2024-09-18:\n")return code_dic.get(from_station, ""), code_dic.get(to_station, ""), time

3. 获取火车票信息

关键点:构建请求 URL,模拟浏览器发送 HTTP 请求获取数据。

代码片段:

def get_train_info(from_station, to_station, time):train_url = f"https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={time}&leftTicketDTO.from_station={from_station}&leftTicketDTO.to_station={to_station}&purpose_codes=ADULT"headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"}response = requests.get(url=train_url, headers=headers)return response.json()

4. 打印火车票信息

关键点:解析服务器返回的 JSON 数据,并使用PrettyTable格式化输出。

代码片段:

def print_train_info(json_data):table = PrettyTable()table.field_names = ['车次', '出发时间', '到达时间', '历时', '一等座', '二等座', '特等座']if json_data['httpstatus'] == 200:result = json_data['data']['result']for item in result:details = item.split('|')table.add_row([details[3], details[8], details[9], details[10], details[30], details[31], details[32]])print(table)else:print(f"获取响应数据失败,状态码为{json_data['httpstatus']}")

5. Selenium 自动化

关键点:使用 Selenium 模拟用户在网页上的操作,如填写表单、点击按钮等。

代码片段:

def main():# 获取站点编码code_dic = get_station_codes()# 获取用户输入from_station_code, to_station_code, time = get_user_input(code_dic)# 使用Selenium打开网页browser = webdriver.Edge()browser.get('https://kyfw.12306.cn/otn/leftTicket/init')# 填写查询表单start_station = browser.find_element(By.CSS_SELECTOR, '#fromStationText')start_station.send_keys("广州南")start_station.send_keys(Keys.ENTER)end_station = browser.find_element(By.CSS_SELECTOR, '#toStationText')end_station.send_keys("韶关")end_station.send_keys(Keys.ENTER)date = browser.find_element(By.CSS_SELECTOR, '#train_date')date.send_keys("2024-09-18")date.send_keys(Keys.ENTER)# 点击查询browser.find_element(By.CSS_SELECTOR, '#query_ticket').click()# 等待查询结果t.sleep(5)  # 优化:使用更明确的等待条件# 处理查询结果# 省略:根据实际情况处理查询结果# 关闭浏览器browser.quit()

6. 完整代码

# coding=gbk
import time as t
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from prettytable import PrettyTable
import re# 获取站点对应的三字码
def get_station_codes():code_url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js"response = requests.get(code_url)code_data = response.text[20:-2]  # 优化:去除尾部的双引号和换行符list_code = code_data.split("|")station_codes = dict(zip(list_code[1::5], list_code[2::5]))  # 优化:直接跳过索引获取站点名称和代码return station_codes# 用户输入起始站、终点站和时间,转化为编码
def get_user_input(code_dic):from_station = input("输入起始站:\n")to_station = input("输入终点站:\n")time = input("输入时间,例如:2024-09-18:\n")return code_dic.get(from_station, ""), code_dic.get(to_station, ""), time# 获取火车票信息
def get_train_info(from_station, to_station, time):train_url = f"https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={time}&leftTicketDTO.from_station={from_station}&leftTicketDTO.to_station={to_station}&purpose_codes=ADULT"headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"}response = requests.get(url=train_url, headers=headers)return response.json()# 打印火车票信息
def print_train_info(json_data):table = PrettyTable()table.field_names = ['车次', '出发时间', '到达时间', '历时', '一等座', '二等座', '特等座']if json_data['httpstatus'] == 200:result = json_data['data']['result']for item in result:details = item.split('|')table.add_row([details[3], details[8], details[9], details[10], details[30], details[31], details[32]])print(table)else:print(f"获取响应数据失败,状态码为{json_data['httpstatus']}")# 主函数
def main():# 获取站点编码code_dic = get_station_codes()# 获取用户输入from_station, to_station, time = get_user_input(code_dic)# 获取火车票信息json_data = get_train_info(from_station, to_station, time)# 打印火车票信息print_train_info(json_data)# 使用Selenium打开网页browser = webdriver.Edge()browser.get('https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc')# 填写查询表单start_station = browser.find_element(By.CSS_SELECTOR, '#fromStationText')start_station.clear()start_station.send_keys("广州南")start_station.send_keys(Keys.ENTER)end_station = browser.find_element(By.CSS_SELECTOR, '#toStationText')end_station.clear()end_station.send_keys("韶关")end_station.send_keys(Keys.ENTER)date = browser.find_element(By.CSS_SELECTOR, '#train_date')date.clear()date.send_keys("2024-09-18")date.send_keys(Keys.ENTER)# 点击查询browser.find_element(By.CSS_SELECTOR, '#query_ticket').click()# 等待查询结果t.sleep(5)  # 优化:使用更明确的等待条件# 处理查询结果elements = browser.find_elements(By.CSS_SELECTOR, '#queryLeftTable tr:nth-child(7) .btn72')if elements:elements[0].click()# 扫码登陆saoma = browser.find_element(By.CSS_SELECTOR, '#login > div.login-box > ul > li.login-hd-account > a')saoma.click()t.sleep(5)  # 优化:使用更明确的等待条件# 登录操作J_userName = browser.find_element(By.CSS_SELECTOR, '#J-userName')J_userName.clear()J_userName.send_keys("aaa")J_password = browser.find_element(By.CSS_SELECTOR, '#J-password')J_password.clear()J_password.send_keys("password")J_loginmodalBtn = browser.find_element(By.CSS_SELECTOR, '#J-login')J_loginmodalBtn.click()# 点击预订browser.find_element(By.CSS_SELECTOR, '#normalPassenger_0').click()t.sleep(1)browser.find_element(By.CSS_SELECTOR, '#dialog_xsertcj_cancel').click()# 修改成人票ticket_type_select = browser.find_element(By.CSS_SELECTOR, '#ticketType_1')ticket_type_select.click()# 选择成人票adult_ticket_option = browser.find_element(By.CSS_SELECTOR, '#ticketType_1 > option[value="1"]')adult_ticket_option.click()t.sleep(1)browser.find_element(By.CSS_SELECTOR, '#submitOrder_id').click()qr_submit_id = browser.find_element(By.CSS_SELECTOR, '#qr_submit_id')if qr_submit_id:qr_submit_id.click()input("输入任意字符后回车继续...")# 关闭浏览器browser.quit()if __name__ == "__main__":main()

这篇关于自动化抢票 12306的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146692

相关文章

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum

基于Python实现自动化邮件发送系统的完整指南

《基于Python实现自动化邮件发送系统的完整指南》在现代软件开发和自动化流程中,邮件通知是一个常见且实用的功能,无论是用于发送报告、告警信息还是用户提醒,通过Python实现自动化的邮件发送功能都能... 目录一、前言:二、项目概述三、配置文件 `.env` 解析四、代码结构解析1. 导入模块2. 加载环

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Python使用python-pptx自动化操作和生成PPT

《Python使用python-pptx自动化操作和生成PPT》这篇文章主要为大家详细介绍了如何使用python-pptx库实现PPT自动化,并提供实用的代码示例和应用场景,感兴趣的小伙伴可以跟随小编... 目录使用python-pptx操作PPT文档安装python-pptx基础概念创建新的PPT文档查看

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

Python调用LibreOffice处理自动化文档的完整指南

《Python调用LibreOffice处理自动化文档的完整指南》在数字化转型的浪潮中,文档处理自动化已成为提升效率的关键,LibreOffice作为开源办公软件的佼佼者,其命令行功能结合Python... 目录引言一、环境搭建:三步构建自动化基石1. 安装LibreOffice与python2. 验证安装

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习

Python自动化批量重命名与整理文件系统

《Python自动化批量重命名与整理文件系统》这篇文章主要为大家详细介绍了如何使用Python实现一个强大的文件批量重命名与整理工具,帮助开发者自动化这一繁琐过程,有需要的小伙伴可以了解下... 目录简介环境准备项目功能概述代码详细解析1. 导入必要的库2. 配置参数设置3. 创建日志系统4. 安全文件名处