
    AHjM                     b   d Z 	 ddlZdZddlZddlZ	 ddlZdZddlm	Z	 ddl
mZ ddlmZmZmZmZ ddlmZ 	 ddlZdZ	 ddlZdZ	 ddlZdZ	 dd	lmZ dd
lmZ ddlmZ ddl m!Z!m"Z"m#Z# ddl$m%Z% erddl&m'Z'm(Z(  ejR                  e*      Z+ddhZ, ejZ                  dej\                        Z/ ejZ                  dej\                        Z0 ejZ                  d      Z1 ejZ                  d      Z2 e"ddddd      Z3 ejZ                  dejh                  ejj                  z        Z6 ejZ                  d      Z7 ejZ                  d      Z8h dZ9ddhZ:dZ; ejZ                  d      Z< ejZ                  d ejz                        Z>d!e?d"e?fd#Z@d$e?d"eAfd%ZBd&e?d"eCeD   fd'ZEd!e?eDz  d"eDfd(ZFd)eDd"eAfd*ZGd+eDd)eDd"eDfd,ZHd-eDd"e!dz  fd.ZId-ed"e!dz  fd/ZJ e	d01      d2eDd"eDfd3       ZKd4eDd"eDfd5ZLdbd4eDd6ed7   d"eDfd8ZM e	d91      dcd:eDd;eAd<eAd"eDdz  fd=       ZNdcd>eDd;eAd<eAd"eDdz  fd?ZOd@ed"efdAZP e	d91      d4eDd"eDfdB       ZQdCed"eAfdDZRdEeDdz  d"eAfdFZSdGedHeTd"efdIZUdJeTdKdLd"eAfdMZVddd@e!dNeDdOeAd"eAfdPZWdQeDdReDd"eDdz  fdSZXdQeDdReDdNeDdTdUd"eYeAdUf   f
dVZZdCed"eAfdWZ[d4eDdz  d"eAfdXZ\dYedZed"dfd[Z]d\ed"eAfd]Z^d\ed"eAfd^Z_dCed"eAfd_Z`dCed"eAfd`ZadCed"eAfdaZby# e$ r dZY w xY w# e$ r dZY w xY w# e$ r dZY w xY w# e$ r dZY w xY w# e$ r dZY w xY w# e$ r dZY w xY w)ezj
Module bundling functions related to HTML and text processing,
content filtering and language detection.
    NTF)	lru_cache)islice)TYPE_CHECKINGAnyLiteralcast	normalize)detect)
