nodejs初学,在学做一个网页爬虫,想请教如何用Nodejs将爬下来的html中的script、img、link、a等标签的外链也爬下来(保持更新直至制作成功)
发布于 7 天前 作者 SHocker-Yu 673 次浏览 最后一次编辑是 3 天前 来自 问答

3/7/2016 QQ截图20160317161217.png

这是经理帮我们分析的一个爬虫制作过程。

{OR%H2XB10LA.png 这是初步的访问html页面,但是这个跟直接查看源代码的效果是一样的。。。我们制作爬虫的目的是将一个网站的静态页面爬下来,改成我们自己要做的网站,我感觉我讲的都不清楚,请各位前辈帮忙分析一下我应该怎么入手

3/8/2016

目前进度做到分类(js/css/img)和下载

1.png

上图是其中的script分类,但是在下载的时候,由于这些js/css/imgt都是外链,下载的时候出现下图

2.png

目前正在寻找这解析外链的资料,感觉应该不难,有前辈提示吗?

现在是下午16:18,贴上目前的代码和进度 var http = require(‘http’); var cheerio = require(‘cheerio’); var request = require(‘request’); var path = require(‘path’); var fs = require(‘fs’); var url = ‘http://demos.q-themes.net/designr/v1.3/’;

request(url,function (error,response,body) { if(!error && response.statusCode == 200){ console.log(body); acquireData_3(body); } });

function acquireData_3 (data) { var $ = cheerio.load(data); //cheerio解析data var images = $(‘img[src]’).toArray(); console.log(images.length); var len = images.length;

for (var i=0;i<len;i++){ //console.log(images[i]); var imgsrc = images[i].attribs.src; console.log(imgsrc); var filename = parseUrlForFileName(imgsrc); downloadImg(imgsrc,filename,function() { console.log(filename+‘done’); }); } }

function parseUrlForFileName (address) {

var filename = path.join(‘http://demos.q-themes.net/designr/v1.3’,'address’);

return filename; }

var downloadImg = function (uri,filename,callback) { request.head(uri,function (err,res,body) { if(err){ console.log(‘err:’+err); return false; } console.log(‘res:’+res); request(uri).pipe(fs.createWriteStream(‘image/’+filename)).on(‘close’,callback); }); };

这段代码还是做不到下载外链,我的思路就是用 path.join 这个API来将外链地址组合起来,就是这段: function parseUrlForFileName (address) {

var filename = path.join(‘http://demos.q-themes.net/designr/v1.3’,'address’);

return filename;

** 但是我的写法肯定错了,有前辈帮忙指出来吗?还是我用的API不对?**

3/21/2016

天哪,刚刚复制时间的时候,我发现我居然是7号开始做的,也就是说我花了一个礼拜的时间还没做完。。。惭愧,得加油了! 下面是url组合成功的结果图

1.png

先忽略里面的err,可以看到地址已经拼接成功了,下面贴代码,用的组合方法是url.resolve(‘http://demos.q-themes.net/designr/v1.3/’,imgsrc);

function acquireData_3 (data) { var $ = cheerio.load(data); //cheerio解析data var images = $(‘img[src]’).toArray(); //contain img script console.log(images.length); var len = images.length;

for (var i=0;i<len;i++){ //console.log(images[i]); var imgsrc = images[i].attribs.src; console.log(imgsrc); var filename = url.resolve(‘http://demos.q-themes.net/designr/v1.3/’,imgsrc); console.log(filename); downloadImg(imgsrc,filename,function() { console.log(filename+’ 下载成功’); }); } }

var downloadImg = function (uri,filename,callback) { request.head(uri,function (err,res,body) { if(err){ console.log(‘err:’+err); return false; } console.log(‘res:’+res); request(uri).pipe(fs.createWriteStream(‘image/’+filename)).on(‘close’,callback); }); };

显然错误原因就是downloadImg方法中uri的路径还是imgsrc也就是没有拼接的地址,修改过几次不同的方式,但是都没成功,所以先继续看request的API,有前辈知道怎么改的话帮忙提出来,谢谢!

这是用组合出来的地址访问到的

1.png

这是目前的错误提示,图下面贴代码 1.png

function acquireData_3 (data) { var $ = cheerio.load(data); //cheerio解析data var images = $(‘img[src]’).toArray(); //contain img script console.log(images.length); var len = images.length;

for (var i=0;i<len;i++){ //console.log(images[i]); var imgsrc = images[i].attribs.src; console.log(imgsrc); var filename = url.resolve(‘http://demos.q-themes.net/designr/v1.3/’,imgsrc); //console.log(filename); var imgsrc_0 = url.resolve(‘http://demos.q-themes.net/designr/v1.3/’,imgsrc); console.log(imgsrc_0); downloadImg(imgsrc_0,filename,function() { console.log(filename+’ 下载成功’); }); } } var downloadImg = function (uri,filename,callback) { request(uri,function (err,res,body) { if(err){ console.log(‘err:’+err); return false; } console.log(‘res:’+res); request(uri).pipe(fs.createWriteStream(‘image/’+filename)).on(‘close’,callback); }); };

27 回复

nodejs可以用中间件node-jquery把抓过来的页面解析成html,然后有了jQuery你想干嘛都行的

@enmoon 我已经用jquery把页面解析成html了,但是html里面还有一些样式,脚本的是外链,我想把这些一起爬下来怎么写?

@SHocker-Yu 分三步的: 1、把爬下来的静态页面存起来 2、写一个分析器分析页面,并把相应资源归类整理 3、跑一个加载服务拉取这些资源

@SHocker-Yu 发送http请求,保存为文件就行了吧

先关注起。哈哈。

@enmoon 感谢,你这样一说我就明白很多了,知道该往哪方面搞

@thesadboy 因为很多网站的css,js都是外链,直接保存下来的是文本,没法用

@SHocker-Yu 就是发送请求,获取文件内容,存储为文件,然后修改抓回的html的js和css引用为本地就行了吧

@thesadboy 至于文本,不就是个后缀的问题么?

@thesadboy “然后修改抓回的html的js和css引用为本地就行了吧” 是这样的。。可是我抓来的js css都是地址,比如:css/bootstrap.min.css css/flexslider.css css/font-awesome.min.css 没有里面的详细内容,前辈指导一下方向,我现在 在看cheerio的API

@thesadboy @SHocker-Yu function acquireData_1 (data) { var $ = cheerio.load(data); var a = $(‘a[href]’).toArray(); console.log(a.length); var len = a.length;

for (var i=0;i<len;i++){

var asrc = a[i].attribs.href; console.log(asrc);

这是我抓取的代码,是不是var asrc = a[i].attribs.href; 这句不够用?

@thesadboy 找到了,应该是用url.resolve,对吗?因为我现在还是弄不出来完整的地址,但是我感觉就是它

@SHocker-Yu 在html中这种就是相对地址,通过你抓取的地址和这个相对路径就能得出实际地址,然后在抓取就行了,至于怎么组合,这个就很简单了吧?而且看你上面的结构基本应该就是类似于 http://xxx.xxx.xxx/js/xxx.jshttp://xxx.xxx.xxx/css/xxx.css 这样的,就很好组合了

@SHocker-Yu url.resolve 这个可以用,但是你要注意看怎样使用才能组合成能访问的地址,是在不行就自己写组合的代码就行了,应该也不是很难

@SHocker-Yu 这个地方应该是 $(‘script’).each() 和 $(‘link’).each() 来拿地址吧,然后再组合,就类似吧,可以试试

@thesadboy 这两天放假就没有来看了。。。上周五用url.resolve已经把地址组合成功了,上面放图,但是在下载的地方又出现了错误,错误提示信息和代码贴上面了,目前正在看request的API,再次感谢前辈!

@SHocker-Yu 都是相互学习,你可以看看你自己组合好的地址在浏览器是否访问

@thesadboy 看了一下地址,应该是你的下载的代码有问题

@thesadboy 可以用superagent试试

@thesadboy superagent正在看,看不太懂,上面贴了我新建一个变量imgsrc-0来表示组合完成后的地址,但是下面request.pipe方法是不是不能识别uri里用url.resolve方法弄出来的地址?

@SHocker-Yu 这样写试试?

/**
 * @file
 * @author Nick
 * @date 16/3/21
 */
"use strict";

var http = require('http'),
    fs = require('fs'),
    path = require('path');

var url = 'http://demos.q-themes.net/designr/v1.3/assets/projects/webdesign5.jpg';

var downloadImg = function (url, cb) {
    http.get(url, function (res) {
        res.pipe(fs.createWriteStream(path.join(__dirname, url.replace(/.*\//, ''))));
        res.on('end', cb);
    });
};

downloadImg(url, function () {
    console.log('done');
});

@thesadboy 赞,还能这样写!我的API基础太薄弱了,但是我就是想通过做的过程来熟悉,Nodejs的回调写法感觉叼爆了!

@SHocker-Yu 多写一些就好了,嘿嘿

@thesadboy 爬虫已经做的差不多了!十分感谢!怎么说呢,这次用Nodejs做爬虫来熟悉这门语言,我个人感觉效果很好!现在回头看文档,感觉轻松多了,我会继续学习这门语言,希望日后我也可以像你一样帮助到别人

@SHocker-Yu 客气了,都是相互学习

回到顶部