RASPADOR

Mini-biblioteca para extração de dados em documentos semiestruturados
SOBRE MIM
Desenvolvedor desde 2003
Conheci Python em 2009
Trabalho na NCR Corporation
Na NCR, Python não é a linguagem primária
fo rsao ipr hsoy
rm apdr mot itr

Foi utilizado para extração de dados de Espelhos MFD
Virou código de base do projeto
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
O QUE?
Extrair dados de arquivos texto que não foram projetados para
isso.
CP:4.0.8/012
NJ 0102000-5

I:
E

602000
000601

I: 3/32
M
637
1/121 1:70
80/03 10:4
CF020 CO079
C:092 O:040
CPMFSA
UO ICL
IE CDG DSRÇOQDU.LUI R S V IE R
TM ÓIO ECIÃ T.NV NT $ T L TM $
011pd
0
r1
1NI 10€
U 1 ,0
022pd
0
r2
Nni
icd
1NN 20€
U 1 ,0
039999991PZA
0 999999 IZS
1NI 1,3
U 1 43€
Sboa R
uttl $
1,3
73
ARSIO
CÉCM
+,0
03€
TTL R
OA
$
1,3
76
Dner
ihio
1,3
76
----------------------------------------------M5 ABE3D91EE0A09884
D: 3B7B0B8C675F26AE
0B1143AEF90 B 554 7AE06F07
2 3B 54 500 6 90C 21 69 2
EFI
C-F
VRÃ:10.0
ESO0.10
EF01
C:0
L:
j
BBBBBABCE
BBBBBAFDI
1/121 1:70
80/03 10:6
FBX000000275
A:X000000003
B
R
{
'O' 79,
CO: 40
'C' 20,
CF: 92
'oa' 1.3
Ttl: 76,
'cecm' 03,
Arsio: .0
'acld' Fle
Cneao: as,
'aclmno:Fle
Cneaet' as,
'aaemsa' dttm(03 0,1,1,7 4,
DtDEiso: aeie21, 1 8 1 , )
'ueoeei' 'R50R000013,
NmrDSre: D01B000275'
'ueooc' 1
NmrDEf: ,
'tn' [
Ies:
{
'tm:1
Ie' ,
'oio:''
Cdg' 1,
'ecia' 'r1,
Dsrco: pd'
't' 1
Qd: ,
'ndd' 'N,
Uiae: U'
'rc' 1
Peo: ,
'oa' 1
Ttl: ,
'acld' Fle
Cneao: as,
'lqoa:{
Aiut'
'oio:'1,
Cdg' I'
PROBLEMA
Extrair dados em documentos de texto
Texto sem marcação
Arquivos grandes
Pequenas variações entre arquivos
Precisão na extração dos dados
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
PLAIN PYTHON + REGEX
Fácil de escrever
Difícil de manter
Write only code
O que faz?
rs=[
e
]
frlnai etaasltie(:
o ih n nrd.pilns)
i ntlna
f o ih:
cniu
otne
ie ={
tm
}
frprei lnaslt)
o at n ih.pi(:
k v=preslt''
,
at.pi(:)
ie[]=v
tmk
rsapn(tm
e.pedie)

Você entende o código, mas não tem significado.
REGULAR EXPRESSIONS
Some people, when confronted with a problem,
think "I know, I'll use regular expressions." Now
they have two problems. (Jamie Zawinski, 1997)
I [:
n ]
#Oqeis fz
u so a?
rgx="((!$&*/?_{}]|[#%'+-=^
ee
^([#%'+-=^`|~w)(!$&*/?_
`|~w[#%'+-=^`|~.w{,[#%'+-=^`
{}]!$&*/?_{}]0}!$&*/?_{
|~w)[]w(-]w)+[.+*$
}])@+[.+*.w(-]w))"

