我正在 Nodejs 中构建一些网络爬虫。刮板可以做的一件事是下载图像。一切都很好,直到我尝试抓取一个网站,该网站的图像不包含 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)
}
})
}
因此,当图像 URL 缺少扩展名时,我会收到如下错误:
错误:ENOENT:没有这样的文件或目录,打开“C:\Users\someuser\Desktop\nodescraper\images\somefilenamewithoutextension”
当我 console.log() 响应的“主体”时,我得到一些 Buffer 数组(因此我无法检查 mime 类型或类似的东西),据我所知,这表示一个流。当我从请求配置中删除 encoding:null 时,我得到一组字符,但节点实际上崩溃了。
我怎么能保存这样的图像?
来自node.js 文档:
ENOENT(没有这样的文件或目录):通常由 fs 操作引发,以指示指定路径名的组件不存在 - 给定路径找不到任何实体(文件或目录)。
此外,如果文件名包含任何受限制的字符,例如? ,因此建议删除或替换这些字符以确保您的应用程序运行时没有任何错误。检查npm 上的sanitize-filename包。
HTTP Content-Type响应头包含响应正文的mime-type。因此,您可以使用它来检测您正在下载的文件扩展名。例如,如果您获得image/jpeg的内容类型,则文件扩展名可以是.jpeg。npm 上还有一堆库可以将 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');
});
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句