URL不包含文件扩展名时,如何使用Node.js下载图像?

时间:2018-08-12 16:21:54

标签: node.js stream request

我正在Nodejs中构建一些Web爬虫。刮板可以做的一件事就是下载图像。一切都很好,直到我尝试抓取一个站点,该站点的图像在url中不包含文件扩展名,例如:https://example.com/images/someimagewithoutextension

这是我正在使用的小型库中的一些代码,用于下载和保存图像:

 options.encoding = null

request(options, (err, res, body) => {
if (err) {
  return onError(err, done)
}

if (body && (res.statusCode === 200 || res.statusCode === 201)) {
  if (!path.extname(options.dest)) {
    options.dest = path.join(options.dest, path.basename(options.url))
  }

  fs.writeFile(options.dest, body, 'binary', (err) => {
    if (err) {
      return onError(err, done)
    }

    if (typeof done === 'function') {
      done(false, options.dest, body)
    }
  })
} 

因此,当图片网址缺少扩展名时,我会收到如下错误:

  

错误:ENOENT:没有这样的文件或目录,请打开'C:\ Users \ someuser \ Desktop \ nodescraper \ images \ somefilename不带扩展名'

当我console.log()响应的“主体”时,我得到了一些Buffer数组(因此我无法检查mime类型或类似内容),并且据我了解,这表示流。当我从请求配置中删除encoding:null时,我得到了一组字符,但是节点实际上崩溃了。

我如何保存此类图像?

1 个答案:

答案 0 :(得分:1)

ENOENT

来自node.js docs

  

ENOENT(没有这样的文件或目录):fs操作通常引发该信息,以指示指定路径名的组件不存在-给定路径找不到任何实体(文件或目录)。

此外,如果文件名包含任何restricted characters(例如),则可能会发生此错误,因此建议删除或替换这些字符以确保您的应用正常运行。在npm上检查sanitize-filename软件包。

检测扩展名

HTTP Content-Type响应标头包含响应正文的mime-type。因此,您可以使用它来检测要下载的文件扩展名。例如,如果获得的内容类型为 image / jpeg ,则文件扩展名可以为 .jpeg 。 npm上还有一堆libraries,可以将mime类型转换为文件扩展名。

完整示例

const { writeFile } = require('fs');
const { extension } = require('mime-types');
const { basename, extname, join } = require('path');
const request = require('request');
const sanitize = require('sanitize-filename');

const dest = join(__dirname, 'images');
const url = '<URL>';

request({ url, encoding: null }, (error, response, body) => {
    if (error || response.statusCode < 200 || response.statusCode >= 300) {
        console.error('Request failed!');
        return;
    }

    let fileName = join(dest, sanitize(basename(url)));
    if (!extname(fileName)) {
        const contentType = response.headers['content-type'];
        const ext = extension(contentType);

        if (ext) {
            fileName += `.${ext}`;
        } else {
            console.error('Cannot detect file extension!');
        }
    }

    writeFile(fileName, body, (err) => {
        if (err) {
            console.error(err);
            return;
        }

        console.log('done');
    });
});