目录
接前面一、二部分解决抢不到票的问题,本部分解决乘客选择与车票提交问题,并完整完成自动化购票功能。
操作系统:win 10
编辑器:pycharm edu
语言及版本:python 3.10
使用的库:selenium
实现思路:使用selenium模拟人的行为,进行自动化操作
关于代码:完整代码已放出
第一部分内容-->已解决登录问题
第一部分内容链接:第一部分内容
第二部分内容-->已解决车次查找与预定车次问题
第二部分内容链接:第二部分内容
浏览器下载与驱动的安装:火狐浏览器下载与驱动下载
浏览器闪退说明:大概率是因为下载的浏览器和浏览器驱动版本不一致,建议使用搜索引擎查找大佬分享的内容解决
tips:以下url不会放真实的,拿来测试注意识别并自行更改。
当前界面默认进入乘客选择界面,因为之前的内容已经进入到该界面了。
需要先把这个提示内容去掉,在输入需要购买车票的乘客名字进行检索,如下图1;
# 进入订单界面,切换视角
driver.switch_to.window(driver.window_handles[-1])
time.sleep(3) # 给加载时间
# 进入乘客选择
driver.find_element(By.XPATH, '//*[@id="quickQueryPassenger_id"]').click() # 先点击,把提示内容去除
driver.find_element(By.XPATH, '//*[@id="quickQueryPassenger_id"]').send_keys("乘客名字") # 输入乘客姓名

图1
乘客检索出来后,进行乘客的选择,如下图2;
time.sleep(0.5) # 给加载时间
driver.find_element(By.XPATH, '//*[@id="normalPassenger_0"]').click() # 选择乘客

图2
选择乘客后,如果是学生会出现学生票购买提示页面,需要关闭这个页面,如下图3;
time.sleep(2) # 给加载时间
driver.find_element(By.XPATH, '//*[@id="dialog_xsertcj_cancel"]').click() # 关闭学生票选项

图3
一切准备就绪,可以进行提交订单了,如下图4;
driver.find_element(By.XPATH, '//*[@id="submitOrder_id"]').click() # 提交订单