from_bytes)_Element)HtmlElement
HTMLParser
fromstring)HTTPResponse   )Document	Extractorutf-8utf_8z^< ?! ?DOCTYPE[^>]*/[^<]*>z(<html.*?)\s*/>z(<!--.*?-->|<[^>]*>)z([\x00-\x08\x0b\x0c\x0e-\x1f\ufffe\uffff])collect_idsdefault_doctypeencodingremove_comments
remove_pisz(?<![p{P}>])\n)flagsz^https?://|/+$z3[^\s]+\.(avif|bmp|gif|hei[cf]|jpe?g|png|webp)(\b|$)>   phitdrefcellheaditemquotecodepre)zhttp-equiv="content-language"zproperty="og:locale"z
([a-z]{2})z\W*(Drucken|E-?Mail|Facebook|Flipboard|Google|Instagram|Linkedin|Mail|PDF|Pinterest|Pocket|Print|QQ|Reddit|Twitter|WeChat|WeiBo|Whatsapp|Xing|Mehr zum Thema:?|More on this.{,8}$)$filecontentreturnc                 4   t        | t              s| S t        r| dd dk(  r	 t        j                  |       S t        r| dd dk(  r	 t        j                  |       S t        r	 t        j                  |       S t        r	 t        j                  |       S | S # t
        $ r t        j                  d       Y ~w xY w# t        j                  $ r t        j                  d       Y w xY w# t        j                  $ r Y w xY w# t        j                  $ r Y | S w xY w)z
    Don't trust response headers and try to decompress a binary string
    with a cascade of installed packages. Use magic numbers when available.
    N   s   zinvalid GZ file   s   (/zinvalid ZSTD file)
isinstancebytesHAS_GZIPgzip
decompress	ExceptionLOGGERwarningHAS_ZSTD	zstandard	ZstdError
HAS_BROTLIbrotlierrorHAS_ZLIBzlib)r'   s    I/root/tools/cai/cai_env/lib/python3.12/site-packages/trafilatura/utils.pyhandle_compressed_filer=   j   s   
 k5) KO6	.??;// KO'::	0''44 	$$[11 	??;//
 -  	.NN,-	. "" 	0NN./	0 || 		 zz 	 		sG   B B9 "C' >D  B65B69(C$#C$'C=<C= DDdatac                 F    	 | j                  d       y# t        $ r Y yw xY w)zLSimple heuristic to determine if a bytestring uses standard unicode encodingzUTF-8FT)decodeUnicodeDecodeError)r>   s    r<   isutf8rB      s,    G   s    	  bytesobjectc                    t        |       rdgS g }t        /t        |       d   }||j                  |j                                t	        |       dk  rt        |       }n!t        | dd | dd z         xs t        |       }t	        |      dkD  r)|j                  |D cg c]  }|j                   c}       |D cg c]  }|t        vs| c}S c c}w c c}w )z> "Read all input or first chunk and return a list of encodingsr   Nr   i'  i  ixr   )	rB   cchardet_detectappendlowerlenr   extendr   UNICODE_ALIASES)rC   guessescchardet_guessdetection_resultsrgs         r<   detect_encodingrP      s     kyG"(5jA%NN>//12
;%&{3&{5D'9K<O'OPkT^_jTk
!,=>q

>?;!!?":A;; ?;s   C<C
Cc                    t        | t              r| S d}t        |       } t        |       D ]  }	 | j	                  |      } n |xs t        | dd      S # t
        t        f$ r t        j                  d|       d}Y Sw xY w)zCheck if the bytestring could be GZip and eventually decompress it,
    guess bytestring encoding and try to decode to Unicode string.
    Resort to destructive conversion otherwise.Nzwrong encoding detected: %sr   replace)r   errors)	r,   strr=   rP   r@   LookupErrorrA   r2   r3   )r'   htmltextguessed_encodings      r<   decode_filerX      s     +s#H )5K+K8 	"))*:;H
  Ks;KK /0 	NN8:JKH	s   A'A?>A?	beginningc                 
    d| vS )zOAssess if the object is proper HTML (awith a corresponding tag or declaration).html )rY   s    r<   is_dubious_htmlr]      s    ""    
htmlstringc                 d   t         j                  d|       } d|v r3| j                  d      \  }}}t        j                  d|d      dz   |z   } t	        t        | j                                     D ]=  \  }}d|v r,|j                  d      rt        j                  d| d      }  | S |d	kD  s< | S  | S )
z>Repair faulty HTML strings to make then palatable for libxml2. doctype
r   )countz<htmlz/>z\1>   )	INVALID_XML_CHARSsub	partitionDOCTYPE_TAG	enumerateiter
splitlinesendswithFAULTY_HTML)r_   rY   	firstline_restilines          r<   repair_faulty_htmlrt      s    "&&r:6JI'11$7	1d __R!_<tCdJ
T*"7"7"9:; 4d?t}}T2$1EJ  q5 r^   
htmlobjectc                     d}	 t        | j                  dd      t              }|S # t        $ r!}t        j                  d|       Y d}~|S d}~ww xY w)z!Try to pass bytes to LXML parser.Nutf8surrogatepassparserzlxml parser bytestring %s)r   encodeHTML_PARSERr1   r2   r9   )ru   treeerrs      r<   fromstring_bytesr      sU    D7*++FOD[Y K  70#66K7s   !' 	AAAc                    t        | t              r| S t        | t              st        | d      r| j                  } t        | t
        t        f      st        dt        |             d}t        |       } | dd j                         }t        |      }t        | |      } d}	 t        | t              }|t)        |      d	k  r|st!        |       }|3|du r/t)        |      d
