Javascript抽取网页正文

标签: Javascript | 发表时间:2012-07-25 08:00 | 作者:Administrator
出处:http://www.scriptlover.com

最近在开发http://www.sokers.com的时候需要抽取网页正文,在网上也看了很多算法,但效果感觉都不好,有的根本打不开无法看到效果,于是自己就试着写了一个,效果还不错,支持图片和Flash,不仅仅能抽取文字。

方法就是适用打分机制,把正文文字和标签的比例、标点符号、换行等因素累加起来,打分最高的就是正文,当然肯定有识别不出来的,这个是任何算法都无法避免的。

感兴趣的同学可以看看,代码很短:

/**
*@Extract Content
*/
var extractor = {iframe: null, iDoc: null};
extractor.markExp = /[\,\.\?\:\;\-\'\!\"\(\)\[\]\{\}\,\。\‘\!\“\”\?\:\、]/g;
extractor.footExp = /(©?)|(All Rights Reserved)|(Powered By)|(备[0-9]{5,}号)/ig;

extractor.extract = function(html)
{
    if(!extractor.iDoc)
    {
        return "";
    }
    
    var arr = html.replace(/\r|\n/g, "").match(/<body(.*)<\/body>/i);
    if(!arr || !arr.length)
    {
        return "";
    }

    html = arr[0].replace(/<iframe.*?<\/iframe>/ig, "");
    html = html.replace(/<link.*?\/?>/ig, "");
    html = html.replace(/<!--.*?-->/g, "");
    html = html.replace(/<style.*?<\/style>/ig, "");
    html = html.replace(/<script.*?<\/script>/ig, "");

    html = html.replace(/<embed.*?\/?>/ig, function(data){
        return data.replace("<", "$1$").replace(">", "$2$");
    });
    html = html.replace(/<img.*?\/?>/ig, function(data){
        return data.replace("<", "$1$").replace(">", "$2$");
    });
    html = html.replace(/<object.*?<\/object>/ig, function(data){
        return data.replace("<", "$1$").replace(">", "$2$");    
    });

    extractor.iDoc.body.innerHTML = html;
    return extractor.process(extractor.iDoc.body);
};

extractor.getWordRatio = function(itemStr)
{
    var tagsCount = 0;
    var tags = itemStr.match(/<[^>]+>/g);
    if(tags && tags.length > 0)
    {
        tagsCount = tags.length;
    }
    
    var ratio = 0;
    var words = itemStr.replace(/<a.*?<\/a>/ig, "");
    words = words.replace(/<[^>]+>/g, "");
    if(tagsCount == 0 && words.length > 6)
    {
        ratio = 6;
    }
    else
    {
        var t = words.length/tagsCount;
        ratio = t > 6 ? 6 : t;
    }

    words = words.match(/\S/g);
    return [ratio, (words ? words.length : 0)];
};

extractor.getMarkRatio = function(itemStr)
{
    var items = itemStr.match(extractor.markExp);
    var length = items ? items.length : 0;
    if(length == 0)
    {
        return 0;
    }
    return length > 5 ? 3 : 1.5;
};

extractor.getLineRatio = function(itemStr)
{
    var items = (/<br ?\/?>/ig).test(itemStr);
    var length = items ? items.length : 0;
    if(length == 0)
    {
        return 0;
    }
    return length > 5 ? 2 : 1;
};

extractor.isFooter = function(itemStr)
{
    return extractor.footExp.test(itemStr);
};

extractor.process = function(body)
{
    var items = body.getElementsByTagName("div");
    if(!items)
    {
        items = body.getElementsByTagName("table");
    }

    if(!items)
    {
        items = body.getElementsByTagName("p");
    }

    if(!items)
    {
        return "";
    }
    
    var mostItemStr = null, mostRatio = 0, mostLength = 0;
    for(var i=0;i<items.length;i++)
    {
        var item = items[i];
        var itemStr = item.innerHTML;
        if(itemStr.length < 16)
        {
            continue;
        }

        var div = item.getElementsByTagName("div");
        if(div && div.length > 8)
        {
            continue;
        }

        var input = item.getElementsByTagName("input");
        if(input && input.length > 2)
        {
            continue;
        }
    
        var wordRatio = extractor.getWordRatio(itemStr);
        var lineRatio = extractor.getLineRatio(itemStr);
        var markRatio = extractor.getMarkRatio(itemStr);
        var isFooter = extractor.isFooter(itemStr);
        if(isFooter)
        {
            continue;
        }
        
        var ratio = wordRatio[0] + lineRatio + markRatio;
        var length = wordRatio[1];
        if(ratio >= mostRatio && length > mostLength)
        {
            //alert(wordRatio[0] +","+ length +","+ markRatio +","+ itemStr);
            mostRatio = ratio;
            mostLength = length;
            mostItemStr = itemStr;
        }
    }
    
    if(mostItemStr)
    {
        return mostItemStr.replace(/\$1\$/g, "<").replace(/\$2\$/g, ">");
    }

    return "";
};

extractor.init = function()
{
    if(extractor.iframe)
    {
        return;
    }

    extractor.iframe = document.createElement("iframe");
    extractor.iframe.src = "about:blank";
    extractor.iframe.style.display = "none";
    document.body.appendChild(extractor.iframe);

    extractor.iDoc = extractor.iframe.document;
    if(!extractor.iDoc)
    {
        extractor.iDoc = extractor.iframe.contentDocument;
    }
};

(function(){
    if(!document.body)
    {
        return;
    }
    extractor.init();
})();

相关 [javascript 网页] 推荐:

Javascript抽取网页正文

- - 脚本爱好者
最近在开发http://www.sokers.com的时候需要抽取网页正文,在网上也看了很多算法,但效果感觉都不好,有的根本打不开无法看到效果,于是自己就试着写了一个,效果还不错,支持图片和Flash,不仅仅能抽取文字. 方法就是适用打分机制,把正文文字和标签的比例、标点符号、换行等因素累加起来,打分最高的就是正文,当然肯定有识别不出来的,这个是任何算法都无法避免的.

Javascript网页截屏的方法

- - WebHek
最近我在研究开发一个火狐插件,具体的功能是将网页内容截屏并分享到微博上. 目前基本功能已经实现,大家可以在 @程序师视野 里看到用这个截图插件分享的微博的效果. 之前我曾写过 如何将canvas图形转换成图片和 下载canvas图像的方法,这些都是在为这个插件做技术准备. 技术路线很清晰,将网页的某个区域的内容生成图像,保持到canvas里,然后将canvas内容转换成图片,保存到本地,最后上传到微博.

Parse将推出Javascript SDK支持移动网页应用

- - CocoaChina移动观察
文/Kim-Mai Culter. 由美国知名创业孵化器Y Combinator支持的创业Parse曾为面向移动应用(如Band of the Day 和Hipmunk)提供后端支持,宣布将为移动网络应用提供支持. 这家位于旧金山的创业公司提供了面向JavaScript的SDK,实现更为方便的创建HTML5应用.

JavaScript解析:让搜索引擎看到更真实的网页

- - 搜索研发部官方博客
长期以来,站长们选择使用JavaScript来实现网页的动态行为,这样做的原因是多种多样的,如加快页面的响应速度、降低网站流量、隐藏链接或者嵌入广告等. 由于早期的搜索引擎没有相应的处理能力,导致在索引这类网页上往往出现问题,可能无法收录有价值的资源,也可能出现作弊. 引入JavaScript解析的目的,正是为了解决上述两方面的问题,其结果也就是使搜索引擎可以更为清晰的了解用户实际打开该网页时看到的效果.

iOS中UIWebView与其中网页的javascript的交互

- - ITeye博客
1.本地语言调js的方式与android中的方式类似,也是向WebView控件发送要调用的js语句. android和iOS对比,它们都用了伪url的技术,但android是在本地语言调js时使用了伪url(该url的schema为javascript),而iOS是js调本地语言时使用了伪url(该url是自定义的标识),这个错落很有意思.

Javascript诞生记

- Milido - 阮一峰的网络日志
二周前,我谈了一点Javascript的历史. 今天把这部分补全,从历史的角度,说明Javascript到底是如何设计出来的. 只有了解这段历史,才能明白Javascript为什么是现在的样子. 我依据的资料,主要是Brendan Eich的自述. "1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.

JavaScript,你懂的

- dylan - keakon的涂鸦馆
经常有人问我,JavaScript应该怎么学. 先学基本语法,如果曾学过C等语言,应该1小时内就能掌握了. 再去使用内置的函数、方法和DOM API,熟悉它能干什么;而在学习DOM API的过程中,你还不得不与HTML和CSS打交道. 然后弄懂匿名函数和闭包,学会至少一个常用的JavaScript库(例如jQuery).

Javascript 里跑Linux

- rockmaple - Shellex's Blog
牛逼到暴的大拿 Fabrice Bellard,用Javascript实现了一个x86 PC 模拟器,然后成功在这个模拟器里面跑Linux(请用Firefox 4 / Google Chrome 11打开,Chome 12有BUG). 关于这个东西… 伊说 “I did it for fun“,大大啊大大啊….

高效 JavaScript

- xtps - ITeye论坛最新讨论
传统上,网页中不会有大量的脚本,至少脚本很少会影响网页的性能. 但随着网页越来越像 Web 应用程序,脚本的效率对网页性能影响越来越大. 而且使用 Web 技术开发的应用程序现在越来越多,因此提高脚本的性能变得很重要. 对于桌面应用程序,通常使用编译器将源代码转换为二进制程序. 编译器可以花费大量时间优化最终二进制程序的效率.

你得学JavaScript

- 蒋冰 - 伯乐在线 -博客
  注:本文由 敏捷翻译 - 蒋少雄 翻译自 Kenny Meyers 的博文.   如果三年前你问我应该学什么语言,我会告诉你是Ruby.   如果你现在想学一门语言的话,你应该学习JavaScript..   我认为,每一位Web开发人员都应该学习JavaScript. 目前推出的许多新技术都支持这个观点.