Python实现自动化抢票

临近放假,相信我们每天都在群聊里或者朋友圈看到一些帮忙抢火车票的信息。

作为一个在广东出生长大上小中大学的仔,我抢得最多的只是外卖红包,火车票倒是从没抢过。

看到朋友们抢回家的车票这么辛(bei)苦(can),结合圈里一些前辈的指点,抱着学习的心态用Python做了一个简单的自动化抢票程序,抢到票之后通过绑定的邮箱(比如QQ)发通知。下面分享主要内容:

先自报家门:

    版本号 Python 3.6.5

    编译器 PyCharm PRO 2018.1

    浏览器 Google Chrome 71.0.3

 

首先,我们用到一个Splinter库:

相信做自动化测试、自动化爬虫的朋友都知道Selenium工具,它可以把人为驱动行为转化为机器执行,Splinter的药效跟它是一样的。我们可以进去cmd后用    pip install splinter

这个命令来安装。

然后 ,开始使劲地码:

1.  定义自动购票的类(初始化属性)

class Buy_Tickets(object):
    # 定义实例属性,初始化
    def __init__(self, username, passwd, order, passengers, dtime, starts, ends):
        self.username = username
        self.passwd = passwd
        self.order = order     # 车次,0代表所有车次
        self.passengers = passengers      # 乘客名
        self.starts = starts     # 起始地和终点
        self.ends = ends
        self.dtime = dtime    # 日期
        self.login_url = 'https://kyfw.12306.cn/otn/login/init'
        self.initMy_url = 'https://kyfw.12306.cn/otn/view/index.html'
        self.ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init'
        self.driver_name = 'chrome'
        self.executable_path = 'C:\python\chromedriver.exe'

2.  实现登录功能

def login(self):
        self.driver.visit(self.login_url)
        self.driver.fill('loginUserDTO.user_name', self.username)
        # sleep(1)
        self.driver.fill('userDTO.password', self.passwd)
        # sleep(1)
        print('请输入验证码...')
        while True:
            if self.driver.url != self.initMy_url:
                sleep(1)
            else:
                break

3.  实现购票功能

def start_buy(self):
        self.driver = Browser(driver_name=self.driver_name, executable_path=self.executable_path)
        # 窗口大小的操作
        self.driver.driver.set_window_size(1200, 700)
        self.login()
        self.driver.visit(self.ticket_url)
        try:
            print('开始购票...')
            # 加载查询信息
            self.driver.cookies.add({"_jc_save_fromStation": self.starts})
            self.driver.cookies.add({"_jc_save_toStation": self.ends})
            self.driver.cookies.add({"_jc_save_fromDate": self.dtime})
            self.driver.reload()
            count = 0
            if self.order != 0:
                while self.driver.url == self.ticket_url:
                    self.driver.find_by_text('查询').click()
                    count += 1
                    print('第%d次点击查询...' % count)
                    try:
                        self.driver.find_by_text('预订')[self.order - 1].click()
                        sleep(1.5)
                    except Exception as e:
                        print(e)
                        print('预订失败...')
                        continue

4. 邮箱通知付款

def sendMail(self, mail_title, mail_content):
        my_sender = '[email protected]'  # 发件人邮箱账号
        my_user = '[email protected]'  # 收件人邮箱账号
        try:
            '''发送邮件'''
            msg = MIMEText(mail_content, "plain", 'utf-8')  # 发送邮件内容
            msg["Subject"] = Header(mail_title, 'utf-8')  # 发送邮件主题/标题
            msg["From"] = formataddr(['Bruce pk', my_sender])  # 邮件发送方
            msg["To"] = formataddr(['brucepk', my_user])  # 邮件接收方
            s = smtplib.SMTP("smtp.qq.com", 25)  # 邮箱的传输协议,端口默认25
            s.login(my_sender, 'xxxxx')  # 登录邮箱,这里的第二个参数为qq邮箱授权码,不要填你的登录密码
            s.sendmail(my_sender, [my_user, ], msg.as_string())  # 发送方,接收方,发送消息
            s.quit()  # 退出邮箱
            print("抢票通知邮件发送成功!")
        except Exception:
            print("邮件发送失败~~")

还有,网络不好或者12306的服务器不稳定的时候,就会卡住,针对这种情况,系统会重复查询:


else:
                while self.driver.url == self.ticket_url:
                    self.driver.find_by_text('查询').click()
                    count += 1
                    print('第%d次点击查询...' % count)
                    try:
                        for i in self.driver.find_by_text('预订'):
                            i.click()
                            sleep(1)
                    except Exception as e:
                        print(e)
                        print('预订失败...')
                        continue
            print('开始预订...')
            sleep(1)
            print('开始选择用户...')
            for p in self.passengers:
                self.driver.find_by_text(p).last.click()
                sleep(0.5)
                if p[-1] == ')':
                    self.driver.find_by_id('dialog_xsertcj_ok').click()
            sleep(3)
            print('提交订单...')
            self.driver.find_by_id('submitOrder_id').click()
            sleep(5)
            print('确认选座...')
            self.driver.find_by_id('qr_submit_id').click()
            print('预订成功...')
            sleep(5)
            self.sendMail(mail_title, mail_content)
        except Exception as e:
            print(e)
最后 ,祝大家都能顺利抢到票回家过年。

猜你喜欢

转载自www.cnblogs.com/leedhwa/p/10231613.html