node写爬虫无法下载图片,可能逻辑有问题
发布于 2 个月前 作者 buleZia 495 次浏览 来自 问答

node初学,想爬一下图片下来,但是程序没有报错的情况下找不到问题在哪里,求解决

放一下程序结果 1505291373(1).png 以下是代码段 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后缀名,可以解析出有效对象),这部分可以改进

虽然解决了, 还是想说一句.

.on('error', function(e) {
	console.log("fail to downloads", e);
})

然后不就知道是什么 error 了…

回到顶部