node写爬虫无法下载图片,可能逻辑有问题
node初学,想爬一下图片下来,但是程序没有报错的情况下找不到问题在哪里,求解决
放一下程序结果 以下是代码段 curl.js
var http =require("http"),
https = require("https");
//to download an url
//callback with the data
function download(url, callback){
https.get(url, function(res){
var data="";
res.setEncoding("utf-8");
res.on('data', function(chunk){
data += chunk;
});
res.on("end", function(){
callback(data);
});
}).on("error", function(){
callback(null);
});
}
exports.download = download;
index.js
var cheerio = require("cheerio");
https = require("https"),
request = require("request");
fs =require("fs"),
path =require("path");
util = require('util')
var server = require("./curl");
var url = 'https://top.baidu.com/news?fr=topbuzz_b618_c9';
dir = 'D:/download';
//包装了模块就函数进行复写
server.download(url, function(data){
console.log(dir)
if(data){
//console.log(data);
var $= cheerio.load(data);
$('img').each(function(i, e){
//console.log($(e).attr('src'));
downImg($(e).attr("src"), dir)
})
}
});
//创建目录
function mkdirSync(){
fs.existsSync(dir) || fs.mkdirSync(dir);
return dir;
}
//下载图片
function downImg(url, dir){
var startTime = new Date().getTime();
url = encodeURI(url);
request(url).on('response', function(){
var endTime = new Date().getTime();
console.log("download..%s..%s",url, (endTime-startTime)/1000)
})
.pipe(fs.createWriteStream(path.join(url))
).on('error', function(){
console.log("fail to downloads");
});
}
7 回复
被反扒了吧
别的不说,英文写错了,不是 download… 是 downloading… ,不是 fail to downloads 是 failed to download。
下面这个捕获错误的代码删掉
on('error', function(){
console.log("fail to downloads");
})
得到
Error: ENOENT: no such file or directory, open 'yourpath\http:\top.bdimg.com\frontend\static\common\logo.png'
把 url 直接作为 文件路径了。然而改好后下载下来是 403,路漫漫,lz 加油。
我进不去你的url,但是得小心一个问题,比如
let url='https://www.baidu.com';
path.join(url)
//'https:/www.baidu.com'
path.join会吃掉一个/
@leavesdrift 这部分应该是作为文件夹名字的,其实从这里我就错了,谢谢
@ianchn 哈哈因为试了很多小demo,写快了就没太在意英文的问题了,暴露了我英文水平差了。 我改了以下代码和依赖
var http = require("http");
url = 'http://www.ivsky.com/tupian/ziranfengguang/'
.pipe(fs.createWriteStream(path.join(dir))
去掉on(‘error’, fn)依然对路径报错
Error: EISDIR: illegal operation on a directory, open 'D:\download'
,加上之后依然是failed to download
解决了。 .pipe(destination,[options]);,destination必须是可写入对象。 'D:\download’只是文件夹而不是对象。 因此要对fileName进行解析。
//下载图片
function downImg(url, dir){
var startTime = new Date().getTime();
url = encodeURI(url);
var fileName = url.split('/').pop();
request(url).on('response', function(){
var endTime = new Date().getTime();
console.log('downloading..%s..%ss', url, (endTime-startTime)/1000);
})
//rs.pipe(destination, [options]);
/**
* destination 必须一个可写入流数据对象
* [opations] end 默认为true,表示读取完成立即关闭文件;
*/
.pipe(fs.createWriteStream(dir + fileName)
)
.on('error', function(){console.log("failed to download");});
}
实际上还需要对文件类型进行判断,我仅仅是对切割后的数组进行提取(url中带了.jpg后缀名,可以解析出有效对象),这部分可以改进