用 Python + Selenium + Browser Driver 实现华为手机自动抢购

随着华为手机的火爆,每次发售的时候,许多小伙伴都会面临“秒没”的困扰。为了提升抢购的成功率,我们可以用 Python 来写一个自动化抢购脚本,利用 Selenium 模拟用户操作,大大提高抢购成功的几率。

本文将详细介绍如何使用 Python + Selenium + 浏览器驱动 来编写一个华为手机自动抢购的脚本。

一、准备工作
  1. Python 环境安装

    首先,你需要安装 Python。可以在 Python官网 下载并安装适合你操作系统的版本。安装完成后,可以在命令行中输入以下命令来确认是否安装成功:

    python --version
    

    输出 Python 版本号表示安装成功。

  2. 安装 Selenium

    Selenium 是一个自动化测试工具,能够控制浏览器进行各种操作。使用 pip 来安装 Selenium:

    pip install selenium
    
  3. 浏览器驱动

    Selenium 需要依赖浏览器驱动与真实的浏览器进行交互。这里我们选择Chrome的驱动。以下是主流浏览器的驱动下载地址:

  4. Chrome驱动下载:https://sites.google.com/chromium.org/driver/downloads
  5. 下载对应的驱动后,将其路径添加到系统的环境变量中或者在程序中指定路径,确保 Selenium 能够找到它。

二、脚本代码

接下来,我们将使用 Python + Selenium 编写一个简单的华为手机抢购脚本。脚本的核心流程包括:

  • 打开华为商城
  • self.browser.get('https://www.vmall.com/')
    self.driverWait.until(EC.url_changes)
  • 登录账号
  •     def __do_login(self):
            logger.info("开始输入账号及密码")
            inputElements = self.driverWait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, "hwid-input")))
    
            inputElements[0].send_keys(self.config.get("user", "name"))
            inputElements[1].send_keys(self.config.get("user", "password"))
            logger.info("已输入账号及密码")
    
            self.driverWait.until(EC.presence_of_element_located((By.CLASS_NAME, "hwid-login-btn"))).click()
            logger.info("发起登录请求")
  • 进入商品页面
  •     def __visit_product_page(self):
            currentUrl = self.browser.current_url
            logger.info("开始进入华为 {0} 产品详情页".format(self.config.get("product", "name")))
            self.browser.get("https://www.vmall.com/product/{0}.html".format(self.config.get("product", "id")))
            try:
                self.driverWait.until(EC.url_changes(currentUrl))
                logger.info("已进入华为 {0} 产品详情页".format(self.config.get("product", "name")))
                self.__get_current_page_type()
            except TimeoutException:
                logger.info("进入华为 {0} 产品详情页失败,程序将在3秒后退出...".format(self.config.get("product", "name")))
                time.sleep(3)
                self.browser.quit()
        def __choose_product_item(self):
            logger.info("开始选择手机单品规格")
            sku_color = self.config.get("product", "color")
            sku_version = self.config.get("product", "version")
            self.driverWait.until(EC.presence_of_element_located((By.XPATH, f"//div[text()='{sku_color}']"))).click()
            self.driverWait.until(EC.presence_of_element_located((By.XPATH, f"//div[text()='{sku_version}']"))).click()
            sku_payment = '无'
            # if EC.text_to_be_present_in_element((By.XPATH, "//div[text()='销售类型']"), "销售类型")(self.browser):
            #     sku_payment = self.config.get("product", "payment")
            #     self.driverWait.until(EC.presence_of_element_located((By.XPATH, f"//div[text()='{sku_payment}']"))).click()
            logger.info("选择手机单品规格完成,颜色:{0} 版本:{1} 销售类型:{1}".format(sku_color, sku_version, sku_payment))
  • 判断是否可以购买
  •     def __waiting_count(self):
            times = 1
            while self.isWaiting and times <= 3:
                try:
                    if EC.text_to_be_present_in_element((By.XPATH, "//div[text()='立即购买']"), "立即购买")(
                            self.browser):
                        logger.info("当前可立即下单")
                        self.__set_end_countdown()
                        self.__set_buy_now()
                    elif EC.text_to_be_present_in_element((By.XPATH, "//div[text()='暂时缺货']"), "暂时缺货")(
                            self.browser):
                        logger.info("【{}】倒计时未开始,等待中...", "暂时缺货")
                        time.sleep(120)
                        self.__refresh_product_page()
                    elif EC.text_to_be_present_in_element((By.XPATH, "//div[text()='即将开始']"), "即将开始")(
                            self.browser):
                        logger.info("倒计时即将开始")
                        self.__get_sec_kill_time()
                        if self.secKillTime is not None:
                            self.__set_end_waiting()
                            time.sleep(1)
                    else:
                        logger.info("【{}】倒计时未开始,等待中...", "暂不售卖")
                        time.sleep(120)
                        self.__refresh_product_page()
                except NoSuchElementException:
                    time.sleep(1)
                    times += 1
  • 下单
  •     def __start_buying(self):
            logger.info("进入抢购活动最后排队下单环节")
            self.__create_and_start_thread()
            clickTimes = 1
            while self.isStartBuying:
                countdownMsDiff = utils.calc_countdown_ms_diff(self.secKillTime,
                                                               self.localTimestamp - self.hwServerTimestamp)
                countdown_times = utils.calc_countdown_times(self.secKillTime,
                                                             self.localTimestamp - self.hwServerTimestamp)
                if countdownMsDiff > 1000:
                    logger.info("距离抢购活动最后下单环节开始还剩:{}", utils.format_countdown_time(countdown_times))
                    time.sleep(1)
                elif countdownMsDiff > 100:
                    logger.info("距离抢购活动最后下单环节开始还剩:{}", utils.format_countdown_time(countdown_times))
                    time.sleep(0.1)
                elif countdownMsDiff > 10:
                    logger.info("距离抢购活动最后下单环节开始还剩:{}", utils.format_countdown_time(countdown_times))
                    time.sleep(0.01)
                else:
                    logger.info("抢购活动最后下单环节,进行第 {} 次尝试立即下单", clickTimes)
                    self.__do_start_buying()
                    self.__check_can_submit_order()
                    self.__submit_order()
                    clickTimes += 1
                    time.sleep(float(self.config.get('process', 'interval', '0.001')))
     
       def __buy_now(self):
            if self.isBuyNow:
                currentUrl = self.browser.current_url
                logger.info("开始立即购买")
                try:
                    buttons = self.driverWait.until(
                        EC.presence_of_all_elements_located((By.XPATH, "//div[text()='立即购买']")))
                    orderBtn = None
                    for button in buttons:
                        if '立即购买' == button.text:
                            orderBtn = button
                    if orderBtn is not None:
                        orderBtn.click()
                        time.sleep(1)
    
                        new_window = self.browser.window_handles[-1]
                        self.browser.switch_to.window(new_window)
                        self.__click_submit_order(currentUrl)
                except (NoSuchElementException, ElementClickInterceptedException, StaleElementReferenceException) as e:
                    logger.info("未找到【立即购买】按钮或按钮不可点击; except:{}", e)
                logger.info("结束立即购买")
    三、运行脚本

    程序运行效果

    用 Python + Selenium + Browser Driver 实现华为手机自动抢购

    作者:苜蓿花乐园

    物联沃分享整理
    物联沃-IOTWORD物联网 » 用 Python + Selenium + Browser Driver 实现华为手机自动抢购

    发表回复