k  r!t$        j'                  dt)        |             d}|S # t        $ r t!        |       }d}Y lt"        $ r }t$        j'                  d|       Y d}~d}~ww xY w)zLoad object given as input and validate its type
    (accepted: lxml.html tree, trafilatura/urllib3 response, bytestring and string)
    r>   zincompatible input typeN2   Fry   Tzlxml parsing failed: %sr   re   z9parsed tree length: %s, wrong data type or not valid HTML)r,   r   r   hasattrr>   r-   rT   	TypeErrortyperX   rG   r]   rt   r   r|   
ValueErrorr   r1   r2   r9   rH   )ru   r}   rY   
check_flagfallback_parser~   s         r<   	load_htmlr      s1   
 *k**l+wz6/J__
j5#,/14
3CDDDZ(J3B%%'I +J#J	:JN5*[9 	D	A~
+ J$.3t9q=PRUVZR[\K  
+ 5.445s    D EE%E  Ei @  )maxsizecharc                 J    | j                         s| j                         r| S dS )z3Return a character if it belongs to certain classesra   )isprintableisspace)r   s    r<   return_printables_and_spacesr     s"     ##%4?R?r^   stringc                 d    | j                         r| S dj                  t        t        |             S )z6Prevent non-printable and XML invalid character errorsra   )r   joinmapr   r   s    r<   remove_control_charactersr     s,     7733V<==r^   unicodeform)NFCNFDNFKCNFKDc                     t        ||       S )z;Normalize the given string to the specified unicode format.r	   )r   r   s     r<   normalize_unicoder   "  s    [&))r^   i   rs   preserve_spacetrailing_spacec                    t        | j                  dd      j                  dd      j                  dd            }|st        t        j	                  d|            }t        t        t        j                  |            rd}|S |rB| d	   j                         rdnd
}| d   j                         rdnd
}d
j                  |||g      }|S )zjRemove HTML space entities, then discard incompatible unicode
    and invalid XML characters on line levelz&#13;z&#10;rc   z&nbsp;     Nr   ra   )
r   rR   trimLINES_TRIMMINGrg   allr   rT   r   r   )rs   r   r   new_linespace_beforespace_afters         r<   line_processingr   '  s     )gt)D)L)LWVZ)[)c)cdlnv)wxH **4:;s3;;)*H
 O	 "&q'//"33L!%b!1!1!3#KwwhDEHOr^   textc                     |rt        | d      S 	 dj                  t        dfd| j                         D                    j	                  dd      S # t
        $ r Y yw xY w)z<Convert text and discard incompatible and invalid charactersTrc   Nc              3   6   K   | ]  }t        |        y w)N)r   ).0rs   r   s     r<   	<genexpr>zsanitize.<locals>.<genexpr>C  s     &kQUt^'L&ks   u   ␤ra   )r   r   filterrl   rR   AttributeError)r   r   r   s    ` r<   sanitizer   <  sh     t^T::yy&kY]YhYhYj&klmuub
 	
  s   AA 	A A r}   c                 R   | j                         D ]  }|j                         }||j                  nd}|j                  t        v xs |t        v }|j                  t        v xs |t        v xs |}|j
                  D ]S  }d|v s|j
                  |   r"|j                  dd      d   | j                  vs9|j
                  j                  |       U |j                  rt        |j                  ||      |_	        |j                  st        |j                  ||      |_         | S )z?Trims spaces, removes control characters and normalizes unicodera   :r   r   )rk   	getparenttagSPACING_PROTECTEDFORMATTING_PROTECTEDattribsplitnsmappopr   r   tail)r}   elemparent
