黑马程序员技术交流社区

标题: 图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记 [打印本页]

作者: 专注的一批    时间: 2020-7-6 11:40
标题: 图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
准备工作

声明

要源码的请关注后留言

软件效果请看使用指南

所需模块:

模块简介

Tkinter:主要是 GUI 模块

pytesseract:图像转文字 API 接口

pdfminter3:读取 PDF 并转换成其他格式

pyhanlp:进行关键句提取

安装方法:

清华源 pip 走起:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytesseract

软件开发

图像转文本

在图像转文本 软件中,需要首先下载一个 tesseract 的开源,文本转图像工具。然后,通过 pytesseract 调用其 API,来实现图像识别文本(OCR)

tesseract 的下载地址

可以下载任意版本,这里推荐下载最新版本

API 使用代码

# coding: utf-8

import pytesseract

from PIL import Image

from tkinter import messagebox as mBox

import tkinter as tk

import os

def img2text(engine_path,img_path,text_path,Widget,lang):

pytesseract.pytesseract.tesseract_cmd = engine_path

mBox.showinfo('提示', '运行中,请耐心等待\n 文件越复杂,运行时间越久哦(关了吧,没关系的)')

text = pytesseract.image_to_string(Image.open(img_path),lang=lang)

with open(text_path+r'\output.txt', "w", encoding='utf-8') as f:

f.write(text)

f.close()

mBox.showinfo('提示', '运行完毕')

Widget.insert(tk.INSERT,text)

def img2text_TEST(engine_path,img_path,text_path):

pytesseract.pytesseract.tesseract_cmd = engine_path

text = pytesseract.image_to_string(Image.open(img_path),lang='chi_sim')

with open(text_path+r'\output.txt', "w", encoding='utf-8') as f:

f.write(text)

f.close()

mBox.showinfo('提示', '运行完毕')

if __name__ == '__main__':

engine_path = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

img_path = r'E:\java-2020-03\eclipse\workspace\Img2Txt\Input\test_math.jpg'

text_path = r'E:\java-2020-03\eclipse\workspace\Img2Txt\Output'

img2text_TEST(engine_path,img_path,text_path)

其他

可以尝试使用百度识图,里面也有相应的 API,不过一天只能使用有限次,所以这里不再采用。详细地,可以参照这篇博文:

https://blog.csdn.net/qq_38144563/article/details/96138470

其实,对于公式的识别,把他转成 latex,还有一个工具,具体是什么,请在评论区提问吧。不过,也是一个有限次使用的主。他的 API,因为某些无聊的原因,现在不对我国开放了,实在可惜。!!!!!
外汇经纪商买卖价https://www.fx61.com/quotesbuy.html

PDF 转文字

pdf 转文字用的是 pdfminer3,最近开发了 python3 版本。所以,网上的那些,都是用不了的,大家大可不一试,因为我试过了。有些模块已经被改了,所以也用不了。因此,就看我怎么写吧?

代码

# coding: utf-8

import argparse

import logging

import sys

import pdfminer3.settings

pdfminer3.settings.STRICT = False

import pdfminer3.high_level

import pdfminer3.layout

from pdfminer3.image import ImageWriter

import tkinter as tk

from tkinter import messagebox as mBox

def extract_text(files=[], outfile='-',

_py2_no_more_posargs=None,

no_laparams=False, all_texts=None, detect_vertical=None, # LAParams

word_margin=None, char_margin=None, line_margin=None, boxes_flow=None, # LAParams

output_type='text', codec='utf-8', strip_control=False,

maxpages=0, page_numbers=None, password="", scale=1.0, rotation=0,

layoutmode='normal', output_dir=None, debug=False,

disable_caching=False, **other):

if _py2_no_more_posargs is not None:

raise ValueError("Too many positional arguments passed.")

if not files:

raise ValueError("Must provide files to work upon!")

if not no_laparams:

laparams = pdfminer3.layout.LAParams()

for param in ("all_texts", "detect_vertical", "word_margin", "char_margin", "line_margin", "boxes_flow"):

paramv = locals().get(param, None)

if paramv is not None:

setattr(laparams, param, paramv)

else:

laparams = None

imagewriter = None

if output_dir:

imagewriter = ImageWriter(output_dir)

if output_type == "text" and outfile != "-":

for override, alttype in ( (".htm", "html"),

(".html", "html"),

(".xml", "xml"),

(".tag", "tag") ):

if outfile.endswith(override):

output_type = alttype

if outfile == "-":

outfp = sys.stdout

if outfp.encoding is not None:

