nodejs将PDF文件转换成txt文本,并利用python处理转换后的文本文件 – Boom__Clap – 博客园

来源: nodejs将PDF文件转换成txt文本,并利用python处理转换后的文本文件 – Boom__Clap – 博客园

目前公司Web服务端的开发是用Nodejs,所以开发功能的话首先使用Nodejs,这也是为什么不直接用python转换的原因。

由于node对文本的处理(提取所需信息)的能力不强,类似于npm上的包:‘linebyline’、’lineReader’,处理能力都不强,所以使用python来处理。

 

目的:提取PDF中带有‘检查’字样的文本(行)

思路:

1、Nodejs 找到PDF转换text的包,转换,将text文本信息发送到Python服务器。

2、创建一个简单的Python服务器,接收并处理text文本,得到所需要的文本信息,打包成Json并发送到Node服务端。

3、Node服务端接收到后,再发给前端页面将信息展示。

 

好,那首先我们要去npm官网上找到转换用的包,pdf-textstring是一个不错的包,测试之后,大部分PDF都可以成功转换成text文本,但是有个别文件转换不成功,所以还需要换一个,最后是使用了’pdf2json‘这个包,在npm 上找包,有一个要点,就是包名很短,功能很多,类似的处理功能会集中在某个包上,但是包名可能只是其中一种功能。

 

PDF文件样本:

 

转换代码:

复制代码
 var fs = require('fs'),
     PDFParser = require("pdf2json");

 var pdfParser = new PDFParser(this, 1);
pdfParser.loadPDF("tmp/testpdf.pdf");
pdfParser.on("pdfParser_dataError", errData => console.error(errData.parserError)); pdfParser.on("pdfParser_dataReady", pdfData => {
     data = pdfParser.getRawTextContent()
     console.log(‘文本信息:’+data)
 });
复制代码

 

转换后的文本信息:

复制代码
操作任务: 3号主变压器带10kVB、C母全部负荷,2号主变压器停电,2号主变压器、162-2隔 
 
 
 
离开关、170、802断路器由运行状态转换为检修状态,110kVB母由运行状态转换为检修状态 
 
 
 
顺序 操 作 项 目 √ 时间 
1 投入10kVB、C母分段820闭锁备自投压板   
2 退出10kVB、C母分段820备投跳803压板   
3 退出10kVB、C母分段820备投合820压板   
4 检查2、3号主变压器分头位置一致   
5 合上820断路器   
6 检查820断路器确带负荷   
7 检查2号、3号主变压器负荷分配正常   
8 拉开802断路器   
9 检查802断路器在分闸位置   
10 检查3号主变压器不过负荷   
11 合上12中0中性点接地刀闸   
12 检查12中0中性点接地刀闸在合闸位置   
13 检查802断路器在分闸位置   
14 将802-3手车由运行位置拉至试验位置   
15 检查802-3手车到位指示正确   
16 将802手车由运行位置拉至试验位置
复制代码

 

Node服务端将转换后的文本信息发送到Python服务端:

复制代码
//Node发送数据并接受返回的处理后的数据

PDFPARSER(data, function(err, result) {
var test = unescape(result.replace(/\\u/g, ‘%u’))//解python端传来的unicode
res.send(ERRCODE.MakeResult(ERRCODE.OK, JSON.parse(test)));//JSON.parse一次,将解后的字符串换转成Json,发给前端
return;

});

//发送数据的函数

var PDFPARSER = function (reqData, callback) {
    var buf = new BUFFER.Buffer(reqData);
    var op = {
        host: "127.0.0.1",
        port: 8087,
        method: 'POST',
        path: "/",
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': buf.length
        }
    };

    var req = HTTP.request(op, function (res) {
        var recvData = "";

        res.on('data', function (chunk) {
            recvData += chunk.toString();
        });

        res.on('end', function () {

            if (callback) {
                callback(null, recvData);
            }

        });
    });

    req.on('error', function (e) {
        console.log(e);
    });

    req.write(reqData);

    req.end();
};
复制代码

 

Python服务端接受并处理、返还数据:

复制代码
import sys 
import codecs
import SimpleHTTPServer
import SocketServer
import json
import re
from urlparse import urlparse
from urlparse import parse_qs

PORT = 8087

class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def do_GET(self):
        pass#print self.headers
        
    def do_POST(self):
        #print self.headers
        
        contentLength = int(self.headers["Content-Length"])

        textString = self.rfile.read(contentLength)
        s = textString.split("\n")

        test = []
        for fileLine in s:
            if u'检查' in fileLine:
                line_pattern =r'\s*\d+\s?(.*)'
        
                def func(text):
                    c = re.compile(line_pattern)
                    lists = []
                    lines = text.split('\n')
                    for line in lines:
                        r = c.findall(line)
                        if r:
                            lists.append(r[0])
        
                    return '\n'.join(lists)
        
                
                result = func(fileLine)
                test.append(result)
        print test
                
        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()
        #print result.decode("utf-8")
        #print result
        test = {"CZBZ": test}
