+
    jej
                        R t ^ RIt^ RIt^ RIHt ^ RIHt ]P                  ! ]4      t	Rt
]
R,           tRtRtRtR	t]P                   ! R
]P"                  ]P$                  ,          4      t]P                   ! R]P"                  ]P$                  ,          4      t]P                   ! R4      t ! R R]4      tR R ltR R ltR R ltRR R lltR R ltRR R lltR# )u  SICAE — Sistema de Informação da Classificação Portuguesa de Actividades Económicas.

Fonte oficial do CAE Rev.4, gratuita e sem quota. Substitui o ptdata, que
morreu (503) e era de onde vinha o CAE.

Portado de `funcoes/empresa_nif_api.php` do Sabichão, que faz esta agregação em
produção há meses. Preservam-se duas decisões de lá que não são óbvias:

* **O NIF aparece duas vezes na resposta** — na linha de resultado e no `<input>`
  da pesquisa, porque o WebForms reescreve o valor submetido. Só contam as
  ocorrências dentro de `<td>`, senão qualquer pesquisa "encontra" o NIF.
* **Não encontrar não é erro.** É o caso normal para NIFs de pessoa singular ou
  entidades sem CAE registado. O sinal de "o site mudou" é dado noutro sítio —
  quando o formulário deixa de ter o `__VIEWSTATE` ou o campo do NIPC. Se o
  alarme fosse no parse, cada "não encontrado" seria um falso alarme e afogava
  o sinal verdadeiro.
N)Any)build_clientzhttp://www.sicae.pt/zConsulta.aspxzctl00$MainContent$ipNipczctl00$MainContent$ipFirmazctl00$MainContent$ipCaezctl00$MainContent$btnPesquisaz<tr[^>]*>(.*?)</tr>z<td[^>]*>(.*?)</td>z<[^>]+>c                       ] tR t^'tRtRtR# )SicaeFormChangedu@   O formulário do SICAE mudou; o scraping precisa de ser revisto. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       app/scrapers/sicae.pyr   r   '   s    Jr   r   c                R    V ^8  d   QhR\         R\        \         \         3,          /#    htmlreturn)strdict)formats   "r   __annotate__r   +   s"      # $sCx. r   c                 ,   / p\         P                  ! R V \         P                  4       Fg  p\         P                  ! RV4      p\         P                  ! RV4      pV'       g   K;  V'       d   VP	                  ^4      MRWP	                  ^4      &   Ki  	  V# )z <input[^>]*type=\"hidden\"[^>]*>zname="([^"]+)"zvalue="([^"]*)" )refindallIsearchgroup)r   outtagnamevalues   &    r   _hiddenr#   +   sn    Czz=tRTTJyy*C0		,c2438QbC

1	 K
 Jr   c                F    V ^8  d   QhR\         R\        \         ,          /# )r   row_htmlr   )r   list)r   s   "r   r   r   5   s      S T#Y r   c           
          ^ RI p. p\        P                  V 4       F]  p\        P	                  RV4      pVP                  \        P                  ! RRVP                  V4      4      P                  4       4       K_  	  V# )    N z\s+)	r   _CELL_REr   _TAG_REsubappendr   unescapestrip)r%   _htmlr   celltexts   &    r   _cellsr3   5   sa    
