设为首页 收藏本站
查看: 2426|回复: 0

[经验分享] NodeJS写个爬虫,把文章放到kindle中阅读

[复制链接]

尚未签到

发表于 2017-2-22 11:27:21 | 显示全部楼层 |阅读模式
  这两天看了好几篇不错的文章,有的时候想把好的文章 down 下来放到 kindle 上看,便写了个爬虫脚本,因为最近都在搞 node,所以就很自然的选择 node 来爬咯~
  本文地址:http://www.cnblogs.com/hustskyking/p/spider-with-node.html,转载请注明源地址。
  所谓爬虫,可以简单理解为利用程序操作文件,只是这些文件不在本地,需要我们拉取过来。

一. 爬虫代码解析

1. 拿到目标页码源码
  Node 提供了很多接口来获取远程地址代码,就拿 AlloyTeam 的页面举例吧,把他首页几篇文章的信息爬取过来。因为 AlloyTeam 使用的协议是 http:// ,本文就不介绍 Node 中 https:// 的使用了。



var http = require("http");
var url = "http://www.alloyteam.com/";
var data = "";
// 创建一个请求
var req = http.request(url, function(res){
// 设置显示编码
res.setEncoding("utf8");
// 数据是 chunked 发送,意思就是一段一段发送过来的
// 我们使用 data 给他们串接起来
res.on('data', function(chunk){
data += chunk;
});
// 响应完毕时间出发,输出 data
res.on('end', function(){
// dealData(data);
        console.log(data);
});
});
// 发送请求
req.end();
  上面短短七八行代码,就拿到了 AlloyTeam 首页的代码,真的十分简单,如果是 https:// 就得引用 https 模块咯,都是差不多的。

2. 正则提取目标内容
  先看下我们要抓取的内容:
DSC0000.png

  由于没有使用其他库,我们没办法像操作 DOM 一样获取目标内容,不过写正则也挺简单的,比如我们要 获取标题/文章链接/摘要 这些内容,正则表达式为:



// function dealData
var reg = /<ul\s+class="articlemenu">\s+<li>\s+<a[^>]*>.*?<\/a>\s+<a href="(.*?)"[^>]*>(.*?)<\/a>[\s\S]*?<div\s+class="text">([\s\S]*?)<\/div>/g;
var res = [];
while(match = reg.exec(data)) {
res.push({
"url": match[1],
"title": match[2],
"excerpt": match[3]
});
}
  这里的正则看起来有点晦涩,不过呢,正则在编程中十分基础的东西,如果没有太多的了解,建议先去搞清楚,这里就不细说啦。这里要强调的一点是:



reg.exec(data);
  如果只写上面这句话,只会拿到第一个匹配结果,所以需要使用 while 循环来处理,没处理一次,正则匹配的位置就会往后推一下。其实上面这条语句执行后返回的是一个对象,其中包含一个 index 属性,具体可以查阅 JavaScript 正则的内容。
  这里返回(res)的数据格式是:



[{
"url: url,
"title": title,
"excerpt" excerpt
}];
3. 数据的过滤
  上面虽然拿到了内容,不过我们需要的是纯文本,其他标签什么的得过滤掉,excerpt 中包含了一些标签:



var excerpt = excerpt.replace(/(<.*?>)((.*?)(<.*?>))?/g, "$3");
  虽说文章中有很多代码,有些标签是不应该删除的,不过这里是摘要内容,这些内容的标签都删除掉,方便我们储存。然后把长度处理下:



excerpt = excerpt.slice(0, 120);
4. 存到数据库(或者文件)
  我这里是把文件储存到文件之中,存放格式为:



[title](url)
> excerpt
  哈哈,很熟熟悉吧,markdown 语法,看起来也比较清晰。



var str = "";
for(var i = 0, len = data.length; i < len; i++){
str += "[" + data.title + "](" + data.url + ")\n" + data.excerpt.replace("\n\s*\n?", ">\n") + "\n\n";
}
  先拼接数据,然后写入到文件:



fs.writeFile('index.md', str, function (err) {
if (err) throw err;
console.log('数据已保存~');
});
  大功告成,过程其实是很简单的。拿到的内容(Linux 下,字体真丑!):
DSC0001.png


二. 源码与小结
  如果对正则不太熟悉,上面的工作是不太好完成的,很多开发者为 Node 提供了工具库,使用 npm 可以安装,如果不习惯正则,使用一些工具包辅助处理,可以把拿到的数据当作 DOM 来解析。
  我了解到的有一个叫做 node-jquery 的库貌似还不错,具体请读者自己去网上搜吧,应该挺多的。
  上面的代码都是随手写的,没有做什么容错的机制,也只爬取了首页的内容,不过思路都是一样的,拿到 URL 之后再写个循环,其他页面的内容也就到手了。
  源码没几行:


DSC0002.gif DSC0003.gif


var http = require("http");
var fs = require("fs");
var url = "http://www.alloyteam.com/";
var data = "";
var req = http.request(url, function(res){
res.setEncoding("utf8");
res.on('data', function(chunk){
data += chunk;
});
res.on('end', function(){
dealData(data);
});
});
req.on('error', function(e){
throw e;
});
req.end();
console.log("数据下载中...");

function dealData(data){
var reg = /<ul\s+class="articlemenu">\s+<li>\s+<a[^>]*>.*?<\/a>\s+<a href="(.*?)"[^>]*>(.*?)<\/a>[\s\S]*?<div\s+class="text">([\s\S]*?)<\/div>/g;
var res = [];
while(match = reg.exec(data)) {
res.push({
"url": match[1],
"title": match[2],
"excerpt": match[3].replace(/(<.*?>)((.*?)(<.*?>))?/g, "$3").slice(0,120)
});
}
writeFile(res)
}
function writeFile(data){
var str = "";
for(var i = 0, len = data.length; i < len; i++){
str += "[" + data.title + "](" + data.url + ")\n>" + data.excerpt.replace(/\n\s*\n?/g, "\n>") + "\n\n";
}
fs.writeFile('index.md', str, function (err) {                                                                                                
if (err) throw err;
console.log('数据已保存~');
});
}
爬虫源码 spider.js  在 node 环境中:



node spider.js
  就可以在同级目录下看到 index.md 文件了。至于如何放到 kindle 中,先了解下 OPF 格式,然后使用 Amazon 的 KindleGen 工具打包就行啦。

三. 参考资料


  • http://nodejs.org/api/fs.html
  • http://nodejs.org/api/http.html

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-345691-1-1.html 上篇帖子: NodeJS的代码调试和性能调优 下篇帖子: [原创]使用 NodeJS, MarkdownJS, PrettifyJS 打造个人博客写作平台
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表