最新做一个新闻项目,项目流程很简单,使用nodejs去网络上面抓取新闻,存到mongodb数据库,然后对客户端提供http服务。客户端的实现网上有很多源码,上一篇文字介绍了,怎么从rss地址抓取新闻的url地址和链接等等,未抓取新闻正文和新闻的概要图片。对于一个新闻客户端来说,没有图片是致命的打击,图文并茂才能吸引用户 。
本文来解决抓取正文和图片的问题。
上一篇文章 网络爬虫,使用NodeJs抓取RSS新闻
项目源码托管在github,欢迎一起进行维护和开发:github源码
本文拿网易新闻RSS服务进行测试和开发的。
对于这样一则新闻 url为:http://news.163.com/14/0304/10/9MG1UUF400014JB6.html
查看源码可知 正文包含在
<div id="endText">正文</div>
这样一对标签中。图片也在这个标签中<img src="">,src中的值,即为图片的url地址
所以开发思路应该是这样的,
- http请求新闻url,得到新闻页面的所有元素
- 在全文中查找新闻的正文
- 在正文中找到需要的图片
现在使用代码一步一步实现,
nodejs的http请求操作起来很简单,直接使用http库或者使用第三方的request库。开发的过程中,我遇到了一个棘手的问题,中文乱码。这个问题很坑爹,困扰了我n久
var request = require(‘request‘); var iconv = require(‘iconv-lite‘); var BufferHelper = require(‘bufferhelper‘) , FeedParser = require(‘feedparser‘) , Iconv = require(‘iconv‘).Iconv; var Post = require(‘../model/Post‘); var cheerio = require(‘cheerio‘); /**抓取网页全文源代码、主要用来抓取新闻正文 * @param url 需要抓取的url地址 * @param calback */ function fetchContent(url,calback){ var req = request(url, {timeout: 10000, pool: false}); req.setMaxListeners(50); req.setHeader(‘user-agent‘, ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36‘) .setHeader(‘accept‘, ‘text/html,application/xhtml+xml‘); req.on(‘error‘, function(err) { console.log(err); }); req.on(‘response‘, function(res) { var bufferHelper = new BufferHelper(); res.on(‘data‘, function (chunk) { bufferHelper.concat(chunk); }); res.on(‘end‘,function(){ var result = iconv.decode(bufferHelper.toBuffer(),‘GBK‘); calback(result); }); }); }
转换的技巧在于,使用buffer去转换,把收到的数据全部变成buffer字节数据。
正文已经得到了,即result。
正文截取的用到了一个html文件源码操作的神器
cheerio,它能让我像使用jquery一样方便快捷地操作抓取到的源码
举一个例子
var cheerio = require(‘cheerio‘), $ = cheerio.load(‘<h2 class="title">Hello world</h2>‘); $(‘h2.title‘).text(‘Hello there!‘); $(‘h2‘).addClass(‘welcome‘); $.html(); //=> <h2 class="title welcome">Hello there!</h2>就这么简单,
所以我截取出正文和图片的代码如下:
/** * 截取单个新闻的正文, * @param url 新闻的url地址 * @param tag 新闻在web界面开始的标签 如:<div id=‘content‘>新闻正文</div>。 content即为tag */ function getNewsContent(url,tag,callback){ console.log(url); fetchContent(url,function(htmlData){ var $ = cheerio.load(htmlData); var context = $(tag).html(); var img = $(tag).find("img")[0]; var imgPath ; if(img !== null){ imgPath = $(img).attr("src"); //新闻的缩略图 } console.log(url); console.log(imgPath); callback(context,imgPath); //回调新闻正文和图片 }); }
好啦 正文有了,图片也有了,标题也有了,新闻抓取基本搞定了。
====
你可以在配置文件中添加自己想抓取的站点和抓取的时间,运行代码,新闻就到了你的数据库了,你就可以直接在web界面访问你抓取的新闻了。