----- Mensaje original -----
De: "Manuel A. Estevez Fernandez" <[email protected]>
Para: "La lista de python en castellano" <[email protected]>
Enviados: Lunes, 2 de Junio 2014 17:50:02
Asunto: Re: [Python-es] Analizar cadena y extraer valores

Muchas gracias por tu aportación Luis, si me pudieras compartir tu código te lo 
agradecería mucho. Porque de momento estoy jugando todavía a prueba y error con 
la interpretación del texto extraído. 

------------
No sé si la lista admite adjuntos.
Envío el módulo principal y un ejemplo de uso. Ten en cuenta que este módulo 
trabaja con el fichero html que se genera con pdftotext a partir del pdf.
Yo lo estoy empleando para leer facturas y generar un json con los datos

El código de uso sería algo así:

from ocr.utilspdf import PdfTextInfo
from extra import debug, fechas
import json
import os.path

        hInfo = PdfTextInfo(ficheroHtml)
        self.json = {}
        j = self.json
        j['002.pdf.pagDesde'] = 1
        j['002.pdf.pagHasta'] = hInfo.totalPaginas
        j['010.factura'] = hInfo.getTextoEnXY(1, 70.8, 216.352)
        j['021.fIniFact'] = 
fechas.YMD(fechas.dd_mm_aa2date(hInfo.getTextoEnXY(1, 70.8, 317.632)))
        p = hInfo.getNumpag(70.8, 126.416, 'ENDEREZO')
        j['040.direccion'] = hInfo.getTextoEnRegion(p, (70.8, 134.032, 300, 
142.888))

La clase PdfTextInfo está definida en el módulo utilspdf que adjunto.
El método getTextoEnXY devuelve la palabra que tiene exactamente esas 
coordenadas en la esquina superior izquierda.
El método getTextoEnRegion recoge el texto que se encuentra en las esquinas que 
se le pasen.
Hay algunos métodos que quizá no te hagan falta, como obtener el total de 
páginas o preguntar en qué página se encuentra tal texto en tal posición.

Si tienes alguna pregunta no tendré problema en contestar: por aquí (si la 
lista está de acuerdo) o por el correo privado.
# -*- coding: ISO-8859-1 -*
'''
Created on 07/03/2012

@author: luis
'''
import os
import codecs
from extra import debug
import subprocess
from HTMLParser import HTMLParser

pdfTextInfo = None 
FORMATO_IDX = "%d^%.3f^%.3f" # página, coordX, coordY

class AnalizadorHtml(HTMLParser):
	def setPage(self, page):
		self.page = page
		
	def handle_starttag(self, tag, attrs):
		for attr in attrs:
			setattr(self, attr[0], attr[1])
			
	def handle_data(self, data):
		self.word=data.strip()
		
	def getInfo(self):
		return (self.page, float(self.xmin), float(self.ymin), 
			float(self.xmax), float(self.ymax), self.word)
	
	def getIdx(self):
		return FORMATO_IDX % (self.page, float(self.xmin), float(self.ymin))
	
class PdfTextInfo:
	def __init__(self, html):
		self.html = html
		self.totalPaginas = 0
		analizador = AnalizadorHtml()
		self.palabras = []
		self.dict = {};
		for lin in codecs.open(html, encoding='utf-8'):
			lin = lin.strip()
			if lin.startswith("<page "):
				self.totalPaginas += 1
				analizador.setPage(self.totalPaginas)
			if lin.startswith("<word "):
				analizador.feed(lin)
				# Añadimos a la lista 
				self.palabras.append(analizador.getInfo())
				# Añadimos al diccionario (accede más rápido por coordenadas)
				self.dict[analizador.getIdx()] = analizador.getInfo()
		# Ahora ordenamos por pag, yMin, xMin
		self.palabras.sort(key=lambda w: (w[0], w[2], w[1]))
		
	def getNumpag(self, pX, pY, texto):
		'Indica en qué página está el texto pasado'
		for pag in range(1, self.totalPaginas+1):
			if self.getTextoEnXY(pag, pX, pY) == texto:
				return pag
	
	def getInfoTexto(self, texto):
		for w in self.palabras:
			if w[5] == texto:
				return w
		
	def getTextoEnXY(self, pPag, pX, pY):
		idx = FORMATO_IDX % (pPag, pX, pY)
		return self.dict[idx][5] if idx in self.dict else None
	
	def getTextoEnRegion(self, pPag, pReg):
		res = ""
		for w in self.palabras:
			(pag, xMin, yMin, xMax, yMax, palabra) = w
			if pag > pPag:
				return res.strip()
			if pag == pPag:
				if xMin >= pReg[0] and yMin >= pReg[1]:
					if xMax <= pReg[2]+1 and yMax <= pReg[3]+1:
						res += " "+ palabra
				if yMin > pReg[3]:
					return res.strip()
		return res.strip()
		
	def getCoordenadasDeTexto(self, pPag, texto):
		for w in self.palabras:
			(pag, xMin, yMin, xMax, yMax, palabra) = w
			if pag > pPag:
				return None
			if pag == pPag and palabra == texto:
				return xMin, yMin
			
_______________________________________________
Python-es mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a