- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python实现全自动购买火车票!抢票回家过年咯由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
这个是实现结果,因为一天只能取消三次,所以最后一步点击确认被我注释了.
1.首先实现使用selenium登陆12306 。
关于使用selenium实现12306登陆可以看我的另一篇文章 这里实现了使用selenium登陆12306,这次是基于上次的代码进行修改实现全自动购买车票的 实现全自动登陆12306链接.
2.根据上面实现登陆后,实现购买火车票还需两步 。
这里只进行了二等座的查询和购票,想要买其他的自己也可以进行修改 1.进行车票的查询 这里面需要注意的是在输入目的地和起始地时需要先click一下文本框browser.find_element_by_id(‘fromStationText’).click() 不然输入的地址无效 还有将日期的只读属性去掉.
def search_railway_ticket(fromstation,tostation,train_date): 。
# 火车票页面查询url 。
search_url = 'https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc' 。
# 转到查询车次页面 。
browser.get(search_url) 。
time.sleep(2) 。
#输入出发地 。
WebDriverWait(browser, 1000).until( 。
EC.presence_of_element_located((By.ID, 'fromStationText')) 。
) 。
#先点击一下 。
browser.find_element_by_id('fromStationText').click() 。
browser.find_element_by_id('fromStationText').send_keys(fromstation) 。
browser.find_element_by_id('fromStationText').send_keys(Keys.ENTER) 。
time.sleep(1) 。
WebDriverWait(browser, 1000).until( 。
EC.presence_of_element_located((By.ID, 'toStationText')) 。
) 。
#输入目的地 。
browser.find_element_by_id('toStationText').click() 。
browser.find_element_by_id('toStationText').send_keys(tostation) 。
browser.find_element_by_id('toStationText').send_keys(Keys.ENTER) 。
time.sleep(5) 。
#将日期的只读属性去掉 。
js = 'document.getElementById("train_date").removeAttribute("readonly")' 。
browser.execute_script(js) 。
#去掉原本的时间 。
WebDriverWait(browser, 1000).until( 。
EC.presence_of_element_located((By.ID, 'train_date')) 。
) 。
browser.find_element_by_id("train_date").clear() 。
#输入出发时间 。
browser.find_element_by_id('train_date').send_keys(train_date) 。
# 等待查询按钮是否可用 。
WebDriverWait(browser, 1000).until( 。
EC.element_to_be_clickable((By.ID, 'query_ticket')) 。
) 。
searBtn = browser.find_element_by_id('query_ticket') 。
searBtn.click() 。
print('点击按钮') 。
2.购买火车票 在这个函数中需要注意的是最好把最后一步注释掉 browser.find_element_by_id(‘qr_submit_id’).click() 因为一天只能取消3次订单.
def buy_ticket(fromstation,tostation,train_date,train_number,passenger): 。
。
#查询火车票 。
search_railway_ticket(fromstation,tostation,train_date) 。
time.sleep(5) 。
#获取每一个车次的信息 。
tr_list = browser.find_elements_by_xpath('.//tbody[@id="queryLeftTable"]/tr[not(@datatran)]') 。
for tr in tr_list: 。
#获取车次号 。
number = tr.find_element_by_class_name('number').text 。
if number in train_number: 。
#获取是否还有票 。
left_ticket = tr.find_element_by_xpath('./td[4]').text 。
if left_ticket =='有'or left_ticket.isdigit: 。
print(f'{number}还有票') 。
#点击预订 。
orderBtn = tr.find_element_by_class_name('btn72') 。
orderBtn.click() 。
time.sleep(5) 。
#获取12306中乘客的信息 。
passenger_list = browser.find_elements_by_xpath('//*[@id="normal_passenger_id"]/li') 。
for li in passenger_list: 。
name = li.find_element_by_xpath('./label').text 。
print(name) 。
#配对12306人名 。
if name == passenger: 。
li.find_element_by_tag_name('input').click() 。
#提交订单 。
submit = browser.find_element_by_id('submitOrder_id') 。
submit.click() 。
WebDriverWait(browser, 1000).until( 。
EC.element_to_be_clickable((By.ID, 'qr_submit_id')) 。
) 。
#一天只能取消3次 所以最好把最后一步注释了 。
browser.find_element_by_id('qr_submit_id').click() 。
print('已经提交订单') 。
break 。
下面是源代码 。
测试的时候可以把#click_captcha()这个点击验证码的去掉自己手动点击,这样就不用扣超级鹰的积分(有钱的话当我没说),留下了贫穷的泪水.
from selenium import webdriver 。
from selenium.webdriver import Actionchains 。
import time 。
from PIL import Image 。
import requests 。
from hashlib import md5 。
from selenium.webdriver import ChromeOptions 。
#验证码识别处理 。
from selenium.webdriver.common.keys import Keys 。
from selenium.webdriver.common.by import By 。
from selenium.webdriver.support.wait import WebDriverWait 。
from selenium.webdriver.support import expected_conditions as EC 。
。
class Chaojiying_Client(object): 。
。
def __init__(self, username, password, soft_id): 。
self.username = username 。
password = password.encode('utf8') 。
self.password = md5(password).hexdigest() 。
self.soft_id = soft_id 。
self.base_params = { 。
'user': self.username, 。
'pass2': self.password, 。
'softid': self.soft_id, 。
} 。
self.headers = { 。
'Connection': 'Keep-Alive', 。
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', 。
} 。
。
def PostPic(self, im, codetype): 。
""" 。
im: 图片字节 。
codetype: 题目类型 参考 http://www.chaojiying.com/price.html 。
""" 。
params = { 。
'codetype': codetype, 。
} 。
params.update(self.base_params) 。
files = {'userfile': ('ccc.jpg', im)} 。
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers) 。
return r.json() 。
。
def ReportError(self, im_id): 。
""" 。
im_id:报错题目的图片ID 。
""" 。
params = { 。
'id': im_id, 。
} 。
params.update(self.base_params) 。
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers) 。
return r.json() 。
。
def login(username,password): 。
# 填写账号密码 。
browser.find_element_by_id('J-userName').send_keys(username) 。
browser.find_element_by_id('J-password').send_keys(password) 。
。
# 获取验证码 。
get_captcha() 。
。
# 填写验证码 。
click_captcha() 。
。
#点击登录 。
time.sleep(4) 。
browser.find_element_by_id('J-login').click() 。
time.sleep(4) 。
。
#滑动验证码 。
slider() 。
。
print('成功登陆') 。
time.sleep(5) 。
。
def slider(): 。
#滑动验证码 。
WebDriverWait(browser, 1000).until( 。
EC.presence_of_element_located((By.XPATH, '//*[@id="nc_1_n1z"]')) 。
) 。
span = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]') 。
# 对div_tag进行滑动操作 。
action = Actionchains(browser) 。
# 点击长按指定的标签 。
action.click_and_hold(span).perform() 。
action.drag_and_drop_by_offset(span, 400, 0).perform() 。
。
def click_captcha(): 。
# 获取验证码需要的为点击位置 。
chaojiying = Chaojiying_Client('自己的用户名', '密码', '软件id') # 用户中心>>软件ID 生成一个替换 96001 。
im = open('./captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要// 。
location = chaojiying.PostPic(im, 9004)['pic_str'] # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加() 。
print(chaojiying.PostPic(im, 9004)) 。
# 将位置进行分割成 [ [ ], [ ], [ ] ]类型 。
location_list = [i.split(',') for i in location.split('|')] 。
for l in location_list: 。
x = l[0] 。
y = l[1] 。
Actionchains(browser).move_to_element_with_offset(browser.find_element_by_class_name('login-pwd-code'), int(x),int(y)).click().perform() 。
time.sleep(0.5) 。
。
def get_captcha(): 。
# 获取网页的截图 。
allscreen = browser.get_screenshot_as_file('allscreen.png') 。
# 获取captcha 。
captcha = browser.find_element_by_class_name('login-pwd-code') 。
# 获取captcha的左上角位置 。
location = captcha.location 。
# 获取图片大小 。
size = captcha.size 。
# 裁取captcha 。
rangle = (location['x'],location['y'],(location['x']+size['width']),(location['y']+size['height'])) 。
i = Image.open('./allscreen.png') 。
captcha_img = './captcha.png' 。
frame = i.crop(rangle) 。
frame.save(captcha_img) 。
。
def buy_ticket(fromstation,tostation,train_date,train_number,passenger): 。
。
#查询火车票 。
search_railway_ticket(fromstation,tostation,train_date) 。
time.sleep(5) 。
tr_list = browser.find_elements_by_xpath('.//tbody[@id="queryLeftTable"]/tr[not(@datatran)]') 。
for tr in tr_list: 。
number = tr.find_element_by_class_name('number').text 。
if number in train_number: 。
left_ticket = tr.find_element_by_xpath('./td[4]').text 。
if left_ticket =='有'or left_ticket.isdigit: 。
print(f'{number}还有票') 。
orderBtn = tr.find_element_by_class_name('btn72') 。
orderBtn.click() 。
time.sleep(5) 。
passenger_list = browser.find_elements_by_xpath('//*[@id="normal_passenger_id"]/li') 。
for li in passenger_list: 。
name = li.find_element_by_xpath('./label').text 。
if name == passenger: 。
li.find_element_by_tag_name('input').click() 。
submit = browser.find_element_by_id('submitOrder_id') 。
submit.click() 。
WebDriverWait(browser, 1000).until( 。
EC.element_to_be_clickable((By.ID, 'qr_submit_id')) 。
) 。
#一天只能取消3次 所以把最后一步注释了 。
# browser.find_element_by_id('qr_submit_id').click() 。
print('已经提交订单') 。
break 。
。
def search_railway_ticket(fromstation,tostation,train_date): 。
# 火车票页面查询url 。
search_url = 'https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc' 。
# 转到查询车次页面 。
browser.get(search_url) 。
time.sleep(2) 。
#输入出发地 。
WebDriverWait(browser, 1000).until( 。
EC.presence_of_element_located((By.ID, 'fromStationText')) 。
) 。
#先点击一下 。
browser.find_element_by_id('fromStationText').click() 。
browser.find_element_by_id('fromStationText').send_keys(fromstation) 。
browser.find_element_by_id('fromStationText').send_keys(Keys.ENTER) 。
time.sleep(1) 。
WebDriverWait(browser, 1000).until( 。
EC.presence_of_element_located((By.ID, 'toStationText')) 。
) 。
#输入目的地 。
browser.find_element_by_id('toStationText').click() 。
browser.find_element_by_id('toStationText').send_keys(tostation) 。
browser.find_element_by_id('toStationText').send_keys(Keys.ENTER) 。
time.sleep(5) 。
#将日期的只读属性去掉 。
js = 'document.getElementById("train_date").removeAttribute("readonly")' 。
browser.execute_script(js) 。
#去掉原本的时间 。
WebDriverWait(browser, 1000).until( 。
EC.presence_of_element_located((By.ID, 'train_date')) 。
) 。
browser.find_element_by_id("train_date").clear() 。
#输入出发时间 。
browser.find_element_by_id('train_date').send_keys(train_date) 。
# 等待查询按钮是否可用 。
WebDriverWait(browser, 1000).until( 。
EC.element_to_be_clickable((By.ID, 'query_ticket')) 。
) 。
searBtn = browser.find_element_by_id('query_ticket') 。
searBtn.click() 。
print('点击按钮') 。
。
if __name__ == '__main__': 。
option = ChromeOptions() # 实例化一个ChromeOptions对象 。
option.add_experimental_option('excludeSwitches', ['enable-automation']) # 以键值对的形式加入参数 。
option.add_experimental_option('useAutomationExtension', False) 。
。
browser = webdriver.Chrome(options=option) 。
# 获取响应 。
browser.get('https://kyfw.12306.cn/otn/resources/login.html') 。
script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});' 。
browser.execute_script(script) 。
browser.maximize_window() 。
time.sleep(1) 。
。
# 点击账号登陆 。
browser.find_element_by_class_name('login-hd-account').click() 。
#登陆12306的账号密码 。
login('用户名','密码') 。
time.sleep(4) 。
#例buy_ticket('南昌','抚州北','2020-12-15','D2241','xx') 。
buy_ticket('起始地','目的地','出发日期','车次','姓名') 。
原文地址:https://www.toutiao.com/a6906741777911317004/ 。
最后此篇关于Python实现全自动购买火车票!抢票回家过年咯的文章就讲到这里了,如果你想了解更多关于Python实现全自动购买火车票!抢票回家过年咯的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一名优秀的程序员,十分优秀!