部分图片宽高显示undefined?如何获取无属性声明的图片尺寸
嘿,这个问题我太熟了!你用scraperjs的静态解析(比如CheerioScraper)的话,确实只能拿到HTML里写死的width/height属性,那些没声明的自然会返回undefined。要搞定这类图片的尺寸,得换个思路——用能模拟浏览器渲染页面的方式,因为图片的实际尺寸是要等浏览器加载完图片资源后才能拿到的。
scraperjs本身就带了PhantomJS的封装(PhantomScraper),它能启动一个无头浏览器,完整加载页面和图片,这样就能获取到图片的真实尺寸了。具体怎么做呢?
核心思路
PhantomScraper会渲染整个页面,加载所有图片资源,这时候我们可以通过DOM元素的naturalWidth和naturalHeight属性拿到图片本身的真实宽高——这俩属性不管HTML里有没有声明宽高,只要图片加载成功就能获取到。
代码示例
先确保你安装了scraperjs和phantomjs相关依赖(如果没装的话,先跑npm install scraperjs phantomjs-prebuilt),然后用下面的代码替换你原来的静态抓取逻辑:
const scraperjs = require('scraperjs'); // 替换成你要抓取的目标网站地址 const targetUrl = 'https://你的目标网站.com'; scraperjs.PhantomScraper.create(targetUrl) // 等待页面上的图片元素加载完成,避免过早获取尺寸 .waitFor('img') .scrape(function($) { // 遍历所有图片,收集尺寸信息 return $('img').map(function() { const imgElement = this; return { 图片地址: imgElement.src, // 优先取HTML里声明的宽高,没有就用真实加载的尺寸 宽度: imgElement.width ? parseInt(imgElement.width) : imgElement.naturalWidth, 高度: imgElement.height ? parseInt(imgElement.height) : imgElement.naturalHeight }; }).get(); }) .then(imagesInfo => { console.log('所有图片尺寸信息:', imagesInfo); }) .catch(err => { console.error('抓取过程出错:', err); });
额外优化点
如果遇到图片加载失败的情况,naturalWidth和naturalHeight会返回0,你可以加个判断标记出来,比如修改返回逻辑:
return { 图片地址: imgElement.src, 宽度: imgElement.width ? parseInt(imgElement.width) : (imgElement.naturalWidth > 0 ? imgElement.naturalWidth : '图片加载失败'), 高度: imgElement.height ? parseInt(imgElement.height) : (imgElement.naturalHeight > 0 ? imgElement.naturalHeight : '图片加载失败') };
为什么之前的静态抓取不行?
你之前用的应该是scraperjs的StaticScraper(基于Cheerio),它只解析静态HTML内容,不会加载任何外部资源(比如图片),所以那些没在HTML里写宽高的图片,自然拿不到尺寸。而PhantomScraper是真正模拟浏览器环境,会加载所有资源,才能获取到图片的真实属性。
内容的提问来源于stack exchange,提问作者OWRU

