• 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)
    最后,祝大家都能顺利抢到票回家过年。
  • 相关阅读:
    css伪类函数 :is() 和 :where()
    卷积层 / 全连接层 的空间和计算复杂度
    mysql中分组获取前三条记录的方法
    sql server数据去重复的四种方法
    C#获取dynamic(动态)实体的属性值
    Sqlserver使用游标循环插入,把上一个select语句的结果当成value值的一部分insert到一张表
    红玫瑰与白玫瑰
    解决vue3中通过params传值以后,刷新页面,params丢失问题。
    mybatis 注解的方式查询
    了解Android已发布的各种版本(即1.0、2.0、3.0、4.0、5.0、6.0、7.0、8.0)
  • 原文地址:https://www.cnblogs.com/leedhwa/p/10231613.html
Copyright © 2020-2023  润新知