zoukankan      html  css  js  c++  java
  • 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:pythonchromedriver.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 = 'xxx@qq.com'  # 发件人邮箱账号
            my_user = 'xxxx@qq.com'  # 收件人邮箱账号
            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)
    最后,祝大家都能顺利抢到票回家过年。
  • 相关阅读:
    Microsoft Visual C++ Compiler for Python
    ArcGIS Server的Tile的松散型存储(Exploded)
    git下载指定版本的代码
    C#+SharpMap的相关代码
    C#+MapServer相关代码
    WebGIS点要素渲染性能测试
    Docker的4种网络模式
    AngularJS中的指令全面解析(转载)
    风云2号云图Mosaic Dataset处理
    查找错误的等值线中的高程点
  • 原文地址:https://www.cnblogs.com/leedhwa/p/10231613.html
Copyright © 2011-2022 走看看