parent_tagr   r   	attributes          r<   sanitize_treer   J  s   		 L!#)#5VZZ2
 %66Y*HY:Y%99qZK_=_qcq  	/Ii{{9-a1H1KSWS]S]1]KKOOI.	/
 99 NNKDI99 NNKDI%L& Kr^   c                     	 dj                  | j                               j                         S # t        t        f$ r Y yw xY w)z/Remove unnecessary spaces within a text string.r   ra   )r   r   stripr   r   r   s    r<   r   r   b  s<    xx'--//I& s   ,/ A Aelementc                     dD ]!  }| j                  |d      }t        |      s! y | j                  j                         D ]$  \  }}|j	                  d      st        |      s$ y y)z*Check if an element is a valid img element)data-srcsrcra   Tr   F)getis_image_filer   items
startswith)r   attrr   values       r<   is_image_elementr   l  si    # kk$# #>>//1 	KD%z*}U/C	 r^   imagesrcc                 `    | t        |       dkD  ryt        t        j                  |             S )zCheck if the observed string corresponds to a valid image extension.
    Use a length threshold and apply a regex on the content.i    F)rH   boolIMAGE_EXTENSIONsearch)r   s    r<   r   r   z  s.     3x=4/&&x011r^   iterablenc              #      K   t        |       }t        t        ||            x}r| t        t        ||            x}ryyw)zChunk data into smaller pieces.N)rk   tupler   )r   r   iteratorbatchs       r<   make_chunksr     sF      H~H!,-
-%
- !,-
-%
-s   >AAmy_lenoptionsr   c                     | |j                   k  r!t        j                  d|j                         y| |j                  kD  r"t        j                  d| |j                         yy)z=Check if the document length is within acceptable boundaries.ztoo small/incorrect for URL %sFztoo large: length %s for URL %sT)min_file_sizer2   r9   urlmax_file_size)r   r   s     r<   is_acceptable_lengthr     sO    %%%5w{{C%%%6Lr^   target_languagestrictc                 P   t         D ]G  }| j                  d| d      }|st        fd|D              r yt        j	                  d|        y |r>| j                  d      }|r+t        fd|D              ryt        j	                  d	       yt        j	                  d
       y)zoCheck HTML meta-elements for language information and split
    the result in case there are several languages.z	.//meta[@z][@content]c              3      K   | ]9  }t         j                  |j                  d d      j                               v  ; yw)contentra   NRE_HTML_LANGr   r   rG   r   r   r   s     r<   r   z"check_html_lang.<locals>.<genexpr>  s6     l^b?l&8&8)R9P9V9V9X&YYl   ?ATz%s lang attr failedFz//html[@lang]c              3      K   | ]9  }t         j                  |j                  d d      j                               v  ; yw)langra   Nr   r   s     r<   r   z"check_html_lang.<locals>.<genexpr>  s6     i[_?l&8&8&"9M9S9S9U&VVir   zHTML lang failedzNo relevant lang elements found)TARGET_LANG_ATTRSfindallanyr2   debugxpath)r}   r   r   r   elemss    `   r<   check_html_langr     s     " yk:;lfkllLL.5 

?+ichiiLL+,
LL23r^   	temp_texttemp_commentsc                     t         du rFt        |       t        |      kD  rt        j                  |       nt        j                  |      \  }}|S t        j                  d       d}|S )zARun external component (if installed) for language identificationTz3Language detector not installed, skipping detectionN)LANGID_FLAGrH   	py3langidclassifyr2   r3   )r   r   resultrp   s       r<   language_classifierr     s]    d58^c-FX5XI&&y1^g^p^pq~^	 M 	LMMr^   docmetar   c                     |[t        | |      |_        |j                  >|j                  |k7  r/t        j                  d|j                  |j                         d|fS d|fS )zFFilter text based on language detection and store relevant informationzwrong language: %s %sTF)r   languager2   r3   r   )r   r   r   r   s       r<   language_filterr     sc     ".y-H 'G,<,<,ONN2G4D4DgkkR= '>r^   c                     | j                   | j                  n| j                   }| xsC |j                         xs1 t        t	        t
        j                  |j                                     S )zFilter out unwanted text)r   r   r   r   r   	RE_FILTERmatchrl   )r   testtexts     r<   
