
    AHjm.                        d Z ddl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mZmZmZ 	 ddlZddlmZmZ dd	lmZ dd
l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   ejB                  e"      Z# e	dd      Z$dZ%dZ&dZ' G d d      Z(de)de)de*e)dz  e)dz  f   fdZ+de)de*e)dz  e)dz  e)dz  f   fdZ,de)de)dedz  fdZ-de)dedz  fdZ.de)de)dz  de/fd Z0d!e1e)   de/fd"Z2	 d5de)d#e(d$e)dz  ddfd%Z3d&edz  d#e(ddfd'Z4	 	 	 	 	 d6d(e)d)e)dz  d*edz  d!e1e)   dz  d+e1e)   dz  d,e)dz  de(fd-Z5	 d7d#e(d.e/de(fd/Z6e&e'dddeddfde)d0e7d1e7d!e1e)   dz  d2e1e)   dz  d)e)dz  d3ed*edz  d,e)dz  de*e1e)   e1e)   f   fd4Z8y# e$ r Y Ww xY w)8zC
Functions dedicated to website navigation and crawling/spidering.
    N)ConfigParser)sleep)RobotFileParser)UrlStoreextract_linksfix_relative_urlsget_base_urlis_navigation_pageis_not_crawlable)XPathtostring   )baseline)Responsefetch_response	fetch_url)prune_unwanted_nodes)DEFAULT_CONFIG)LANGID_FLAGdecode_file	load_htmlF)
compressedstrictz/robots.txt
   i c                       e Zd ZdZg dZ	 	 	 ddededz  dedz  dedz  ddf
d	Zdedefd
ZdedefdZ	de
ddfdZdee   dz  dee   fdZdedefdZy)CrawlParametersz6Store necessary information to manage a focused crawl.)	startbaselangrulesrefi	known_numis_onprune_xpathNr   r   r    r%   returnc                     || _         | j                  |      | _        | j                  |      | _        || _        |xs t        | j                        | _        d| _        d| _	        d| _
        || _        y )Nr   T)r   _get_base_urlr   _get_referencer!   r   	get_rulesr    r"   r#   r$   r%   )selfr   r   r    r%   s        J/root/tools/cai/cai_env/lib/python3.12/site-packages/trafilatura/spider.py__init__zCrawlParameters.__init__/   sh      
++E2	++E2 $	-2-Ji		6J

'2    c                 <    t        |      }|st        d|       |S )z#Set reference domain for the crawl.zcannot start crawl: )r	   
ValueError)r+   r   r   s      r,   r(   zCrawlParameters._get_base_url@   s'     '3E7;<<r.   c                 X    |j                  d      dk\  r|j                  dd      d   S |S )zDetermine the reference URL./   r   r   )countrsplit)r+   r   s     r,   r)   zCrawlParameters._get_referenceG   s-    */++c*:a*?u||C#A&JUJr.   	url_storec                     t        |j                  | j                              | _        t	        |j                  | j                              | _        y)z*Adjust crawl data based on URL store info.N)boolfind_unvisited_urlsr   r$   lenfind_known_urlsr#   )r+   r6   s     r,   update_metadatazCrawlParameters.update_metadataK   s8    )77		BC
Y66tyyABr.   todoc                 r    |sg S |D cg c]#  }|| j                   k7  s| j                  |v s"|% c}S c c}w )z.Prepare the todo list, excluding invalid URLs.)r   r!   )r+   r=   us      r,   filter_listzCrawlParameters.filter_listP   s2    IEa1

