nodejs將PDF文件轉換成txt文本,並利用python處理轉換后的文本文件


目前公司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']}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM