
    AHj'<                        d Z ddlZddlmZ ddlmZmZ ddlmZm	Z	m
Z
mZmZmZ ddlmZ ddlmZ dd	lmZmZmZmZmZ dd
lmZmZmZ ddlmZmZ  ej>                  e       Z!ddddddddddddZ"e"jG                         D  ci c]  \  } }|| 
 c}} Z$h dZ%g dZ&dededefdZ'dUdede(defdZ)dVdede*e
   de+defdZ,de*e   de-e.e.e.e*e(   f   fdZ/dVd ed!e(d"e+de-e+e*e(   f   fd#Z0d ede+fd$Z1	 	 dWd%ed&e(d'e+d"e+def
d(Z2	 	 dXd)eded*e+d+e+dedz  f
d,Z3d)edededz  fd-Z4d)eddfd.Z5d)eddfd/Z6d!e(dz  de+fd0Z7d)eddfd1Z8d)eddfd2Z9d)eddfd3Z:d)eddfd4Z;i d5e5d6e5d7e5d8e8d9e8d:e8d;e8d<e8d=e8d>e9d?e9d@e6dAe6dBe6dCe:dDe:dEe:dFe;iZ<d)edGe(dz  ddfdHZ=dYdededIe(dz  defdJZ>d7dKdAd@dL d>dMdNdO dP	Z?dedefdQZ@dVdRedSe+de(fdTZAyc c}} w )Zz*
Functions to process nodes in HTML code.
    N)deepcopy)fix_relative_urlsget_base_url)Element
SubElementXPath_Element
strip_tagstostring)HtmlElement   )duplicate_test)CUT_EMPTY_ELEMSMANUALLY_CLEANEDMANUALLY_STRIPPEDDocument	Extractor)is_image_element
textfiltertrim)META_ATTRIBUTESdelete_element#iz#bz#uz#tz#subz#sup)emibstrongukbdsampttvarsubsup>   figuresourcepicture){z("z('z
    treeoptionsreturnc                    t        j                         t        j                         }}|j                  s|j	                  g d       n| j                  d      D ]	  }d|_         |j                  r)|D cg c]  }|t        vs| }}|j                  d       t        | |       |j                  dk(  rX| j                  d      Gt        |       }|D ]#  }| j                  |      D ]  }t        |        % | j                  d      +|} n(|D ]#  }| j                  |      D ]  }t        |        % t!        | |j                        S c c}w )z/Prune the tree by discarding unwanted elements.)tabletdthtrz.//figure[descendant::table]divimgrecallz.//p)r   copyr   tablesextendxpathtagimagesPRESERVE_IMG_CLEANINGremover
   focusfindr   iterr   
prune_html)	r)   r*   cleaning_liststripping_listelemetcopy
expressionelements	            R/root/tools/cai/cai_env/lib/python3.12/site-packages/trafilatura/htmlprocessing.pytree_cleaningrH   /   sH    %5$9$9$;=N=S=S=U>M>>89 JJ=> 	DDH	~~$1TqQ>S5STTe$ t^$ }} TYYv%6%B' 	(J99Z0 (w'(	( 99V$D ( 	(J99Z0 (w'(	( dGMM**) Us   6EEr<   c                 |    |dk7  }| j                  d      D ]"  }|j                  t        v st        ||       $ | S )zADelete selected empty elements to save space and processing time.	precisionz-.//processing-instruction()|.//*[not(node())])	keep_tail)r7   r8   r   r   )r)   r<   tailsrF   s       rG   r?   r?   R   sB    [ E::MN 5;;/)7e45 K    nodelistwith_backupc                     |r$t        | j                               }t        |       }|D ]  } ||       D ]  }t        |         |r%t        | j                               }|dz  kD  r| S S | S )z2Prune the HTML tree by removing unwanted sections.   )lentext_contentr   r   )r)   rN   rO   old_lenbackuprE   subtreenew_lens           rG   prune_unwanted_nodesrX   \   s    d'')*$ $
!$' 	$G 7#		$$ d'')*1,t8&8KrM   links_xpathc                     d | D        D cg c]  }|s|	 }}t        t        t        |            }t        d |D              }t        |      t        |      ||fS c c}w )zCollect heuristics on link textc              3   N   K   | ]  }t        |j                                 y wN)r   rS   ).0rB   s     rG   	<genexpr>z$collect_link_info.<locals>.<genexpr>t   s     L$t0023Ls   #%c              3   ,   K   | ]  }|d k  s	d  yw)
   r   N )r]   lengths     rG   r^   z$collect_link_info.<locals>.<genexpr>w   s     <6Q<s   
)listmaprR   sum)rY   rC   mylistlengths
shortelemss        rG   collect_link_infori   p   s^     MLRAPQaRFR3sF#$G<W<<Jw<Vj&88	 Ss
   AArF   textfavor_precisionc                 F   | j                  d      }|sdg fS | j                  d      dg fS g }t        |      dk(  rN|rdnd}t        |d   j	                               }t        |      |kD  rt        |      t        |      dz  kD  rd	g fS | j
                  d
