Node.js中Puppeteer无法捕获动态图片,如何获取图片URL?
问题描述
使用Puppeteer加载页面时,已通过page.goto()等待网络空闲,且成功找到图片选择器,但尝试获取图片URL时,始终返回Promise { <pending> }或[object Promise],无法拿到实际的图片地址。
原代码示例
const puppeteer = require('puppeteer'); var $url = "https://twitter.com/astro_greek/status/1754801971725312352"; const $selector_timeout = 5000; // default "selector wait" timeout const img_selector = 'img'; // [alt="Image"] (async () => { // Launch the browser and open a new blank page const browser = await puppeteer.launch({headless: false}); const page = await browser.newPage(); await page.goto($url , { waitUntil: 'networkidle2'}); // all dynamic items are loaded let image2 = await page.waitForSelector(img_selector, {timeout: $selector_timeout} ) .then(() => { console.log("Success with selector."); let image = page.$(img_selector) .then(()=>{ console.log("Image is caught."); page.$eval( img_selector, el => el.scrollIntoView()); let body = page.$(img_selector ) .then((el)=>{ console.log("typeof el: " + typeof el); console.log("Element outerHtml: " + el.getProperty('outerHTML')); console.log("Element innerHtml: " + el.getProperty('innerHTML')); console.log("Element href: " + el.getProperty('href')); }); console.log("Body: "); console.log(body); }).catch((err)=>{ console.log(err);}); console.log("Image: "); console.log(image); }).catch((err)=> { console.log("Failure to get tax info HTML element. ERR:", err); } ); console.log("Image 2: " + image2); await browser.close(); })();
原运行结果
Success with selector. Image: Promise { <pending> } Image 2: undefined Image is caught. Body: Promise { <pending> } Element: JSHandle@node Promise { <pending> } typeof el: object Element outerHtml: [object Promise] Element innerHtml: [object Promise] Element href: [object Promise]
问题原因分析
- 混用
async/await与.then(),导致异步操作未被正确等待,Promise始终处于pending状态 - 调用
el.getProperty()后未用await解析,直接打印Promise对象而非实际属性值 - 错误尝试获取
href属性,图片的实际地址存储在src(或srcset)属性中
修正后的代码与解决方案
const puppeteer = require('puppeteer'); const url = "https://twitter.com/astro_greek/status/1754801971725312352"; const selectorTimeout = 5000; const imgSelector = 'img[alt="Image"]'; // 精准选择目标图片,避免匹配无关元素 (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // 等待页面所有资源(包括图片)加载完成 await page.goto(url, { waitUntil: 'load' }); try { // 等待目标图片元素出现 await page.waitForSelector(imgSelector, { timeout: selectorTimeout }); // 方式1:直接在页面上下文获取图片src(简洁高效) const imgUrl = await page.$eval(imgSelector, el => el.src); console.log("图片URL:", imgUrl); // 方式2:通过元素句柄获取属性(适合需要多步元素操作的场景) const imgElement = await page.$(imgSelector); const srcProperty = await imgElement.getProperty('src'); const imgUrl2 = await srcProperty.jsonValue(); console.log("图片URL(方式2):", imgUrl2); } catch (err) { console.log("获取图片失败:", err); } await browser.close(); })();
关键注意事项
- 统一使用
async/await替代.then()嵌套,让异步逻辑更清晰,彻底避免Promise pending问题 getProperty()返回的是Promise对象,必须通过await解析后,再用jsonValue()获取实际属性值- 使用精准选择器(如
img[alt="Image"]),避免匹配页面中其他无关图片 - 若需确保图片完全加载,可将
page.goto()的waitUntil参数设为'load',等待所有资源加载完成
内容的提问来源于stack exchange,提问作者Igor Savinkin
相关产品推荐
相关产品推荐