?txx1}EEEs   444linkc                     | j                    xs | j                   j                  d|      xr | j                  |v xr t        |       S )z9Run checks: robots.txt rules, URL type and crawl breadth.*)r    	can_fetchr!   r   )r+   rA   s     r,   is_valid_linkzCrawlParameters.is_valid_linkV   sB    JJA$**"6"6sD"AvtxxSWGWv`pqu`v\vvr.   NNN)__name__
__module____qualname____doc__	__slots__strr   r-   r(   r)   r   r<   listr@   r8   rE    r.   r,   r   r   *   s    <cI
  (,"&33 Dj3 %	3
 4Z3 
3"3 3 KC KC KC Cd C
FS	D 0 FT#Y Fw# w$ wr.   r   
htmlstringhomepager&   c                    d| vrd| vr| |fS t        |       }|| |fS |j                  d      }|r|d   nd}|rd|vrt        j                  d|       | |fS |j	                  d      d   j                         j                         j                  d	d      }|j                  d
      st        |      }t        ||      }t        |      }|t        j                  d|       yt        j                  d|       ||fS )z:Check if there could be a redirection by meta-refresh tag.z	"refresh"z	"REFRESH"z@.//meta[@http-equiv="refresh" or @http-equiv="REFRESH"]/@contentr    ;zno redirect found: %sr   zurl=httpzfailed redirect: %s)NNzsuccessful redirect: %s)r   xpathlogginginfosplitstriplowerreplace
startswithr	   r   r   warning)rO   rP   	html_treeresultsresulturl2base_urlnewhtmlstrings           r,   refresh_detectionrd   [   s   *$J)F8##*%I8## oo`aG"WQZFS&,h78##<<Q%%'--/77CD??6"% 40dOM-t4LL*D1$r.   c                 H   t        | d      }|r|j                  sy|j                  | dfvr,t        j                  d|j                         |j                  } t        |j                        }t        ||       \  }}|yt        j                  d|       ||t        |      fS )zBCheck if the homepage is redirected and return appropriate values.FdecoderF   r2   zfollowed homepage redirect: %szfetching homepage OK: %s)	r   dataurlrV   rW   r   rd   debugr	   )rP   responserO   new_htmlstringnew_homepages        r,   probe_alternative_homepagern   }   s     hu5H8== ||Hc?*5x||D<< X]]+J $5Z#J NLMM,l;<l)CCCr.   
robots_urlrh   c                     t               }|j                  |        	 |j                  |j                                |S # t        $ r }t
        j                  d|       Y d}~yd}~ww xY w)zEParse a robots.txt file with the standard library urllib.robotparser.zcannot read robots.txt: %sN)r   set_urlparse