C  *{{3%

266&#u~~d';<BBDE + Jr   c                h    V ^8  d   QhR\         R\        \        \         \        3,          ,          /# r   r   r&   r   r   )r   s   "r   r   r   ?   s'      c d4S>2 r   c                `   . p\         P                  V 4       EF  p\        V4      p\        V4      ^8  d   K!  \        P
                  ! RRV^ ,          4      p\        V4      ^	8w  d   KR  V^,          ;'       g    Rp\        P
                  ! RRV^,          4      ;'       g    Rp\        V4      ^8  d.   V^,          '       d   \        P                  ! RV^,          4      M. pV'       g   V'       g   K  TP                  RTRTRTR	R
P                  V4      ;'       g    R/4       EK  	  V# )zCLinhas de resultado -> [{nipc, denominacao, cae, cae_secundarios}].\D+r   Nz[^0-9]z\d{4,5}nipcdenominacaocaecae_secundariosz, )_ROW_REr   r3   lenr   r,   r-   join)r   r   rowvalsr8   denomr:   secss   &       r   _parse_rowsrC   ?   s     "Ct$c{t9q=vvfb$q'*t9>Q4ffYDG,4425d)a-DGGrzz*d1g.QSS

us!499T?#:#:d		
 %( Jr   c          	      t    V ^8  d   QhR\         R\         R\        \        \         \        3,          ,          /# )r   r8   firmar   r5   )r   s   "r   r   r   Y   s.     # # # #d4S>6J #r   c                   "   \        R R7      ;_uu_4       GRj  xL
 pVP                  \        4      G Rj  xL
 pVP                  4        \	        VP
                  4      pRV9  g   \        VP
                  9  d!   \        P                  R4       \        R4      h/ VCRRRR\        V \        V\        R\        R	/CpVP                  \        VR
\        RR/R7      G Rj  xL
 pVP                  4        \        VP
                  4      uuRRR4      GRj  xL
  #  EL L L@ L  + GRj  xL 
 '       g   i     R# ; i5i)g      4@)timeoutN__VIEWSTATEu@   SICAE: o formulário de Consulta.aspx mudou — scraping a reveru   formulário do SICAE alterado__EVENTTARGETr   __EVENTARGUMENT	PesquisarRefererzContent-Typez!application/x-www-form-urlencoded)dataheaders)r   getCONSULTAraise_for_statusr#   r2   F_NIPCloggererrorr   F_FIRMAF_CAEF_BTNpostrC   )r8   rE   clientpagehiddenrM   rs   &&     r   _searchr]   Y   s    D)))VZZ))# &&		*ALL[\"#BCC

RrDU2;
 ++.:]^  
 

 	
166"5 *)))&
) *)))sm   EDED(D"B*D(#D$$(D(ED&E"D($D(&E(E	.D1/
E	:E	<	Ec                `    V ^8  d   QhR\         R\        \         \        3,          R,          /# )r   nifr   N)r   r   r   )r   s   "r   r   r   w   s'     = =c =d38nt&; =r   c                D  a "   \         P                  ! RRS ;'       g    R4      o \        S 4      ^	8w  d   R#  \        S R7      G Rj  xL
 p\        T 3R lT 4       R4      #  L  \         d    h \
         d#   p\        P                  RS T4        Rp?R# Rp?ii ; i5i)uu   Denominação social + CAE principal e secundários. None quando não há
registo — o que é normal, não é falha.r7   r   N)r8   zSICAE lookup %s falhou: %sc              3   F   <"   T F  qR ,          S8X  g   K  Vx  K  	  R# 5i)r8   Nr   ).0r\   r_   s   & r   	<genexpr>!lookup_by_nipc.<locals>.<genexpr>   s     5DqfI$4Ds   !
!)	r   r,   r=   r]   r   	ExceptionrS   infonext)r_   rowses   f  r   lookup_by_nipcrj   w   s      &&SYYB
'C
3x1}#&& 5D5t<< '  0#q9sF   5B A% A#	A% B #A% %B:B;BB BB c          	      t    V ^8  d   QhR\         R\        R\        \        \         \        3,          ,          /# )r   r!   limitr   )r   intr&   r   r   )r   s   "r   r   r      s.      s 3 T#s(^8L r   c                  "   T ;'       g    RP                  4       p \        V 4      ^8  d   . #  \        V R7      G Rj  xL
 pTRT #  L	  \         d    h \         d#   p\
        P                  RY4       . u Rp?# Rp?ii ; i5i)uf   Pesquisa inversa nome -> NIPC. Útil quando uma publicação ou um anúncio
traz uma entidade sem NIF.r   )rE   Nz%SICAE pesquisa por nome %r falhou: %s)r/   r=   r]   r   re   rS   rf   )r!   rl   rh   ri   s   &&  r   search_by_namero      s~      JJBD
4y1}	4(( < )  ;TE	sK   -BA A	 A B	A B B!A>8B9B>BB)r   r   )
   )r   loggingr   typingr   app.scrapers.baser   	getLoggerr   rS   BASErP   rR   rU   rV   rW   compiler   Sr<   r*   r+   RuntimeErrorr   r#   r3   rC   r]   rj   ro   r   r   r   <module>ry      s   "  	  *			8	$/!	#
%!'
**+RTTBDD[
9::,bddRTTk:
**Z
 K| K4#<=  r   