k(  r| j                         dnd}n| j                         d}nd}t        |      }||k  rKt        |      \  }	}
}}|
dk(  rd	|fS t        j                  d|	|||
       |	|dz  kD  s|
dkD  r||
z  dkD  rd	|fS d|fS )z>Remove sections which are rich in links (probably boilerplate).//refFz
.//graphicr   r`   d   r   g?Tp<      i,  u8   list link text/total: %s/%s – short elems/total: %s/%s皙?)
findallr=   rR   r   rS   r8   getnextri   LOGGERdebug)rF   rj   rk   rY   rf   len_threshold	link_textlimitlenelemlenlinklenelemnumrh   s               rG   link_density_testr}   {   sL   //(+Kby||L!-byF
;1-3Q4467	y>M)c)ns4y3.N8O{{c *22??$H H$iG/@/M,*fa<<F	
 Ws]"w{zG7Kc7Q<&=rM   c                     | j                  d      }|syt        t        | j                                     }|dk  ryt	        |      \  }}}}|dk(  ryt
        j                  d||       |dk  r|d|z  kD  S |d	|z  kD  S )
z=Remove tables which are rich in links (probably boilerplate).rm   F   r   Tztable link text: %s / total: %si  rr   g      ?)rs   rR   r   rS   ri   ru   rv   )rF   rY   rz   r{   r|   _s         rG   link_density_test_tablesr      s    //(+K$w++-./G}.{;GWa!|
LL2GWE&-n7S7]"Q'C'M:QQrM   rV   tagnamebacktrackingc                 j   g }|rdnd}|rdnd}| j                  |      D ]k  }t        |j                               }t        |||      \  }	}
|	s-|s1|
s4dt	        |      cxk  r|k  sIn Lt	        |      |k\  s[|j                  |       m t        j                  |      D ]  }t        |        | S )z{Determine the link density of elements with respect to their length,
    and remove the elements identified as boilerplate.r   rn   r      r   )	r>   r   rS   r}   rR   appenddictfromkeysr   )rV   r   r   rk   	deletionsrw   depth_thresholdrB   elemtextresulttemplists              rG   delete_by_link_densityr      s     I*CM*aOW% #))+,,T8_MlxAH4U4UZ]^bZcgvZvT"	# i( t NrM   rB   comments_fixpreserve_spacesc                    | j                   dk(  rt        |       r| S | j                   dk(  s&t        |       dk(  r| j                  s| j                  sy|s1| j                   dk(  r"|st        | j                        xs d| _        | S | j                  s?t        |       dk(  r1| j                  dc| _        | _        |r| j                   dk(  rd| _         |sHt        | j                        xs d| _        | j                  rt        | j                        xs d| _        | j                  st        |       s|j                  rt        | |      ry| S )z3Convert, format, and probe potential text elements.graphicdoner   Nlb ro   )	r8   r   rR   rj   tailr   r   dedupr   )rB   r*   r   r   s       rG   handle_textnoder      s    xx9!1$!7xx6c$i1nTYYtyy DHH,TYY/4DI 99Ta  $yy"	49DHH,DH O+t	99TYY/4DI 99D)gmmtU\@]KrM   c                    | j                   dk(  s&t        |       dk(  r| j                  s| j                  syt	        | j                        xs dt	        | j                        xs dc| _        | _        | j                   dk7  r1| j                  s%| j                  r| j                  dc| _        | _        | j                  s| j                  r$t        |       s|j                  rt        | |      ry| S )zBConvert, format, and probe potential text elements (light format).r   r   Nr   )r8   rR   rj   r   r   r   r   r   )rB   r*   s     rG   process_noder      s    xx6c$i1nTYYtyy  		?2dDO4KtDIty xx4		dii#yy$	49 yyDIId.w2OKrM   c                 $   | j                  d| j                         d| _        d}| j                  ddd      D ]U  }|j                  dv r>|j                  dt        |j                         d|        |j                  dk(  r|dz  }d	|_        W y
)zGConvert <ul> and <ol> to <list> and underlying <li> elements to <item>.rendrc   r   dddtli)r   r   -itemN)setr8   r>   str)rB   r   subelems      rG   convert_listsr     s    HHVTXXDH	A99T4. ;;,&KK3w{{#3"4AaS 9:{{d"QrM   c                 &   d}| j                   dk(  rot        |       dk(  r| d   j                   dk(  rd}| j                  d      }|r#d}|D ]  }|j                  j	                           t        | j                        rd}|rd| _         y
d	| _         y
)z?Convert quoted elements while accounting for nested structures.Fprer   r   spanTz#.//span[starts-with(@class,'hljs')]codequoteN)r8   rR   r7   attribclear_is_code_blockrj   )rB   	code_flag
code_elemsr   s       rG   convert_quotesr     s    Ixx5 t9>d1gkkV3IZZ EF
I% '$$&'$))$I"vDHDHrM   c                 ,    | syt         D ]  }|| v s y y)z2Check if the element text is part of a code block.FT)CODE_INDICATORS)rj   	indicators     rG   r   r   2  s'    $ 	 rM   c                 ~    | j                   j                          | j                  d| j                         d| _        y)z$Add head tags and delete attributes.r   headN)r   r   r   r8   rB   s    rG   convert_headingsr   <  s+    KKHHVTXXDHrM   c                     d| _         y)zConvert <br> and <hr> to <lb>r   N)r8   r   s    rG   convert_line_breaksr   C  s	    DHrM   c                 6    d| _         | j                  dd       y)z7Convert <del>, <s>, <strike> to <del rend="overstrike">delr   
overstrikeN)r8   r   r   s    rG   convert_deletionsr   H  s    DHHHV\"rM   c                 L    d| _         | j                  d      D ]	  }d|_          y)zHandle details and summary.r1   summaryr   N)r8   r>   )rB   r   s     rG   convert_detailsr   N  s(    DH99Y' rM   dlolulh1h2h3h4h5h6brhr
blockquoter   qr   sstrikedetailsbase_urlc                     d| _         | j                  d      }| j                  j                          |r!|rt	        ||      }| j                  d|       yy)z7Replace link tags and href attributes, delete the rest.refhreftargetN)r8   getr   r   r   r   )rB   r   r   s      rG   convert_linkr   l  sL    DHXXfFKK&x8F6"	 rM   urlc                 "   |j                   s=d}|j                  r|dz  }| j                  |      D ]	  }d|_         t	        | d       n2|xr t        |      }| j                  dd      D ]  }t        ||        |j                  rm| j                  t        j                               D ]F  }|j                  j                          |j                  dt        |j                            d|_        H nt	        | gt        j                           | j                  t        j                               D ]  }t        |j                     |        |j                  r| j                  d      D ]	  }d|_         |j                   rt!        | j                  d            D ]j  }t!        |j                  d            }t#        |      D ]  }|j%                  |        |sA|j'                         j)                         r`t+        |       l | S )	zBSimplify markup and convert relevant HTML tags to an XML standard.z).//*[self::div or self::li or self::p]//az|.//table//ar   ar   hir2   r   )linksr5   r7   r8   r
   r   r>   r   
