You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速Python嵌套循环执行?基于Selenium自动化场景

Selenium表格遍历提速优化方案

针对6行6列表格嵌套循环耗时30秒的问题,核心优化方向是减少Selenium与浏览器的实时交互次数,把重复的DOM查询改成内存数据处理,具体优化步骤如下:

优化要点

  • 预提取所有单元格数据到本地:一次性把所有单元格的日期、系数信息提取并处理好,后续循环完全在内存中进行,避免每次循环都调用find_element(这是耗时的核心原因)
  • 提前计算固定值:把today、buffer_date这类不会变化的值放在循环外计算,避免重复运算
  • 调整循环逻辑:先过滤掉不符合日期条件的单元格,再在有效范围内匹配系数,减少无效遍历
  • 简化异常处理:减少嵌套的try-except,避免不必要的性能损耗

修改后的代码

def __parse_full_page(self, url: str, data: dict = {}) -> bool:
    try:
        WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(Locator.PLAN)).click()
        cells = WebDriverWait(self.driver, 10).until(EC.visibility_of_all_elements_located(Locator.CELLS_TABLE))
        current_url = str(self.driver.current_url)
        id_ticket = current_url.split("&")[-2].split("=")[-1]
        button_planning = self.driver.find_element(*Locator.CONFIRM)

        ticket_data = tickets.get(id_ticket)
        max_rate = 0
        if ticket_data != "Заявка не найдена":
            _, max_rate = ticket_data.split(':')
            max_rate = int(max_rate)

        coefficients = ["Бесплатно"] + [f'✕{i}' for i in range(1, max_rate + 1)]
        
        # 提前计算固定日期值,避免循环内重复计算
        today = datetime.now()
        buffer_days = int(config["BOT"]["BUFFER"])
        buffer_date = today + timedelta(days=buffer_days)
        
        # 预提取并处理所有单元格数据到本地列表
        cell_data_list = []
        for cell in cells:
            try:
                # 一次性提取当前单元格的所有需要的数据
                date_text = cell.find_element(*Locator.DATE).text
                date_text_clean = date_text.split(',')[0].strip()
                date_object = datetime.strptime(date_text_clean, "%d %B").replace(year=today.year)
                coefficient_text = cell.find_element(*Locator.RATE).text.strip()
                # 保存单元格元素和处理后的数据
                cell_data_list.append({
                    "cell": cell,
                    "date_object": date_object,
                    "coefficient_text": coefficient_text,
                    "date_text": date_text
                })
            except ValueError as ve:
                print(f"Ошибка при преобразовании даты: {ve}")
                continue
            except Exception as e:
                print(f"Ошибка при извлечении данных ячейки: {e}")
                continue
        
        # 先过滤符合日期条件的单元格
        valid_cells = [item for item in cell_data_list if item["date_object"] > buffer_date]
        
        # 遍历系数,在有效单元格中查找匹配项
        for coefficient in coefficients:
            for item in valid_cells:
                if item["coefficient_text"] == coefficient:
                    try:
                        button_hover = item["cell"].find_element(*Locator.CHOOSE_HOVER)
                        self.action.move_to_element(button_hover).perform()
                        item["cell"].find_element(*Locator.CHOOSE).click()
                        self.action.move_to_element(button_planning).click().perform()
                        new_id_el = self.driver.find_element(*Locator.ID).text
                        new_id = new_id_el.strip()
                        logger.debug("ЗАЯВКА ПРОШЛА")
                        self.__pretty_log({"id_ticket": id_ticket, 'coefficient': coefficient, 'date': item["date_text"], "new_id": new_id})
                        return True
                    except Exception as e:
                        print(f"Ошибка при нажатии 'Выбрать': {e}")
                        continue

    except Exception as e:
        print(f"Ошибка: {e}")

    return False

优化效果说明

  • 原来的嵌套循环中,每个单元格要多次调用find_element(日期、系数、按钮),现在只在预提取时调用一次,后续都是内存操作,能把耗时从30秒压缩到1-2秒以内
  • 提前过滤无效日期的单元格,减少后续循环的遍历次数
  • 固定值只计算一次,避免重复运算

内容的提问来源于stack exchange,提问作者Dourfyt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:28:13