使用Puppeteer.js调用谷歌翻译文档后下载文件未生效问题
问题:Puppeteer调用谷歌翻译文档后下载的仍是原文件
执行以下Puppeteer代码调用谷歌翻译处理Excel文件时,文件能正常上传、页面显示正在翻译,但下载完成后打开仍为原英文文件,未完成翻译:
const puppeteer = require('puppeteer'); (async () => { //let launchOptions = { headless: false, args: ['--start-maximized'] }; const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setViewport({width: 1366, height: 768}); const client = await page.target().createCDPSession(); await client.send("Page.setDownloadBehavior", { behavior: "allow", downloadPath: "C:\\Users\\pragyas\\Desktop\\downloaded", }); await page.goto( 'https://translate.google.com/?sl=en&tl=hi&op=docs', { waitUntil: "networkidle2", } ); await page.setDefaultTimeout(45000); const [fileChooser] = await Promise.all([ page.waitForFileChooser(), page.click("label"), ]); await fileChooser.accept(["C:\\Users\\pragyas\\Downloads\\Report_1667284876358.xlsx"]); await page.setDefaultTimeout(5000); const button = await page.waitForSelector( "#yDmH0d > c-wiz > div > div.WFnNle > c-wiz > div.R5HjH > c-wiz > div.oLbzv > c-wiz > div > div:nth-child(1) > div > div.ld4Jde > div > div > button > span"); await button.evaluate((b) => b.click()); const button2 = await page.waitForSelector( "#yDmH0d > c-wiz > div > div.WFnNle > c-wiz > div.R5HjH > c-wiz > div.oLbzv > c-wiz > div > div:nth-child(1) > div > div.ld4Jde > div > button > span.VfPpkd-vQzf8d", { visible: true, timeout: 0, } ); await button2.evaluate((b) => b.click()); })();
现象:上传后页面显示"正在翻译",下载的Excel文件打开后内容仍为英文,未转换为目标语言(印地语)。
排查与修复方案
- 替换不稳定的绝对选择器:代码中使用的多层级绝对选择器(
#yDmH0d > c-wiz > ...)极易失效,谷歌翻译页面结构频繁更新,很可能定位到错误的按钮。改用基于语义属性或文本的选择器,比如:- 上传按钮:
label[aria-label="上传文件"] - 下载按钮:
button:has-text("下载")(需确保Puppeteer支持has-text,或用page.waitForFunction判断按钮文本)
- 上传按钮:
- 等待翻译完成状态:当前代码未等待翻译真正完成就点击下载,页面显示"正在翻译"时,翻译后的文件尚未生成,此时下载会直接返回原文件。需等待页面出现翻译完成的标识:
- 等待按钮文本从"翻译"变为"下载"
- 等待翻译预览内容加载完成
- 调整超时与等待策略:
- 上传文件后不要将超时改为5000ms,大文件上传和翻译需要更长时间,建议保留至少30秒的超时,或使用
waitForFunction等待状态变化 - 启用有头模式调试:取消注释
launchOptions并设置headless: false,手动观察页面操作流程,确认按钮点击时机和定位是否正确
- 上传文件后不要将超时改为5000ms,大文件上传和翻译需要更长时间,建议保留至少30秒的超时,或使用
- 确保下载目录存在:Puppeteer不会自动创建下载目录,需提前用
fs模块创建,否则可能导致下载文件异常 - 修改后的示例代码:
const puppeteer = require('puppeteer'); const fs = require('fs'); (async () => { // 启用有头模式方便调试 const launchOptions = { headless: false, args: ['--start-maximized'] }; const browser = await puppeteer.launch(launchOptions); const page = await browser.newPage(); await page.setViewport({ width: 1366, height: 768 }); // 确保下载目录存在,不存在则创建 const downloadPath = "C:\\Users\\pragyas\\Desktop\\downloaded"; if (!fs.existsSync(downloadPath)) { fs.mkdirSync(downloadPath, { recursive: true }); } const client = await page.target().createCDPSession(); await client.send("Page.setDownloadBehavior", { behavior: "allow", downloadPath: downloadPath, }); await page.goto( 'https://translate.google.com/?sl=en&tl=hi&op=docs', { waitUntil: "networkidle2" } ); // 等待上传按钮并触发文件选择 await page.waitForSelector('label[aria-label="上传文件"]'); const [fileChooser] = await Promise.all([ page.waitForFileChooser(), page.click('label[aria-label="上传文件"]'), ]); await fileChooser.accept(["C:\\Users\\pragyas\\Downloads\\Report_1667284876358.xlsx"]); // 等待翻译完成:等待按钮显示"下载"(根据页面语言调整,英文界面用"Download") await page.waitForFunction(() => { const buttons = document.querySelectorAll('button'); return Array.from(buttons).some(btn => btn.textContent.includes('下载') || btn.textContent.includes('Download')); }, { timeout: 120000 }); // 最长等待2分钟,可根据文件大小调整 // 点击下载按钮 await page.click('button:has-text("下载")'); // 英文界面替换为:await page.click('button:has-text("Download")'); // 等待下载完成(可根据实际情况调整等待时间) await page.waitForTimeout(5000); await browser.close(); })();
内容的提问来源于stack exchange,提问作者Stella
相关产品推荐
相关产品推荐