formattingREND_TAG_MAPPINGkeysr   r   r   CONVERSIONSr9   rc   reversedaddnextrS   stripr   )	r)   r*   r   
xpath_exprrB   r   r   graphicsr   s	            rG   convert_tagsr   x  s    ==@
>>.(JJJz* 	DDH	 	4 ,<,IIc5) 	)Dx(	) II.3356 	DKKHHV-dhh78DH	
 	42*//12 		+**,- $DHHd#$ ~~IIe$ 	!D DH	! ==DIIe,- 	( 34'1 )GKK()
 C$4$4$6$<$<$>"3'	( KrM   r   c                 D    dt        | j                  dd      dd         S )Nhr   r   r   )intr   r   s    rG   <lambda>r     s%    1S&$!7!;<=> rM   r   r   c                 4    t         | j                  dd         S )Nr   r   )HTML_TAG_MAPPINGr   r   s    rG   r   r     s    '(>? rM   )	rc   r   r   r   r   r   r2   r   r   c                    | j                  t        j                               D ]  }t        t        |j                           }t        |      r ||      |_        n||_        |j                  dk(  r-|j                  d|j                  j                  dd             {|j                  j                           d| _        t        d      }|j                  |        |S )zConvert XML to simplified HTML.r   r   r   r   bodyhtml)r>   HTML_CONVERSIONSr   r   r8   callabler   r   popr   r   r   )r)   rB   
conversionroots       rG   convert_to_htmlr     s    		*//12  %c$((m4
J!$'DH!DH88s?HHVT[[__Xr:;KK  DH6?DKKKrM   documentwith_metadatac                     t        | j                        }|rFt        d      }t        D ]   }t	        | |      x}st        |d||       " |j                  d|       t        |dd      j                         S )z1Convert the document to HTML and return a string.r   meta)namecontentr   Tunicode)pretty_printencoding)	r   r   r   r   getattrr   insertr   r   )r   r   	html_treer   r   values         rG   build_html_outputr    sw    .Iv# 	CD$//u/4dEB	C 	D!ID9EKKMMrM   )balanced)F)FF)TFr\   )B__doc__loggingr4   r   courlan.urlutilsr   r   
lxml.etreer   r   r   r	   r
   r   	lxml.htmlr   deduplicationr   settingsr   r   r   r   r   utilsr   r   r   xmlr   r   	getLogger__name__ru   r   itemsr   r:   r   rH   r   r?   rc   boolrX   tupler   ri   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  )kvs   00rG   <module>r     s     < Q Q ! )  6 5 0			8	$ 			
  &6%;%;%=>TQAqD> 7 - +  +i  +K  +F[  k { d5k PT al (9k"9
3S$s)#$9&{ &# & &Y^_ceijmen_nYo &RRk Rd R, !	  	
 : !	'
'' ' 	'
 _'Tx ) 4 ( T  0 0d 0&t  8  h 4 
#H # #( t -- 	- 	
	
 	
 	
 	
 	
 	
 	
 	
 . 
>  
  	!" #$ %.	#{ 	#cDj 	#T 	#.{ .Y .S4Z .S^ .d >

?
 ( x (N N N# NE ?s   G