textfilterr    sN    &||3w||H<a8++-aS(J]J]J_5`1aar^   c                 >    t        |       xr | j                          S )zJDetermine if a string is only composed of spaces and/or control characters)r   r   r   s    r<   text_chars_testr    s     <0 000r^   	dest_elemsrc_elemc                 l    |j                         D ]!  }| j                  ||j                  |          # y)z0Copy attributes from src element to dest elementN)keyssetr   )r  r  keys      r<   copy_attributesr    s.    }} 1c8??3/01r^   r   c                 t    | j                         y| }|#|j                  dk(  ry|j                         }|#y)z+Check whether an element is in a table cellFr!   T)r   r   )r   currents     r<   is_in_table_cellr    sG    ~~#G

;;& ##% 
 r^   c                     t        |       sy| j                  dk(  r| j                         }| xs |d   | k(  S t        t        | j                               }|j                         }| xs |d   | k(  S )z:Check whether an element is the last element in table cellFr!   r   )r  r   getchildrenr   r   r   )r   childrenr   s      r<   is_last_element_in_cellr    st    D!xx6##%|3x|t33h 01%%'|3x|t33r^   c                 R    | }|#|j                   dk(  ry|j                         }|#y)z=Check whether an element is a list item or within a list itemr#   TF)r   r   )r   r  s     r<   is_element_in_itemr    s7    &G

;;& ##% 
 r^   c                     | j                   dk(  r| j                  ry| }d}|%|j                   dk(  r|}n|j                         }|%|y|j                  syy)z:Check whether an element is the first element in list itemr#   TNF)r   r   r   )r   r  item_ancestors      r<   is_first_element_in_itemr     sk    {{f&GM

;;& #M##%	 
 r^   c                     t        |       sy| j                  dk(  rt        | j                               dk(  S | j	                         }|y|j                  dk(  S )z9Check whether an element is the last element in list itemFr#   r   T)r  r   rH   r  getnext)r   next_elements     r<   is_last_element_in_itemr    sZ    g& {{f7&&()Q..??$L6))r^   )r   )FF)F)c__doc__r/   r.   ImportErrorloggingrer;   r:   	functoolsr   	itertoolsr   typingr   r   r   r   unicodedatar
   r8   r7   r5   r4   r   r   cchardetr   rE   charset_normalizerr   
lxml.etreer   	lxml.htmlr   r   r   urllib3.responser   settingsr   r   	getLogger__name__r2   rJ   compileIri   rn   HTML_STRIP_TAGSrf   r|   UNICODE	MULTILINEr   URL_BLACKLIST_REGEXr   r   r   r   r   
IGNORECASEr  r-   r=   r   rB   listrT   rP   rX   r]   rt   r   r   r   r   r   r   r   r   r   r   r   intr   r   r   r   r   r   r  r  r  r  r  r  r  r  r\   r^   r<   <module>r7     sD  
H  	H    4 4 !JH
K
2 *  9 9 *-			8	$G$bjj5rtt<bjj+RTT2"**45BJJJK  UEGeivz{-RZZ",,5NO bjj!23  "**STP UO  N rzz-( BJJG --		" "% "J 4 < <49 <0LUS[ LS L2#s #t #
3 3 3 " t); (# (+"4 (V 5@s @s @ @
>c >c >*c *8T0U *be *
 4# t T ^adh^h  (3  d WZ]aWa  X 0 4   h 4 2C$J 24 2# # #  { t +  T VZ 03 s sTz s 3  Wa fklpr|l|f} "b bT b1C$J 14 11x 18 1 1	8 	 	4( 4t 4 T h 4 (*X *$ *S  H  H  J  H  K  Osh   K K+ K9 L L L# K('K(+K65K69LLLLL L #L.-L.