#这里test的格式是因为前端页面接收数据的格式需要
        self.wfile.write(json.dumps(test) )
                
        

        



if __name__ == "__main__":
    reload(sys)
    sys.setdefaultencoding("utf-8")
    httpd = SocketServer.TCPServer(("", PORT), Handler)
    print "serving at port", PORT
    httpd.serve_forever()
复制代码

 

Python处理后的数据:

复制代码
{"CZBZ":['\xe6\xa3\x80\xe6\x9f\xa52\xe3\x80\x813\xe5\x8f\xb7\xe4\xb8\xbb\xe5\x8f\x98\xe5\x8e\x8b\xe5\x99\xa8\xe5\x88\x86\xe5\xa4\xb4\xe4\xbd\x8d\xe7\xbd\xae\xe4\xb8\x80\xe8\x87\xb4   \r', '\xe6\xa3\x80\xe6\x9f\xa5820\xe6\x96\xad\xe8\xb7\xaf\xe5\x99\xa8\xe7\xa1\xae\xe5\xb8\xa6\xe8\xb4\x9f\xe8\x8d\xb7   \r', '\xe6\xa3\x80\xe6\x9f\xa52\xe5\x8f\xb7\xe3\x80\x813\xe5\x8f\xb7\xe4\xb8\xbb\xe5\x8f\x98\xe5\x8e\x8b\xe5\x99\xa8\xe8\xb4\x9f\xe8\x8d\xb7\xe5\x88\x86\xe9\x85\x8d\xe6\xad\xa3\xe5\xb8\xb8   \r', '\xe6\xa3\x80\xe6\x9f\xa5802\xe6\x96\xad\xe8\xb7\xaf\xe5\x99\xa8\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa53\xe5\x8f\xb7\xe4\xb8\xbb\xe5\x8f\x98\xe5\x8e\x8b\xe5\x99\xa8\xe4\xb8\x8d\xe8\xbf\x87\xe8\xb4\x9f\xe8\x8d\xb7   \r', '\xe6\xa3\x80\xe6\x9f\xa512\xe4\xb8\xad0\xe4\xb8\xad\xe6\x80\xa7\xe7\x82\xb9\xe6\x8e\xa5\xe5\x9c\xb0\xe5\x88\x80\xe9\x97\xb8\xe5\x9c\xa8\xe5\x90\x88\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5802\xe6\x96\xad\xe8\xb7\xaf\xe5\x99\xa8\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5802-3\xe6\x89\x8b\xe8\xbd\xa6\xe5\x88\xb0\xe4\xbd\x8d\xe6\x8c\x87\xe7\xa4\xba\xe6\xad\xa3\xe7\xa1\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5802\xe6\x89\x8b\xe8\xbd\xa6\xe5\x88\xb0\xe4\xbd\x8d\xe6\x8c\x87\xe7\xa4\xba\xe6\xad\xa3\xe7\xa1\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5170\xe6\x96\xad\xe8\xb7\xaf\xe5\x99\xa8\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5170-2\xe9\x9a\x94\xe7\xa6\xbb\xe5\xbc\x80\xe5\x85\xb3\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5170-3\xe9\x9a\x94\xe7\xa6\xbb\xe5\xbc\x80\xe5\x85\xb3\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5162-3\xe9\x9a\x94\xe7\xa6\xbb\xe5\xbc\x80\xe5\x85\xb3\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5162-2\xe9\x9a\x94\xe7\xa6\xbb\xe5\xbc\x80\xe5\x85\xb3\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5170-2\xe9\x9a\x94\xe7\xa6\xbb\xe5\xbc\x80\xe5\x85\xb3\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5170-20\xe6\x8e\xa5\xe5\x9c\xb0\xe5\x88\x80\xe9\x97\xb8\xe5\x9c\xa8\xe5\x90\x88\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5170-3\xe9\x9a\x94\xe7\xa6\xbb\xe5\xbc\x80\xe5\x85\xb3\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5170-30\xe6\x8e\xa5\xe5\x9c\xb0\xe5\x88\x80\xe9\x97\xb8\xe5\x9c\xa8\xe5\x90\x88\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa51B9\xe9\x9a\x94\xe7\xa6\xbb\xe5\xbc\x80\xe5\x85\xb3\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa51B90\xe6\x8e\xa5\xe5\x9c\xb0\xe5\x88\x80\xe9\x97\xb8\xe5\x9c\xa8\xe5\x90\x88\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa5162-2\xe9\x9a\x94\xe7\xa6\xbb\xe5\xbc\x80\xe5\x85\xb3\xe5\x9c\xa8\xe5\x88\x86\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r', '\xe6\xa3\x80\xe6\x9f\xa51B10\xe6\x8e\xa5\xe5\x9c\xb0\xe5\x88\x80\xe9\x97\xb8\xe5\x9c\xa8\xe5\x90\x88\xe9\x97\xb8\xe4\xbd\x8d\xe7\xbd\xae   \r']}
复制代码
分享到:更多 ()