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