Email validation - RFC 2821, 2822 compliant
Não exagere
I love regular expressions (Jeff Atwood)
OBJETIVOS
Reduzir complexidade
Incluir semântica
Favorecer composição
Código testável
pessoa_parser.py
fo rsao ipr Pre
rm apdr mot asr
fo rsao ipr SrnFed Itgril
rm apdr mot tigil, neeFed
casPreDIfraosesasPre)
ls asrenomcePsoi(asr:
Nm =SrnFedrNm:(*'
oe
tigil('oe .))
Iae=Itgril('+ ao'
dd
neeFedr(d) ns)

A definição de um atributo e o tipo de dado agregam semântica
pessoa.txt
Nome: Guido van Rossum
Guido van Rossum é um programador de
computadores dos Países Baixos que é mais
conhecido por ser o autor da linguagem de
programaçã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
pessoa_utilizacao.py
fo pso_asripr PreDIfraosesas
rm esapre mot asrenomcePsoi
pre =PreDIfraosesas)
asr
asrenomcePsoi(
wt oe(pso.x' a f
ih pn'esatt) s :
frpso i pre.as()
o esa n asrpref:
pitpso.oe
rn(esaNm)
pitpso.dd)
rn(esaIae

Guido van Rossum
57
#pre.as rtrau gnrtr
asrpre eon m eeao
wt oe(pso.x' a f
ih pn'esatt) s :
g=pre.as()
asrpref
pittp()
rn(yeg)
pitnx()
rn(etg)

<ye'eeao'
tp gnrtr>
Dcinr((Nm' 'ud vn
itoay['oe, Gio a
Rsu',(Iae,5))
osm) 'dd' 7]
RASPADOR.ITEM
casDcinr(reeDc)
ls itoayOdrdit:
""
"
Dcinr ta epssky a poete fr
itoay ht xoe es s rpris o
es ra acs.
ay ed ces
""
"
df_gttr_sl,nm)
e _eat_(ef ae:
i nm i sl:
f ae n ef
rtr sl[ae
eun efnm]
rieAtiuero(
as trbtErr
"swtotat 's"%
% ihu tr %'
(yesl)_nm_,nm)
tp(ef._ae_ ae)
CAMPOS BUILT-IN
fo rsao ipr (
rm apdr mot
BsFed Itgril,
aeil, neeFed
SrnFed Boenil,
tigil, olaFed
Fotil,BFotil,
laFed RlaFed
DtFed DtTmFed
aeil, aeieil)

TODO: B F o t i l , definir sistema de localização.
RlaFed
BASEFIELD
search
>>s="20/031:15
>
0/121 02:1
CO023"
O:274
>>fed=BsFedsac='O:+'
> il
aeil(erhrCO(d))
>>fedpreboks
> il.as_lc()
'274
023'
BASEFIELD
input_processor
>>s="20/031:15
>
0/121 02:1
CO023"
O:274
>>dfdul(au)
> e obevle:
..
.
rtr itvle *2
eun n(au)
..
.
>>fed=BsFedrCO(d),
> il
aeil('O:+'
..
.
iptpoesrdul)
nu_rcso=obe
>>fedpreboks #448=2x274
> il.as_lc()
56
23
448
56
BASEFIELD
is_list
>>s="20/031:15
>
0/121 02:1
CO023"
O:274
>>fed=BsFedrCO(d),i_itTu)
> il
aeil('O:+' sls=re
>>fedpreboks
> il.as_lc()
[023'
'274]

Por convenção, quando o campo retorna uma lista, os valores
serão acumulados.
DATEFIELD
format_string
>>s="030-21:15
>
21-10T02:1
CO023"
O:274
>>fed=DtFedr^+++'
> il
aeil('(d-d-d),
..
.
fra_tig'Y%-d)
omtsrn=%-m%'
>>fedpreboks
> il.as_lc()
dttm.ae21,1 2
aeiedt(03 , )
PARSER
Responsável por conduzir a iteração
Podem ser alinhados
NEM TUDO QUE É TEXTO
... está em texto
pdftotext
Dica:
pfoet-aot<ruv.d>
dttx lyu aqiopf

Mantém a estrutura do arquivo gerado próxima com o original.
REGULAR EXPRESSIONS
Debuggex: visualize suas REs
https://www.debuggex.com/
Aurélio
Expressões regulares, uma abordagem divertida
COMPATIBILIDADE
CPython 2.6+
2.6: pip install ordereddict
CPython 3.2+
PyPy
TESTES
Testes automatizados com tox.
$tx
o

Bibliotecas de terceiros para os testes são instaladas
automaticamente no ambiente virtual da versão do Python:
ns=130
oe=..
cvrg=36
oeae=.
fae=20
lk8=.
É NOSSO
https://github.com/fgmacedo/raspador
https://pypi.python.org/pypi/raspador
https://raspador.readthedocs.org/
OBRIGADO!
Fernando Macedo
@fgmacedo
fgmacedo.com
fgmacedo@gmail.com
http://code.fgmacedo.com/talks (Slides)

Raspador: Biblioteca em Python para extração de dados em texto semi-estruturado