CNode

node写爬虫无法下载图片,可能逻辑有问题

问答
BbuleZia发布于9 年前最后回复9 年前7 回复5064 浏览0 收藏

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)

K
kan831019#1·9 年前

被反扒了吧

I
ianchn#2·9 年前

别的不说,英文写错了,不是 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 加油。

L
leavesdrift#3·9 年前

我进不去你的url,但是得小心一个问题,比如

let url='https://www.baidu.com';
path.join(url)
//'https:/www.baidu.com'
path.join会吃掉一个/
B
buleZia#4·9 年前
引用 leavesdrift我进不去你的url,但是得小心一个问题,比如 ``` let url='https://www.baidu.com'; path.join(url) //'https:/www.baidu.c...

@leavesdrift 这部分应该是作为文件夹名字的,其实从这里我就错了,谢谢

B
buleZia#5·9 年前
引用 ianchn别的不说,英文写错了,不是 download... 是 downloading... ,不是 fail to downloads 是 failed to download。 下面这个捕获错误的...

@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

B
buleZia#6·9 年前

解决了。 .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后缀名,可以解析出有效对象),这部分可以改进

Y
yinxin630#7·9 年前

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

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

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

参与回复
登录后即可参与回复。登录