codec = 'utf-8'

else:

outfp = open(outfile, "wb")

for fname in files:

with open(fname, "rb") as fp:

pdfminer3.high_level.extract_text_to_fp(fp, **locals())

return outfp

def trans(files, outfile):

mBox.showinfo('提示', '运行中,请耐心等待\n 文件越复杂,运行时间越久哦(关了吧,没关系的)')

outfp = extract_text(files=files,outfile=outfile)

outfp.close()

mBox.showinfo('提示ʾ', '运行完毕')

if __name__ == '__main__':

trans(files=['E:/java-2020-03/eclipse/workspace/Img2Txt/Fun/test.pdf'],outfile='output.html')

在运行代码的时候,注意删掉一些哈。

Tooltip

在 PDF 转文本哪里,用了一个弹出说明,我把代码封装成一个类了,希望以后能够用到:

# -*- coding: utf-8 -*-

import tkinter as tk

class Tooltip():

def __init__(self,widget):

self.widget = widget

self.tipwindow = None

self.id = None

self.x = self.y = 0

def showtip(self,text):

self.text = text

if self.tipwindow or not self.text:

return

x,y,_cx,cy = self.widget.bbox("insert")

x = x + self.widget.winfo_rootx()+27

y = y + cy + self.widget.winfo_rooty()+27

self.tipwindow = tw = tk.Toplevel(self.widget)

tw.wm_overrideredirect(1)

tw.wm_geometry("+%d+%d"%(x,y))

label = tk.Label(tw,text=self.text,justify=tk.LEFT,

background='#ffffe0',relief=tk.SOLID,

borderwidth=1,font=('tahma',"8","normal"))

label.pack(ipadx=1)

def hidetip(self):

tw = self.tipwindow

self.tipwindow = None

if tw:

tw.destroy()

def createToolTip(widget,text):

aTooltip = Tooltip(widget)

def enter(event):

aTooltip.showtip(text)

def leave(event):

aTooltip.hidetip()

widget.bind('',enter)

widget.bind('',leave)

关键句提取

这个很容易啦,直接用 pyhanlp 就行了。里面用的是 PageRank 算法,相当于 Google 的网页排名算法。

# -*- coding: utf-8 -*-

"""

Created on Thu May 7 14:52:32 2020

@author:

"""

from pyhanlp import *

from tkinter import messagebox as mBox

import tkinter as tk

def summary(text,num,Widget):

text_list = HanLP.extractSummary(text,num)

text = '\n'.join([t for t in text_list])

Widget.insert(tk.INSERT,text)

mBox.showinfo('提示', '运行完毕')

if __name__ == "__main__":

