等待点击加载div完成后执行的英国站亚马逊发票批量下载脚本问题
亚马逊英国站订单发票批量下载脚本优化方案
存在问题说明
现有代码的核心问题是Promise链没有正确串联,内部异步操作未暴露到外层导致执行顺序混乱,同时固定时长的setTimeout无法适配网络/页面加载速度波动,容易出现元素未加载完成就执行后续逻辑的问题,这也是首个订单经常下载失败的核心原因。
优化后完整代码
// 配置项 const config = { checkInterval: 100, // 元素检测间隔(毫秒) maxWaitTime: 10000, // 单步最大等待时长(毫秒) afterDownloadWait: 1000 // 下载完成后等待时长(毫秒) }; // 工具函数:等待指定条件满足 function waitFor(conditionFn) { return new Promise((resolve, reject) => { const startTime = Date.now(); const timer = setInterval(() => { const result = conditionFn(); if (result) { clearInterval(timer); resolve(result); } else if (Date.now() - startTime > config.maxWaitTime) { clearInterval(timer); reject(new Error('等待超时')); } }, config.checkInterval); }); } // 获取订单卡片列表 const orderCards = Array.from(document.querySelectorAll("div.a-box-group.order.js-order-card")); const pdfReg = /\.pdf/gi; // 处理单个订单的函数 async function processSingleOrder(orderCard, index) { console.log(`开始处理第${index+1}个订单:${getOrderName(orderCard)}`); try { // 1. 点击发票按钮唤起弹窗 const invoiceBtn = orderCard.children[0].children[0].children[0].children[0].children[1].children[1].children[0].children[2].children[0]; invoiceBtn.click(); // 2. 等待弹窗加载完成 const popover = await waitFor(() => { const allPopovers = Array.from(document.querySelectorAll(".a-popover.a-popover-no-header.a-declarative.a-arrow-bottom")); // 找到刚打开的可见弹窗 return allPopovers.find(p => p.offsetParent !== null); }); // 3. 等待弹窗内PDF链接生成 const pdfLink = await waitFor(() => { const links = Array.from(popover.querySelectorAll(".a-link-normal")); return links.find(link => pdfReg.test(link.getAttribute('href'))); }); // 4. 打开PDF链接触发下载 window.open(pdfLink.getAttribute('href')); console.log(`第${index+1}个订单发票下载触发成功`); // 5. 关闭当前弹窗 const closeBtn = popover.querySelector(".a-button-close.a-declarative"); closeBtn?.click(); // 可选等待后再处理下一个 await new Promise(resolve => setTimeout(resolve, config.afterDownloadWait)); } catch (err) { console.error(`第${index+1}个订单处理失败:`, err); } } // 获取订单商品名 function getOrderName(orderCard) { try { const rightCol = orderCard.querySelectorAll(".a-fixed-left-grid-col.a-col-right")[0]; const itemLink = rightCol.querySelectorAll(".a-link-normal")[0]; return itemLink.innerHTML.trim(); } catch { return '未知商品'; } } // 主执行函数 async function run() { console.log(`共找到${orderCards.length}个订单,开始处理`); for (let i = 0; i < orderCards.length; i++) { await processSingleOrder(orderCards[i], i); } console.log('所有订单处理完成'); } // 执行 run();
使用说明
- 打开亚马逊英国站订单页面,等待页面完全加载
- 按下F12打开Chrome开发者工具,切换到Console标签页
- 粘贴上述代码按下回车即可自动执行
- 如果弹出弹窗拦截提示,请允许亚马逊站点的弹出窗口,否则无法触发下载
自定义调整说明
- 如果发票按钮选择器失效,可以自行修改
processSingleOrder函数内invoiceBtn的元素路径 - 可调整顶部
config内的时长参数适配你的网络环境 - 如需处理多页订单,可在
run函数末尾添加分页跳转逻辑
内容的提问来源于stack exchange,提问作者Lenniott
相关产品推荐
相关产品推荐

