用JavaScript实现对PDF的全文索引

2013-10-15 09:12:46 | 新闻来源:叶凡网络 | 点击量:1221

某些人就可能会将其作为一种潜在廉价且拥有无限制处置能力的资源来加以利用,如果一种交通资源在现代浏览器上面运行。即使是出于整合索引的目的尽管必需针对系统的自然不稳定性做出规定。

能够从逾越两亿分份PDF文档中提取文本并对 其进行索引,曾今在一个售卖法律和财务数据库访问方案(称之为“智能信息”公司工作。大多数法庭记录都是通过PA CER以PDF形式提供的一 个站点被特地开发进去用于发布法庭记录。基于这个数据集的一个意义重大的数据库产品需要建立一条处理管道。展示美国超越20年的诉讼记录。这些处置过程将花费数月的机器时间,使得软件工作组在构建它时的面临很大的压力。这一处置过程中的早期有 个一步骤是从电子文档化的PDF中提取出内容,其在稍后的将会被送入一个NLP处置阶段—显示关键字,标注局部词类,识别实体,而然后发出演讲(如果你对此感兴趣,可以检索Python中的自然语言处置 作为入门 -再读一读这里我评论  

 

这一项目的野心令人印象深刻:一个浏览器中仅仅使用Javascript来对PDF进行渲染。PDF文档的结构令人难以置信的复杂,Mozilla实验室最近已经收到许多为一个项目做出的尝试。因此要祝pdf.j工作组的兄弟们好运了另外一条不同的尝试道路上,OliverNightingale使用Javascript实现了一个的Javascript全文索引装置—将这两个项目结合起来,就可以在web浏览器中完全再现PDF处置管道。

全文索引能用户可以搜索非结构化的文档,站在一名新手的角度来看。也可以依据由词频决定的相关度分值来对结果文档进行排名。索引装置会计算每一个份文档中 每一个词出现的次数,并且对文本进行最轻微的修改,以移除内容中跟搜索无关的一些文本语法特性。例如,可能会提取出“-ing将元音局部变卦为一般 表示形式。如果一个词语频繁呈现在整个文档集中,索引装置会自动将其识别为不那么重要的关键词,而它对排名结果的影响将会被最小化。这同GooglPageRank面前的基本概念是不同的后者是基于一个引征图来提升文档排名的

 

但如果是大规模装置的话,大多数数据库软件都提供了对全文索引的支持。通常会使用功能更加强大的工具来进行处理。开源产品中主要是Solr/LucenSolr围绕Lucen库封装的一个web应用。都是用Java编写的

终端用户机或者加密存储的用户数据这些之前很难实现搜索功能的地方成为可能。有一整个领域只研究加密的搜索指数,构造一个Javascript全文索引装置使得搜索在诸如Phonegap引用。而在客户机上对数据进行索引和加密看上去像是围绕这个天生具有挑战性的问题想出的一个好办法。

首先来看看如何从PDF中提取文本,为了测试这个处置管道。这些文本将在稍后被插入到一个全文索引中。pdf.j代码是很有启发性的其中Mozilla开发者们使用了一些并不常用的浏览器特性,举个例子,Web工作者,会要你设置后台的处置线程。

 

 

pdf.jAPI大量使用约定来持有代码中未完成操作的引用。会使用回调来对它进行操作:

var pdf = PDFJS.getDocu'http://www.pacer.gov/documents/pacermanual.pdf'; 

  •   var pdf = PDFJS.getDocu'pacermanual.pdf'; 
  • pdf.thenfunctionpdf {  // this code is called once the PDF is ready 
  • }; 

    但现在那还是不可用的这样的API看起还不怎么幼稚—理想情况下你应该能够写出 promise.thenfx.thengx.thenhx 等等代码。

    因为它为并行的渲染处置留下了空间。对于只是从一份PDF中提取出文本感觉上好像有大量的工作要做—必需相信你回调会依照秩序运行并且跟踪到哪个是最后。约定模式在渲染PDF方面起了很大的作用。

    并在浏览器中控制台日志中输出下面的示例代码演示了提取PDF内容.:

    use strict; 
  • var pdf = PDFJS.getDocu'http://www.pacer.gov/documents/pacermanual.pdf';   
  • var pdf = PDFJS.getDocu'pacermanual.pdf'; pdf.thenfunctionpdf { 
  •  var maxPages = pdf.pdfInfo.numPages;  for var j = 1; j <= maxPages; j++ { 
  •     var page = pdf.getPagj;   
  •     // the callback function - we create one per page     var processPageText = function processPageTextpageIndex { 
  •       return functionpageData, cont {         return functiontext { 
  •           // bidiTexts has a property identifying whether this           // text is left-to-right or right-to-left 
  •           for var i = 0; i < text.bidiTexts.length; i++ {             str += text.bidiTexts[i].str; 
  •           }   
  •           if pageData.pageInfo.pageIndex ===                maxPages - 1 { 
  •             // later this will insert into an index             console.logstr; 
  •           }         } 
  •       }     }j; 
  •       var processPage = function processPagpageData { 
  •       var content = pageData.getTextCont;   
  •       content.thenprocessPageTextpageData, cont;     } 
  •       page.thenprocessPag; 
  •  } }; 

    需要非常理解PDF命令(PDF可能使用流渲染命令,这并不会识别页眉和图片.如何识别这些内容需要使用渲染代码.类似于RTF

    Lunr

    以下是一个简单的AIP示例创建一个Lunr函数直接添加字段-所有的API都使用JSON类型.

    doc1 = { 
  •     id: 1,     title: 'Foo', 
  •     body: 'Foo foo foo!'   }; 
  •   doc2 = { 
  •     id: 2,     title: 'Bar', 
  •     body: 'Bar bar bar!'   }  
  •   doc3 = { 
  •     id: 3,     title: 'gary', 
  •     body: 'Foo Bar bar bar!'   } 
  •   index = lunrfunction  { 
  •     this.field'title', {boost: 10}     this.field'body' 
  •     this.ref'id'   } 
  •   // A dd documents to the index 
  • index.adddoc1 index.adddoc2 
  • index.adddoc3 

    一个简单的方法可以查询索引,搜索也很方便.因为它只是一个JS对象:

    // Run a search 
  • index.searchfoo   
  • // Inspect the actual index to see which docs match a term index2.tokenStore.root.f.o.o.docs 

    对他所谓的"文档"有所迷惑-包括了一个PDF或者一个办公文档以及任何一个数据库,当我第一次接触全文索引.很可能包括大堆的文本.

    全文索引将会是愚蠢的而Lunr则使索引自身的序列化和反序列化变得真正简单起来:如果你不得不时刻构建索引。

    var serializedIndex = JSON.stringifiindex1.toJSON 
  • var deserializedIndex = JSON.parsserializedIndex var index2 = lunr.Index.loaddeserializedIndex 

    只带有需要被序列化的数据。Index.toJSON也会返回一个“bean风格的对象(而不是一个string历来没有见过像这样的API但是喜欢这个创意—给了一个干净的Javascript对象。

    下面是索引的属性:

    • corpusToken– 已经排好序的token列表
    • documentStor– 每一份文档的列表 – 系
    • field– 用来描述每一份文档的域 类似于数据库中列)
    • pipelin– 用来处理token管道对象
    • tokenStor– 每一份文档中关键词呈现的位置和频率

    然后作为一个map-reduc作业被整合。上述对象只有三个条目需要被整合,这种索引最棒的一个特性是作业可以并行完成。因为“域”和“管道”静态的下面就展示了再现方法的实现(注意jQueri被引入了

    function reduca, b {  
  •   var j1 = a.toJSON;    var j2 = b.toJSON; 
  •     // The "unique" function does uniqueness by sorting, 
  •   // which we need here.   var corpusTokens =  
  •       $.uniqu           $.merg 
  •               $.merg[], j1.corpusToken,                             j2.corpusToken; 
  •     // It's important to create new arrays and 
  •   // objects throughout, or else you modify    // the source indexes, which is disastrous. 
  •   var documentStore =       {store: $.extend{},  
  •                       j1.documentStore.store,                       j2.documentStore.stor, 
  •       length: j1.documentStore.length + j2.documentStore.length};   
  •   var jt1 = j1.tokenStore;   var jt2 = j2.tokenStore; 
  •     // The 'true' here triggers a deep copy 
  •   var tokenStore = {     root: $.extendtrue, {}, jt1.root, jt2.root, 
  •     length: jt1.length + jt2.length   }; 
  •     return {version: j1.version, 
  •           fields: $.merg[], j1.field,            ref: j1.ref,  
  •           documentStore: documentStore,            tokenStore: tokenStore, 
  •           corpusTokens: corpusTokens,            pipeline: $.merg[], j1.pipelin};  
  • }index1, index2 

    需要简单的改变:通过创建三个索引我测试了这段代码:index1index2和index3index1{doc1}index2{doc2doc3}而index3则是{doc1doc2doc3}为了测试这段代码。

    JSON.stringifiindex3.toJSON 
  •   JSON.stringificombinindex1, index2 

    可能性

    ebai和fiberr上待售清单上充斥着“网络交通流量”叫卖,总的来说这项技术很浪费网络I/O使得这看起来很傻。从另外一方面来看。通常来自背 后弹出式广告,僵尸网络,隐藏的ifram等等。能很容易的发现像“3美元20000次点击”列表,小批量的因为没有多少商业价值它通常是很便宜 此外还得犯下各种形式的欺诈行为。

    以及公共可用的数据—不能将其作为一项针对浏览器跨域请求保护的搜刮技术。也需要使用一种独特的方式来生成单独的文档ID也许要使用到原生的URL需要一个便宜点的VM负载作为一个代理的带宽。

     

     

  • 上一篇:日媒:武器出口三原则名存实亡 新标准亟待建立 下一篇:关注微信公众平台了解更多功能!