summary_list = summary('“芦花滩上有扁舟, 俊杰黄昏独自游, 义到尽头原是命, 反躬逃难必无忧。”\

这是一首出自《水浒传》中吴用留下的藏头反诗;电视剧《裂变》中汉奸“蝙蝠”也曾\

使用数字对应书本页面和文字的方法传递消息给日寇;电影《暗算》中更是提到了黄依\

依解决多种密文的具体情节;甚至连动画片《名侦探柯南》也出现了 skytale 加密的细\

节。事实上,密文不仅存在于荧幕中,而且深入到生活的方方面面,例如用于存储互联\

网消息的 cookie、以及互联网安全中常提到的数字签名、在银行等网站上填写个人信息\

时,都会用一定的手段将明文加密成密文传输到在远处的服务器中,可以说,在互联网\

的世界里,只要有比特流动,就一定会有加密的存在。为此,各大高校还设立了专门的\

学科,如密码学、密码分析学、密码史等。不得不说,密码的发展更数学密切相关、大\

多数的密码学家都兼任数学家的身份,而密码学,这一学科在战争时代更是快速地发展。\

以下将会介绍密码学的发展史、以及一些经典密码学的典型加密方法和其对应的解密方\

法的介绍、文章最后会简单地提及现代密码学的一些实现手段',5)

print(summary_list)

截图

在图像转文本哪里,我还内置了截图功能,代码如下:

# -*- coding:utf-8 -*-

import tkinter as tk

from tkinter import filedialog as fd

import os

from os import path

from PIL import ImageGrab

from time import sleep

class ScreenShot:

def __init__(self,master,filename):

self._createWidge(master, filename)

#变量X和Y用来记录鼠标左键按下的位置

def _onLeftButtonDown(self,event):

self._X.set(event.x)

self._Y.set(event.y)

#开始截图

self._sel = True

def _onLeftButtonMove(self,event):

if not self._sel:

return

try:

#删除刚画完的图形,要不然鼠标移动的时候是黑乎乎的一片矩形

self._canvas.delete(self._lastDraw)

except Exception as e:

pass

self._lastDraw = self._canvas.create_rectangle(self._X.get(), self._Y.get(),

event.x, event.y, outline='black',

width = 5)

def _onLeftButtonUp(self,event):

self.fileName = os.path.join(os.path.dirname(__file__),'../Input')

self._sel = False

try:

self._canvas.delete(self._lastDraw)

except Exception as e:

pass

sleep(0.1)

#考虑鼠标左键从右下方按下而从左上方抬起的截图

leftSel, rightSel = sorted([self._X.get(), event.x])

topSel, bottomSel = sorted([self._Y.get(), event.y])

pic = ImageGrab.grab((leftSel+1,topSel,rightSel+1,bottomSel))

#弹出保存截图对话框

fDir = os.path.join(os.path.dirname(__file__),'../Input') #���ϼ��ļ�Ŀ¼��

self.fileName = fd.asksaveasfilename(title='保存截图',

filetypes=[('JPG files','*.jpg')],

initialdir=fDir)

#默认的文件夹呀!!

if self.fileName:

pic.save(self.fileName)

pic.close()

#关闭当前窗口

#print(left, ' ', top,' ',right,' ',bottom)

self.top.destroy()

print(self.fileName)

sleep(1)

def _createWidge(self,master,filename):

self.fileName = os.path.abspath(os.path.join( os.path.dirname(__file__),".."))+'\Input'

self._X = tk.IntVar(0)

self._Y = tk.IntVar(0)

#屏幕尺寸

screenWidth = master.winfo_screenwidth()

#print(screenWidth)

screenHeight = master.winfo_screenheight()

#print(screenHeight)

#创建顶级组件容器

self.top = tk.Toplevel(master, width=screenWidth, height=screenHeight)

#不显示最大化、最小化按钮

self.top.overrideredirect(True)

self._canvas = tk.Canvas(self.top,bg='white', width=screenWidth, height=screenHeight)

#显示全屏截图,在全屏截图上进行区域截图

self._img = tk.PhotoImage(file=filename)

self._canvas.create_image(screenWidth//2, screenHeight//2,image=self._img)

#鼠标左键按下的位置

self._canvas.bind('', self._onLeftButtonDown)

#鼠标左键移动,显示选取的区域

self._canvas.bind('', self._onLeftButtonMove)

#获取鼠标左键抬起的位置,保存区域截图

self._canvas.bind('', self._onLeftButtonUp)

self._canvas.pack(fill=tk.BOTH, expand=tk.YES)

def buttonCaptureClick(master):

#最小化主窗口

master.state('icon')

sleep(0.5)

filename = 'screenShot.png'

im = ImageGrab.grab()

im.save(filename)

im.close()

#显示全屏幕截图

w = ScreenShot(master,filename)

os.remove(filename)

print(w.fileName)

return w.fileName

古文排版

所谓古文排版,就是将横的转为右起,竖的。实现代码如下:

# -*- coding: utf-8 -*-

import re

import tkinter as tk

from tkinter import messagebox as mBox

def cut_text(text,lenth):

textArr = re.findall('.{'+str(lenth)+'}', text)

textArr.append(text[(len(textArr)*lenth):])

return textArr

def verticalPrint(text,counts,Widget):

mBox.showinfo('提示', '运行中,请耐心等待\n 文件越复杂,运行时间越久哦(关了吧,没关系的)')

text = cut_text(text,counts)

text[-1] = text[-1].ljust(counts,' ')

cols = len(text)

text.reverse()

rows = []

for i in range(counts):

row = ''

for col in range(cols):

row += text[col][i]

rows.append(row)

text = '\n'.join(rows)

string = ''

for char in text:

if not char.isdigit() and not char==' ':

if (char >= u'\u0041' and char<=u'\u005a') or (char >= u'\u0061' and char<=u'\u007a'):

char += ' '

else:

pass

else:

char +=' '

string += char

Widget.insert(tk.INSERT,string)

mBox.showinfo('提示', '运行完毕')

if __name__ == '__main__':

x=u"凡是到达了的地方,都I want to die, but I still to my life 属于昨天。哪怕那山再青,那水再秀,那风再温柔。带深的流连便成了一种羁绊,\

绊住的不仅是双脚,还有未来。可我的钱不够[笑哭]"

# counts = 12

# string = verticalPrint(x,counts)

# print(string)





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2