Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado
-
Upload
fernando-macedo -
Category
Technology
-
view
1.004 -
download
0
description
Transcript of Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado
![Page 1: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/1.jpg)
RASPADORMini-biblioteca para extração de dados em documentos semi-estruturados
![Page 2: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/2.jpg)
SOBRE MIMDesenvolvedor desde 2003Conheci Python em 2009Trabalho na NCR CorporationNa NCR, Python não é a linguagem primária
![Page 3: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/3.jpg)
Foi utilizado para extração de dados de Espelhos MFDVirou código de base do projeto
from raspador import history
![Page 4: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/4.jpg)
OUTRO PARSER?lxml (XPath, cssselectors)html5lib (html parser)BeautifulSoup (tree parser api)PyQuery (cssselectors)Scrapely (magia negra)Scrapy (crawler: request, responsing)pyparsing (grammar)NLTK (grammar)Plain Python + regex
![Page 5: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/5.jpg)
O QUE?Extrair dados de arquivos texto que não foram projetados paraisso.
![Page 6: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/6.jpg)
CNPJ: 40.100.280/0001-25 IE: 600020060001 IM: 36/3372 18/01/2013 11:07:04 CCF:002902 COO:007490 CUPOM FISCAL ITEM CÓDIGO DESCRIÇÃO QTD.UN.VL UNIT R$ ST VL ITEM R$ 001 1 prd1 1UN I1 1,00€ 002 2 prd2 Nincid 1UN N1 2,00€ 003 9999999999991 PIZZAS 1UN I1 14,33€Subtotal R$ 17,33ACRÉSCIMO +0,30€ TOTAL R$ 17,63Dinheiro 17,63------------------------------------------------MD5: A3BBE73BD09B18ECE607A50F92868A4E 02B 131B4 35A4E F59000 B6 59504C 72A1E 0669F 027ECF-IF VERSÃO:01.01.00 ECF:001 Lj: BBBBBBBBBBAABFCDEI 18/01/2013 11:07:06 FAB:XX000000000000207053 BR
![Page 7: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/7.jpg)
{ 'COO': 7490, 'CCF': 2902, 'Total': 17.63, 'Acrescimo': 0.30, 'Cancelado': False, 'Cancelamento': False, 'DataDeEmissao': datetime(2013, 01, 18, 11, 7, 4), 'NumeroDeSerie': 'DR0510BR000000207153', 'NumeroDoEcf': 1, 'Itens': [ { 'Item': 1, 'Codigo': '1', 'Descricao': 'prd1', 'Qtd': 1, 'Unidade': 'UN', 'Preco': 1, 'Total': 1, 'Cancelado': False, 'Aliquota': { 'Codigo': 'I1',
![Page 8: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/8.jpg)
PROBLEMAExtrair dados em documentos de texto
Texto sem marcaçãoArquivos grandes
Pequenas variações entre arquivosPrecisão na extração dos dados
![Page 9: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/9.jpg)
OPÇÕES?lxml (XPath, cssselectors)html5lib (html parser)BeautifulSoup (tree parser api)PyQuery (cssselectors)Scrapely (magia negra)Scrapy (crawler: request, responsing)pyparsing (grammar)NLTK (grammar)Plain Python + regex
![Page 10: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/10.jpg)
PLAIN PYTHON + REGEXFácil de escreverDifícil de manter
Write only code
![Page 11: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/11.jpg)
O que faz?
res = []for linha in entrada.splitlines(): if not linha: continue item = {} for parte in linha.split(): k, v = parte.split(':') item[k] = v res.append(item)
Você entende o código, mas não tem significado.
![Page 12: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/12.jpg)
REGULAR EXPRESSIONSSome people, when confronted with a problem,think "I know, I'll use regular expressions." Nowthey have two problems. (Jamie Zawinski, 1997)
![Page 13: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/13.jpg)
In []:
# O que isso faz?regex = "̂((([!#$%&'*+\-/=?̂_̀{|}~\w])|([!#$%&'*+\-/=?̂_{̀|}~\w][!#$%&'*+\-/=?̂_̀{|}~\.\w]{0,}[!#$%&'*+\-/=?̂_̀{|}~\w]))[@]\w+([-.]\w+)*\.\w+([-.]\w+)*)$"
Email validation - RFC 2821, 2822 compliant
![Page 14: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/14.jpg)
Não exagere
(Jeff Atwood)I love regular expressions
![Page 15: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/15.jpg)
OBJETIVOSReduzir complexidade
Incluir semânticaFavorecer composição
Código testável
![Page 16: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/16.jpg)
pessoa_parser.py
from raspador import Parserfrom raspador import StringField, IntegerField
class ParserDeInformacoesPessoais(Parser): Nome = StringField(r'Nome: (.*)') Idade = IntegerField(r'(\d+) anos')
A definição de um atributo e o tipo de dado agregam semântica
![Page 17: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/17.jpg)
pessoa.txt
Nome: Guido van Rossum
Guido van Rossum é um programador decomputadores dos Países Baixos que é maisconhecido por ser o autor da linguagem deprogramação Python. Wikipédia
Nascimento: 31 de janeiro de 1956 (57 anos),Países Baixos
Cônjuge: Kim Knapp (desde 2000)
Educação: Universidade de Amsterdã (1982)
Filho: Orlijn Michiel Knapp-van Rossum
Irmão: Just van Rossum
![Page 18: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/18.jpg)
pessoa_utilizacao.py
from pessoa_parser import ParserDeInformacoesPessoais
parser = ParserDeInformacoesPessoais()
with open('pessoa.txt') as f: for pessoa in parser.parse(f): print(pessoa.Nome) print(pessoa.Idade)
Guido van Rossum
57
![Page 19: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/19.jpg)
# parser.parse retorna um generatorwith open('pessoa.txt') as f: g = parser.parse(f) print(type(g)) print(next(g))
<type 'generator'>
Dictionary([('Nome', 'Guido vanRossum'), ('Idade', 57)])
![Page 20: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/20.jpg)
RASPADOR.ITEMclass Dictionary(OrderedDict): """ Dictionary that exposes keys as properties for easy read access. """ def __getattr__(self, name): if name in self: return self[name] raise AttributeError( "%s without attr '%s'" % (type(self).__name__, name))
![Page 21: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/21.jpg)
CAMPOS BUILT-INfrom raspador import ( BaseField, IntegerField, StringField, BooleanField, FloatField, BRFloatField, DateField, DateTimeField)
TODO: BRFloatField, definir sistema de localização.
![Page 22: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/22.jpg)
BASEFIELDsearch
>>> s = "02/01/2013 10:21:51 COO:022734">>> field = BaseField(search=r'COO:(\d+)')>>> field.parse_block(s)'022734'
![Page 23: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/23.jpg)
BASEFIELDinput_processor
>>> s = "02/01/2013 10:21:51 COO:022734">>> def double(value):... return int(value) * 2...>>> field = BaseField(r'COO:(\d+)', ... input_processor=double)>>> field.parse_block(s) # 45468 = 2 x 2273445468
![Page 24: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/24.jpg)
BASEFIELDis_list
>>> s = "02/01/2013 10:21:51 COO:022734">>> field = BaseField(r'COO:(\d+)', is_list=True)>>> field.parse_block(s)['022734']
Por convenção, quando o campo retorna uma lista, os valoresserão acumulados.
![Page 25: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/25.jpg)
DATEFIELDformat_string
>>> s = "2013-01-02T10:21:51 COO:022734">>> field = DateField(r'̂(\d+-\d+-\d+)', ... format_string='%Y-%m-%d')>>> field.parse_block(s)datetime.date(2013, 1, 2)
![Page 26: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/26.jpg)
PARSERResponsável por conduzir a iteraçãoPodem ser alinhados
![Page 27: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/27.jpg)
NEM TUDO QUE É TEXTO... está em texto
Dica:
Mantém a estrutura do arquivo gerado próxima com o original.
pdftotext
pdftotext -layout <arquivo.pdf>
![Page 28: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/28.jpg)
REGULAR EXPRESSIONSDebuggex: visualize suas REs
Aurélio
https://www.debuggex.com/
Expressões regulares, uma abordagem divertida
![Page 29: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/29.jpg)
COMPATIBILIDADECPython 2.6+
2.6: pip install ordereddictCPython 3.2+PyPy
![Page 30: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/30.jpg)
TESTESTestes automatizados com .
Bibliotecas de terceiros para os testes são instaladasautomaticamente no ambiente virtual da versão do Python:
tox
$ tox
nose==1.3.0 coverage==3.6 flake8==2.0
![Page 31: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/31.jpg)
É NOSSO
https://github.com/fgmacedo/raspador
https://pypi.python.org/pypi/raspador
https://raspador.readthedocs.org/
![Page 32: Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado](https://reader033.fdocumentos.tips/reader033/viewer/2022042508/5598f4a31a28ab4d5e8b47ed/html5/thumbnails/32.jpg)
OBRIGADO!Fernando Macedo
(Slides)
@fgmacedo
fgmacedo.com
http://code.fgmacedo.com/talks