splitlines	ExceptionLOGGERerror)ro   rh   r    excs       r,   parse_robotsrx      s[     E	MM*DOO%& L  137s   > 	A'A""A'rb   c                 J    | t         z   }t        |      }|rt        ||      S dS )z?Attempt to fetch and parse robots.txt file for a given website.N)ROBOTS_TXT_URLr   rx   )rb   ro   rh   s      r,   r*   r*      s*    N*JZ D-1<
D);t;r.   languagec                     | r=|r;t         r5t        |       \  }}}t        j                  |      \  }}t	        ||k(        S y)zRun a baseline extraction and use a language detector to
    check if the content matches the target language.
    Return True if language checks are bypassed.T)r   r   	py3langidclassifyr8   )rO   r{   _textr`   s        r,   is_target_languager      sB     h;j)
4&&t,	Fh&''r.   r=   c                 &    t        d | D              S )z6Probe if there are still navigation URLs in the queue.c              3   2   K   | ]  }t        |        y w)N)r
   ).0ri   s     r,   	<genexpr>z&is_still_navigation.<locals>.<genexpr>   s     73!#&7s   )any)r=   s    r,   is_still_navigationr      s    7$777r.   paramsri   c           	      b   t        | |j                        sy| r|j                  |t        |j                  t              r|j                  gn|j                  }t        |       }|<t        ||D cg c]  }t        |       c}      }t        |      j                         } g g }}t        | |xs |j                  d|j                  dd      D ]B  }|j                  |      st        |      r|j                  |       2|j                  |       D t        j!                  ||       yc c}w )zExamine the HTML code and process the retrieved internal links.
    Extract and filter new internal links after an optional language check.
    Store the links in todo-list while prioritizing the navigation ones.NFT)pagecontentri   external_boolr{   with_navr   )urls
appendleft)r   r   r%   
isinstancerL   r   r   r   r   rg   r   r   rE   r
   append	URL_STOREadd_urls)	rO   r   ri   xpathstreexlinkslinks_priorityrA   s	            r,   process_linksr      s    j&++6f((4)3F4F4F)L&$$%RXRdRd$'.HAuQx.HID!$..0J>E6;;  ##D)d#!!$'LL En=' /Is   0D,
rk   c                     | | j                   syt        j                  | j                  gd       t	        t        | j                         ||j                         y)z2Convert urllib3 response object and extract links.NT)visited)rh   r   r   ri   r   r   r   )rk   r   s     r,   process_responser      sG    
 x}}~t4 +hmm,ffkkBr.   r   r   r    knownr%   c                    t        | |||      }t        j                  |xs g d       t        j                  |j                  |             t        j	                  |j
                  |j                         |s1t        j                  |j                  gd       t        |d      }|S |j                  t               |S )zInitialize crawl by setting variables, copying values to the
    URL store and retrieving the initial page if the crawl starts.T)r   r   )r   F)initial)
r   r   r   r@   store_rulesr   r    r   
crawl_pager<   )r   r   r    r=   r   r%   r   s          r,   
init_crawlr      s     UD%=F EKR6F..t45&++v||4 >FD1 M 	y)Mr.   r   c                    t         j                  | j                        }|s6d| _        t	        t         j                  | j                              | _        | S | xj                  dz  c_        |r:t        |      \  }}}|rB|r@|r>t         j                  |g       t        || |       nt        |d      }t        ||        | j                  t                | S )z6Examine a webpage, extract navigation links and links.Fr   )ri   rf   )r   get_urlr   r$   r:   r;   r#   r"   rn   r   r   r   r   r<   )r   r   ri   rO   rP   new_base_urlrk   s          r,   r   r   	  s     

FKK
(Cy88EF
HHMH-G-L*
Hl(|z**f#6!#e46* 9%Mr.   max_seen_urlsmax_known_urlsknown_linksconfigc	                 N   t        | |||||      }	t        j                  |	j                  |j	                  dd            }
|	j
                  r_|	j                  |k  rP|	j                  |k  rAt        |	      }	t        |
       |	j
                  r|	j                  |k  r|	j                  |k  rAt        t        j                  t        j                  |	j                                    }t        t        j                  t        j                  |	j                                    }||fS )a  Basic crawler targeting pages of interest within a website.

    Args:
        homepage: URL of the page to first page to fetch, preferably the homepage of a website.
        max_seen_urls: maximum number of pages to visit, stop iterations at this number or at the exhaustion of pages on the website, whichever comes first.
        max_known_urls: stop if the total number of pages "known" exceeds this number.
        todo: provide a previously generated list of pages to visit / crawl frontier.
        known_links: provide a list of previously known pages.
        lang: try to target links according to language heuristics.
        config: use a different configuration (configparser format).
        rules: provide politeness rules (urllib.robotparser.RobotFileParser() format).
        prune_xpath: remove unwanted elements from the HTML pages using XPath.

    Returns:
        List of pages to visit, deque format, possibly empty if there are no further pages to visit.
        Set of known links.

    DEFAULT
SLEEP_TIME)default)r   r   get_crawl_delayr   getfloatr$   r"   r#   r   r   rM   dictfromkeysr9   r;   )rP   r   r   r=   r   r   r   r    r%   r   
sleep_times              r,   focused_crawlerr   (  s    : $t[+NF**6;;PY[g@h*iJ ,,688m38H8H>8YF#j ,,688m38H8H>8Y
 i;;FKKHIJDt}}Y%>%>v{{%KLMKr.   )rR   )NNNNN)F)9rJ   rV   configparserr   timer   urllib.robotparserr   courlanr   r   r   r	   r
   r   r}   ImportError
lxml.etreer   r   r   	downloadsr   r   r   htmlprocessingr   settingsr   utilsr   r   r   	getLoggerrG   ru   r   rz   MAX_SEEN_URLSMAX_KNOWN_URLSr   rL   tuplerd   rn   rx   r*   r8   r   rM   r   r   r   r   r   intr   rN   r.   r,   <module>r      s    %  . 	 '  : : 0 $ 6 6			8	$e4	.w .wb#  sTz3QU:?U9V DDD
3:sTz3:-.D2S  $0F < <$ 6 <3 #*  8d3i 8D 8 ">">"> 
t"> 
	">JCoCC 
C  $(!""
* T! s)d
	
 9t t :  B '(!$()$("*** * s)d
	*
 cT!* ** * T!* t* 49d3i *e  		s   E= =FF