""" 主程序 - 批量下载离散备料计划维护数据 """ from playwright.sync_api import sync_playwright from login import login import re import os import pandas as pd from time import sleep from utils.excel_converter import ExcelConverter def read_order_ids(file_path): """读取订单号文件""" with open(file_path, 'r', encoding='utf-8') as f: # 去除空白行和空格 order_ids = [line.strip() for line in f if line.strip()] return order_ids def group_order_ids(order_ids, group_size=100): """将订单号分组""" for i in range(0, len(order_ids), group_size): yield order_ids[i:i + group_size] def download_batch(inner_frame, order_ids, batch_index, page1, debug_mode=False, debug_batch=None): """下载一批订单号的数据""" # 清空文本框 textbox = inner_frame.get_by_role("textbox", name="来源生产订单号") textbox.fill("") # 填充订单号 textbox.fill(",".join(order_ids)) # 点击查询 inner_frame.locator(".search-component-searchBtn").click() print(f"第 {batch_index + 1} 批查询完成,等待加载结果...") # 等待加载完成 loading_locator = inner_frame.locator("div").filter(has_text="加载中").nth(1) try: loading_locator.wait_for(state="visible", timeout=3000) loading_locator.wait_for(state="hidden", timeout=0) # 无限等待,直到消失 except TimeoutError: # 加载很快完成,或者没有出现加载提示 pass print(f"第 {batch_index + 1} 批加载完成,开始选择数据...") # 调试模式:只在指定批次暂停 if debug_mode and (debug_batch is None or batch_index == debug_batch): print(f"=== 调试暂停:第 {batch_index + 1} 批 ===") page1.pause() # 选择所有数据 inner_frame.get_by_role("row", name="序号").get_by_label("").click() # 点击输出 inner_frame.get_by_role("button", name="更多").hover() inner_frame.get_by_text("输出", exact=True).click() # 设置行数阈值 input_box = inner_frame.locator("div").filter(has_text=re.compile(r"^行数阈值$")).locator("input[type='text']") input_box.fill("300000") # 下载文件 download_path = f"D:/python/playwrite/data/temp_batch_{batch_index + 1}.xlsx" with page1.expect_download() as download_info: inner_frame.get_by_role("button", name="确定(Y)").click() download = download_info.value download.save_as(download_path) print(f"第 {batch_index + 1} 批下载完成: {download_path}") # 关闭输出对话框(如果有的话) try: inner_frame.get_by_role("button", name="取消").click() except: pass # 等待页面恢复,准备下一次查询 import time time.sleep(1) return download_path def convert_and_merge_files(file_paths, output_path): """使用 ExcelConverter 转换并合并所有文件""" converter = ExcelConverter(verbose=False) # 不打印详细日志 all_dataframes = [] for i, file_path in enumerate(file_paths, 1): print(f"转换第 {i} 个文件: {file_path}") df = converter.convert(file_path, output_file=None) # 只转换,不保存 all_dataframes.append(df) print(f" 提取到 {len(df)} 条记录") if all_dataframes: print(f"\n合并 {len(all_dataframes)} 个文件的数据...") merged_df = pd.concat(all_dataframes, ignore_index=True) merged_df.to_excel(output_path, index=False) print(f"合并完成: {output_path}, 总共 {len(merged_df)} 条记录") # 删除临时文件 for file_path in file_paths: os.remove(file_path) print(f"已删除临时文件: {file_path}") return output_path return None def main(): with sync_playwright() as playwright: # 调用登录模块 browser, context, page, main_frame = login( playwright=playwright, username="BLDpengqiangqiang", password="Cqbld123456.", headless=False, ignore_https_errors=True ) # 登录成功后可以进行后续操作 # 点击打开"菜单" main_frame.locator("i").first.click() # 点击打开"离散备料计划维护" with page.expect_popup() as page1_info: main_frame.get_by_title("离散备料计划维护", exact=True).first.click() page1 = page1_info.value # 获取 nested iframe main_frame = page1.locator("#forwardFrame").content_frame inner_frame_locator = main_frame.locator("#mainiframe") inner_frame_locator.wait_for(state="visible", timeout=15000) inner_frame = inner_frame_locator.content_frame # 点击图标按钮打开查询界面 inner_frame.locator(".search-name-wrapper > .iconfont").click() inner_frame.get_by_text("订单号查询").click() inner_frame.get_by_role("tab", name="全部").click() # 填充并验证,如果失败则重试 max_retries = 3 expected_value = "5000" for attempt in range(max_retries): inner_frame.locator("#rc_select_0").fill(expected_value) inner_frame.locator("#rc_select_0").press("Enter") # 检查填充是否成功 actual_value = inner_frame.locator("#rc_select_0").input_value() if actual_value == expected_value: print(f"文本框填充成功: {expected_value}") break else: print(f"第 {attempt + 1} 次填充失败,实际值: {actual_value},重试...") if attempt == max_retries - 1: print(f"警告: {max_retries} 次尝试后仍未成功填充,继续执行...") # 读取订单号文件 order_id_file = os.path.join(os.path.dirname(__file__), "orderID.txt") order_ids = read_order_ids(order_id_file) print(f"共读取到 {len(order_ids)} 个订单号") # 确保 data 目录存在 data_dir = "D:/python/playwrite/data" os.makedirs(data_dir, exist_ok=True) # 按批次下载 downloaded_files = [] for batch_index, order_ids_batch in enumerate(group_order_ids(order_ids, 100)): print(f"\n=== 开始处理第 {batch_index + 1} 批,共 {len(order_ids_batch)} 个订单号 ===") downloaded_file = download_batch(inner_frame, order_ids_batch, batch_index, page1, debug_mode=False, debug_batch=None) downloaded_files.append(downloaded_file) # 转换并合并文件 if downloaded_files: print(f"\n=== 开始转换并合并 {len(downloaded_files)} 个文件 ===") final_output = "D:/python/playwrite/data/离散备料计划维护_合并.xlsx" convert_and_merge_files(downloaded_files, final_output) else: print("\n没有下载到任何文件") print(f"\n=== 全部完成 ===") print(f"最终文件: {final_output}") input("按回车退出...") # 关闭浏览器 context.close() browser.close() if __name__ == "__main__": main()