图4
座位选择的是F靠窗位置,座位不选择直接提交订单,随机座位也是可以的;
# 选择座位,这里选择的是靠窗的F座位,不选择座位也是可以的
driver.find_element(By.XPATH, '//*[@id="1F"]').click()
# 点击确认订单
driver.find_element(By.XPATH, '//*[@id="qr_submit_id"]').click()
from selenium.webdriver import Firefox # 导入火狐
from selenium.webdriver.common.action_chains import ActionChains # 导入时间链
from selenium.webdriver.common.by import By # 导入需要的组件
from selenium.webdriver.common.keys import Keys
import time
def login_shop():
login_url = "这里是12306登录的url" # 登录界面url
trains = ['G4362', 'K1208'] # 这里是你要购买票的车次名称
driver = Firefox()
driver.get(login_url)
script = 'Object.defineProperty(navigator,"webdriver",{get:()=>false,});'
driver.execute_script(script)
driver.find_element(By.XPATH, '//*[@id="J-userName"]').send_keys("你的账户")
driver.find_element(By.XPATH, '//*[@id="J-password"]').send_keys("你的密码")
driver.find_element(By.XPATH, '//*[@id="J-login"]').click()
time.sleep(5)
push_btu = driver.find_element(By.XPATH, '//*[@id="nc_1_n1z"]')
# 拖动滑块后,会跳转新窗口 //*[@id="nc_1_n1z"]
ActionChains(driver).drag_and_drop_by_offset(push_btu, 300, 0).perform()
# 切换到新窗口
driver.switch_to.window(driver.window_handles[-1])
time.sleep(3)
# 刷新
driver.refresh()
time.sleep(3)
# 在新窗口点击前往订票,又会跳转到新窗口
driver.find_element(By.XPATH, '//*[@id="link_for_ticket"]').click()
# 这里也生成了一个新窗口,需要切换
driver.switch_to.window(driver.window_handles[-1])
time.sleep(5)
# 出发地
driver.find_element(By.XPATH, '//*[@id="fromStationText"]').click()
driver.find_element(By.XPATH, '//*[@id="fromStationText"]').send_keys("深圳北", Keys.ENTER)
# 目的地
driver.find_element(By.XPATH, '//*[@id="toStationText"]').click()
driver.find_element(By.XPATH, '//*[@id="toStationText"]').send_keys("百色", Keys.ENTER)
# 日期,先清除默认内容,在输入
driver.find_element(By.XPATH, '//*[@id="train_date"]').click()
driver.find_element(By.XPATH, '//*[@id="train_date"]').clear()
driver.find_element(By.XPATH, '//*[@id="train_date"]').send_keys("2023-01-20")
# 点击查询
driver.find_element(By.XPATH, '//*[@id="query_ticket"]').click()
# 保存加载出来的车次信息,并进行筛选判断
time.sleep(6) # 确保页面内容加载完成
# print(driver.current_url)
tr_list = driver.find_elements(By.XPATH, ".//tbody[@id='queryLeftTable']/tr[not(@datatran)]")
# //*[@id="queryLeftTable"]
for tr in tr_list: # 遍历所有车次信息
train_number = tr.find_element(By.CLASS_NAME, "number").text # 车次
print(train_number)
if train_number in trains: # 如果该车次在输入的车次里
left_ticker_td = tr.find_element(By.XPATH, './/td[4]').text
if left_ticker_td == '有' or left_ticker_td.isdigit(): # 如果该车次有票
print(train_number+'有票')
btn72 = tr.find_element(By.CLASS_NAME, 'btn72') # 找到该车次的预订按钮
btn72.click()
break # 这里点击了之后一定要退出,否则程序继续循环会导致报错
# 进入订单界面,切换视角
driver.switch_to.window(driver.window_handles[-1])
time.sleep(3) # 给加载时间
# 进入乘客选择
driver.find_element(By.XPATH, '//*[@id="quickQueryPassenger_id"]').click() # 先点击,把提示内容去除
driver.find_element(By.XPATH, '//*[@id="quickQueryPassenger_id"]').send_keys("乘客名称") # 输入乘客姓名
time.sleep(0.5) # 给加载时间
driver.find_element(By.XPATH, '//*[@id="normalPassenger_0"]').click() # 选择乘客
time.sleep(2) # 给加载时间
driver.find_element(By.XPATH, '//*[@id="dialog_xsertcj_cancel"]').click() # 关闭学生票选项
driver.find_element(By.XPATH, '//*[@id="submitOrder_id"]').click() # 提交订单
# 选择座位,这里选择的是靠窗的F座位,不选择座位也是可以的
driver.find_element(By.XPATH, '//*[@id="1F"]').click()
# 点击确认订单
driver.find_element(By.XPATH, '//*[@id="qr_submit_id"]').click()
if __name__ == '__main__':
login_shop()
视频已经制作好了,但是有些奇怪不知道为啥电脑接收不了,所以就不上传了,需要视频请在评论区评论或者私聊我。
如下图5:

图5
1)将一个大问题分析若干部分解决,将会变得轻松;
2)多学习;
1)在以上的代码中用到了很多延时来确保页面可以加载成功,导致抢票慢,那么如何改进呢?
有两个库可以解决这个问题;
from selenium.webdriver.support.ui import WebDriverWait # 条件等待 from selenium.webdriver.support import expected_conditions # 导入判断条件
加入限定条件,确保页面加载完成了在进行下一步代码的执行,就不需要一直time.sleep了;
2)我们简陋的程序如何能抢得过各大抢票平台呢?
使用服务器进行代码的持续运行,增加购票成功的几率;
3)我们代码只能进行单次的抢票,如何进行多次抢票呢?
使用循环,或者其它条件,指定时间就执行一次代码,进行查票购票等操作即可;
4)买到票之后,只有10分钟的付款时间,抢到票如何进行快速通知呢?
Python实现用QQ邮箱发邮件进行提醒等;
总之,购票平台的自动化购票对我而言是一次很好的锻炼,以上内容是粗略记录该过程,之后更加完善自动化购票功能在进行分享,欢迎批评指正;
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or