1 Star 1 Fork 0

Fdk少东家 / 基于selenium的12306抢票程序

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
12306.py 8.21 KB
一键复制 编辑 原始数据 按行查看 历史
Fdk少东家 提交于 2018-10-09 17:04 . second commit
# encoding: utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
import re, time
import smtplib
from email.mime.text import MIMEText
from email.header import Header
class Qiangpiao(object):
def __init__(self):
# 邮箱配置
self.mail_host = "smtp.qq.com" # 设置服务器
self.mail_user = "978326643@qq.com" # 用户名
self.mail_pass = "bfkmrfborcwsbcgb" # 口令
self.sender = '978326643@qq.com' # 发件人
# 搜索余票次数
self.search_time = 0
self.driver = webdriver.Chrome()
# 登录的url
self.login_url = "https://kyfw.12306.cn/otn/login/init"
# 个人主页
self.initMy_url = "https://kyfw.12306.cn/otn/index/initMy12306"
# 查票
self.search_url = "https://kyfw.12306.cn/otn/leftTicket/init"
# 订票
self.confirmPassenger_url = "https://kyfw.12306.cn/otn/confirmPassenger/initDc"
# 确定抢票车次
self.sure_train = ''
# 输入个人信息及车次信息
def _inputInfo(self):
print('请在【15分钟】内完成你的信息输入!')
self.start = input('请输入出发地:')
self.to_station = input('请输入目的地:')
self.peoples = input('请输入乘车人(如有多人请用英文逗号隔开):').split(',')
self.start_time = input('请输入乘车日期[例如:2018-06-09]:')
self.train_num = input('请输入抢票的车次(如有多个请用英文逗号隔开):').split(',')
self.my_mail = input('请输入你的邮箱,方便通知你抢票结果信息!:')
print('请在弹出的窗口进行信息填写!')
# 登录12306
def _login(self):
self._inputInfo()
self.driver.get(self.login_url)
WebDriverWait(self.driver, 1000).until(
EC.url_to_be(self.initMy_url)
)
# 检测车票信息输入
def _search_infor(self):
# 1.跳转到查票页面
self.driver.get(self.search_url)
# 2.等待出发地是否输入正确
WebDriverWait(self.driver, 1000).until(
EC.text_to_be_present_in_element_value((By.ID, 'fromStationText'), self.start)
)
# 3.等待目的地是否输入正确
WebDriverWait(self.driver, 1000).until(
EC.text_to_be_present_in_element_value((By.ID, 'toStationText'), self.to_station)
)
# 4.等待出发日期是否输入正确
WebDriverWait(self.driver, 1000).until(
EC.text_to_be_present_in_element_value((By.ID, 'train_date'), self.start_time)
)
# 5.查看查询按钮是否可以被点击
WebDriverWait(self.driver, 1000).until(
EC.element_to_be_clickable((By.ID, 'query_ticket'))
)
# 点击查询按钮,进行车次和余票判断。
# 用于while循环,持续检测余票信息。
def _click_search(self):
# 1.查看查询按钮是否可以被点击
WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((By.ID, 'query_ticket'))
)
# 点击查询按钮
queryBtn = self.driver.find_element_by_id('query_ticket')
queryBtn.click()
# 等待查询页面有数据显示
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.XPATH, '//tbody[@id="queryLeftTable"]/tr'))
)
tr_list = self.driver.find_elements_by_xpath('//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
for tr in tr_list:
train_number = tr.find_element_by_class_name('number').text
if train_number in self.train_num:
# td[10]是硬座,td[4]是二等座
ticket = tr.find_element_by_xpath('.//td[10]').text
if ticket == '有' or ticket.isdigit():
self.sure_train = train_number
print('符合条件的车次有:' + train_number + ',硬座车票状态:' + ticket)
presentBtn = tr.find_element_by_class_name('btn72')
presentBtn.click()
# 成功检测到了符合条件的车票
return True
# 未检测到符合条件的车票
return False
# 提交订单
def _present(self):
# 等待到达订单页面
WebDriverWait(self.driver, 1000).until(
EC.url_to_be(self.confirmPassenger_url)
)
print('------进入订单页面------')
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.XPATH, '//ul[@id="normal_passenger_id"]/li'))
)
Spectator = self.driver.find_elements_by_xpath('//ul[@id="normal_passenger_id"]/li')
for one in Spectator:
person_name = one.find_element_by_xpath('./label').text
name = re.sub(r'\(.*?\)', '', person_name)
# print(person_name,name)
# print('=' * 20)
if name in self.peoples:
personBtn = one.find_element_by_xpath('./label')
personBtn.click()
if self.isElementExits('//a[@id="qd_closeDefaultWarningWindowDialog_id"]'):
self.driver.find_element_by_xpath(
'//div[@id="content_defaultwarningAlert_id"]//a[@class="btn92s"]').click()
print('乘客已选中...')
# 选则座位等级,默认普通火车硬座
selectTag = Select(self.driver.find_element_by_id('seatType_1'))
# value=1是硬座,O是高铁二等座。其他的去查网站源码。
selectTag.select_by_value('1')
# 提交订单
WebDriverWait(self.driver, 20).until(
EC.presence_of_element_located((By.XPATH, '//a[@id="submitOrder_id"]'))
)
submitBtn = self.driver.find_element_by_xpath('//a[@id="submitOrder_id"]')
submitBtn.click()
# 确定订单
WebDriverWait(self.driver, 20).until(
EC.presence_of_element_located((By.XPATH, '//a[@id="qr_submit_id"]'))
)
sure_submitBtn = self.driver.find_element_by_xpath('//a[@id="qr_submit_id"]')
WebDriverWait(self.driver, 20).until(
EC.element_to_be_clickable((By.XPATH, '//a[@id="qr_submit_id"]'))
)
time.sleep(2)
sure_submitBtn.click()
print('订单已提交!')
self.send_mail(to_addr=self.my_mail, content='你已成功抢到了%s车次车票,请在30分钟内前往付款!' % self.sure_train)
# 发送邮件
def send_mail(self, to_addr, content):
# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
message = MIMEText(content, 'plain', 'utf-8')
message['From'] = Header("抢票小程序", 'utf-8') # 发送者
message['Subject'] = Header('抢票结果通知', 'utf-8')
to_addr = [to_addr]
try:
smtpObj = smtplib.SMTP_SSL(self.mail_host, port=465)
smtpObj.login(self.mail_user, self.mail_pass)
smtpObj.sendmail(self.sender, to_addr, message.as_string())
print('通知邮件发送成功!')
except smtplib.SMTPException as e:
print(e)
print('通知发送邮件失败!')
# 检查元素是存在:
def isElementExits(self, xpath):
s = self.driver.find_elements_by_xpath(xpath)
if len(s) == 0:
return False
else:
return True
# 循环查询车票
def _put_order(self):
while True:
flag = self._click_search()
if flag:
return True
self.search_time += 1
print('第{}次搜索!'.format(self.search_time))
if self.search_time > 180:
print('已搜索180次车票信息!暂时没有符合你条件的车票!')
return False
def run(self):
self._login()
self._search_infor()
# 如果有票,就执行订票函数。
if self._put_order():
self._present()
if __name__ == '__main__':
spider = Qiangpiao()
spider.run()
Python
1
https://gitee.com/Fdkhome/12306.git
git@gitee.com:Fdkhome/12306.git
Fdkhome
12306
基于selenium的12306抢票程序
master

搜索帮助