NodeJs抓取新聞正文和正文中的圖片

最新做一個新聞項目,項目流程很簡單,使用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地址

所以開發思路應該是這樣的,

  1.  http請求新聞url,得到新聞頁面的所有元素
  2.  在全文中查找新聞的正文
  3.  在正文中找到需要的圖片
現在使用代碼一步一步實現,
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界面訪問你抓取的新聞了。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章