用Node.js爬取图片的踩坑日志

1,529 阅读1分钟

最近写了个node小程序来爬取网页上的图片,不知道是不是我要抓取的内容是动态生成的,地址后缀是以.do结尾而不是以.png/.jpg结尾的原因,以为是个小case,没想到踩坑了!!!

在百度和bing上找了好久,都没找出来原因所在,后来换了种思路才解决,专门记下来给大家避雷!!!

以爬取png图片为例子,我原本的思路是axios.get请求图片地址,然后把返回内容保存下来。

大致如下:

const fs = require('fs');
axios.get(img_url, { responseType: Buffer })
            .then(async function (response) {
                let d = response.data;
                fs.writeFileSync(`${fileName}.png`, d);
            }).catch(e => {
                console.error(e);
            });

万万没想到,就这么短短几行的代码,踩到了天坑,图片显示不出来!

然后我先后把responseType改成了ArrayBufferString还是不行,然后在想,会是文件编码的问题吗?

writeFileSyncencoding乱改一通,从binaryascii试到utf16le都不行。

尼玛

然后开始上网找,先后安装了据说能够识别Buffer类型的FileType,识别我axios取回来的buffer显示undefined;安装了据说能够处理图片的shark,显示格式出错;安装了据说处理png图片很专业的pngjs,这个起码告诉我Error: Invalid file signature

image.png

用hexEditor可以看到编码(左:正常图,右:程序抓取)的确不一样。

行吧...然后试了n多方法,终于找到一种能行的!不用Buffer,直接用Stream!

        const writer = fs.createWriteStream(img_save_path)
        let response  = await axios.get(url, {
            responseType:"stream"
        })
        response.data.pipe(writer)

然后就可以了。

不知道为毛。