Ë
    '}j|/  ã                   óÌ   — d Z ddlZddlZddlZddlZddlZddlZddlmZmZ ddl	m
Z
 dZdZdZdZd	Zd
ZddgZg d¢ez   Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zedk(  r e«        yy)uŸ   
Crawler for å²³é˜³åŽ¿äººæ°‘æ”¿åºœ - å…¬ç¤ºå…¬å‘Š
CMS: TRS-style static HTML, GBK encoding
Site: www.yyx.gov.cn/37584/38137/index.htm
Province: æ¹–å�— (Hunan)
é    N)ÚdatetimeÚ	timedelta)ÚBeautifulSoupzhttps://www.yyx.gov.cnz/37584/38137u   å²³é˜³åŽ¿-å…¬ç¤ºå…¬å‘Šé   é   é   z-AzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36)Úcurlz-sz-kz--connect-timeoutÚ10z
--max-timeÚ20c                 óþ   — t         | gz   }t        j                  |dd¬«      }|j                  dk7  r2t	        dj                  |j                  |j                  dd «      «      ‚|j                  j                  d«      S )	zFetch URL via curl.Té   ©Úcapture_outputÚtimeoutr   zcurl failed: {} (stderr: {})NéÈ   Úgbk)	Ú	BASE_CURLÚ
subprocessÚrunÚ
returncodeÚ	ExceptionÚformatÚstderrÚstdoutÚdecode©ÚurlÚcmdÚrs      ú#/root/gov_crawler/crawl_yyx_gsgg.pyÚfetchr!      sh   € ä
�s�eÑ
€CÜ�‰�s¨4¸Ô<€AØ‡|�|�qÒÜÐ6×=Ñ=¸a¿l¹lÈAÏHÉHÐUYÐVYÈNÓ[Ó\Ð\à�8‰8�?‰?˜5Ó!Ð!ó    c                 óÄ   — t         | gz   }t        j                  |dd¬«      }|j                  dk7  r$t	        dj                  |j                  «      «      ‚|j                  S )zFetch URL and return raw bytes.Tr   r   r   zcurl failed: {})r   r   r   r   r   r   r   r   s      r    Ú	fetch_rawr$   $   sP   € ä
�s�eÑ
€CÜ�‰�s¨4¸Ô<€AØ‡|�|�qÒÜÐ)×0Ñ0°·±Ó>Ó?Ð?Ø�8‰8€Or"   c           	      ó6  — g }t        j                  d| «      D �]¼  }|j                  d«      j                  «       }|j                  d«      r|j                  d«      j                  «       nd}|j	                  d«      rd|vrŒkd|v rŒp|j                  d«      r|}nS|j                  d	«      rt        t        z   d
z   |z   }n.|j                  d
«      r
t        |z   }nt        t        z   d
z   |z   }ddl}|j                  d
«      }g }|D ]2  }	|	dk(  r|sŒ|j                  «        Œ|	dk7  sŒ"|j                  |	«       Œ4 d
j                  |«      }|s[t        j                  d| | j                  |«      | j                  |«      dz    «      }
|
r|
j                  d«      j                  «       }|s�Œ—|s�Œ›|j                  |j                  «       |df«       �Œ¿ t        «       }g }|D ]/  }|d   |vsŒ|j!                  |d   «       |j                  |«       Œ1 |S )z3Parse list page, return list of (title, url, date).z1<a[^>]*href="([^"]+)"[^>]*title="?([^"]*)"?[^>]*>é   é   Ú z.htmlÚcontentÚ
javascriptÚhttpú../ú/r   Nz..ú.z>([^<]{10,})</a>iô  )ÚreÚfinditerÚgroupÚstripÚendswithÚ
startswithÚBASE_URLÚ	LIST_PATHÚ	posixpathÚsplitÚpopÚappendÚjoinÚsearchÚindexÚsetÚadd)ÚhtmlÚitemsÚmÚhrefÚtitleÚfull_urlr7   ÚpartsÚresolvedÚpÚtitle_matchÚseenÚunique_itemsÚitems                 r    Ú
parse_listrM   -   sý  € à€Eô �[‰[ÐMÈtÓTó -8ˆØ�w‰w�q‹z×ÑÓ!ˆØ&'§g¡g¨a¤j�—‘˜“
× Ñ Ô"°bˆð �}‰}˜WÔ%¨¸$Ñ)>Øð ˜4ÑØð �?‰?˜6Ô"Ø‰HØ�_‰_˜UÔ#ä¤)Ñ+¨cÑ1°DÑ8‰HØ�_‰_˜SÔ!Ü $‘‰Hä¤)Ñ+¨cÑ1°DÑ8ˆHó 	Ø—‘˜sÓ#ˆØˆØò 	#ˆAØ�DŠyÚØ—L‘L•NØ�c“Ø—‘ Õ"ð	#ð —8‘8˜HÓ%ˆñ
 ÜŸ)™)Ð$7¸¸d¿j¹jÈÓ>NÈtÏzÉzÐZ^ÓO_Ð`cÑOcÐ9dÓeˆKÙØ#×)Ñ)¨!Ó,×2Ñ2Ó4�ó “XØ�L‰L˜%Ÿ+™+›-¨°2Ð6Ö7ð[-8ô` ‹5€DØ€LØò &ˆØ�‰7˜$ÒØ�H‰H�T˜!‘WÔØ×Ñ Õ%ð&ð
 Ðr"   c                 óØ  ‡— t        | d«      }d}|j                  dd¬«      }|r|j                  d¬«      }d}|j                  dd¬«      }|rU|j                  d	«      }|D ]?  }|j                  d¬«      }	t	        j
                  d
|	«      }
|
sŒ.|
j                  d«      } n |s_dD ]Z  }|j                  dd|i¬«      }|sŒ|j                  d«      sŒ-t	        j
                  d
|d   «      }
|
sŒI|
j                  d«      } n d}|j                  dd¬«      }|r|j                  «       }g }|�r4t        |d«      }|j                  dd¬«      D �]  }|d   j                  «       Št        ˆfd„dD «       «      sŒ,‰j                  d«      s­‰j                  d«      r
t        ‰z   Šn’‰j                  d«      rfddl}|j                  d«      }‰j                  d«      r)‰dd Š|r|j                  «        ‰j                  d«      rŒ)‰|d<   dj!                  |«      Šn|j#                  dd«      d   dz   ‰z   Š|j%                  |j                  d¬«      xs d‰dœ«       �Œ |||||d œS )!zParse detail page content.úhtml.parserr(   ÚdivrD   )Úclass_T©r2   ÚdescÚspanz(\d{4}[-/]\d{1,2}[-/]\d{1,2})r&   )ÚPubDateÚpublishdatezdc.dateÚmetaÚname)Úattrsr)   zcontent-wrapperÚa)rC   rC   c              3   óB   •K  — | ]  }|‰j                  «       v –— Œ y ­w©N©Úlower©Ú.0ÚextÚahrefs     €r    ú	<genexpr>zparse_detail.<locals>.<genexpr>™   s   øè ø€ Òn¨C�3˜%Ÿ+™+›-Ô'Ñnùó   ƒ©z.pdfz.docz.docxz.xlsz.xlsxz.zipz.rarr+   r-   r,   r   Né   éÿÿÿÿu   é™„ä»¶)rD   r   ©rD   Údater)   ÚattachmentsÚ
source_url)r   ÚfindÚget_textÚfind_allr/   r<   r1   ÚgetÚdecode_contentsr2   Úanyr4   r5   r7   r8   r9   r;   Úrsplitr:   )r@   r   ÚsouprD   Ú	title_divÚpub_dateÚdesc_divÚspansÚsÚtextrB   Ú	meta_namerW   Úcontent_htmlÚcontent_wrapperrj   ÚcsoupÚa_tagr7   rF   rb   s                       @r    Úparse_detailr   m   s€  ø€ ä˜˜}Ó-€Dð €EØ—	‘	˜%¨�	Ó0€IÙØ×"Ñ"¨Ð"Ó.ˆð €HØ�y‰y˜ vˆyÓ.€HÙØ×!Ñ! &Ó)ˆØò 	ˆAØ—:‘: D�:Ó)ˆDÜ—	‘	Ð:¸DÓAˆAÚØŸ7™7 1›:�Ùð	ñ Ø>ò 	ˆIØ—9‘9˜V¨F°IÐ+>�9Ó?ˆDÚ˜Ÿ™ Õ+Ü—I‘IÐ>ÀÀYÁÓP�ÚØ Ÿw™w q›z�HÙð	ð €LØ—i‘i Ð.?�iÓ@€OÙØ&×6Ñ6Ó8ˆð €KÚÜ˜l¨MÓ:ˆØ—^‘^ C¨d�^Ó3ó 	ˆEØ˜&‘M×'Ñ'Ó)ˆEÜÓnÐ3mÔnÕnØ×'Ñ'¨Ô/Ø×'Ñ'¨Ô,Ü (¨5Ñ 0™Ø×)Ñ)¨%Ô0ã(Ø #§	¡	¨#£˜Ø#×.Ñ.¨uÔ5Ø$)¨!¨" I˜EÙ$Ø %§	¡	¤ð $×.Ñ.¨uÕ5ð %*˜˜b™	Ø #§¡¨£™à #§
¡
¨3°Ó 2°1Ñ 5¸Ñ ;¸eÑ C˜Ø×"Ñ"Ø"Ÿ^™^°$˜^Ó7ÒC¸8Ø ñ$ö ð%	ð0 ØØØ"Øñð r"   c                 ó  ‡
— | rt        | j                  «       «      dk  rdj                  ||«      S t        | d«      }g }|j                  D �]Å  }|j
                  €%|j                  «       }|sŒ#|j                  |«       Œ5|j
                  dk(  r(|j                  dd¬«      }|sŒZ|j                  |«       Œl|j
                  d	k(  rHt        |«      }|j                  d
||j                  d«      d j                  dd«      d   z   dz   «       ŒÃ|j
                  dk(  r(|j                  dd¬«      }|sŒè|j                  |«       Œú|j
                  dk(  s�Œ|j                  dd«      Š
|j                  d¬«      }|s�Œ3‰
s�Œ7‰
j                  d«      r�ŒJt        ˆ
fd„dD «       «      r#|j                  dj                  |‰
«      «       �Œ�‰
j                  d«      r#|j                  dj                  |‰
«      «       �Œµ|j                  |«       �ŒÈ dj                  d„ |D «       «      j                  «       }	t        j                   dd|	«      }	t        |	j                  «       «      dk  rdj                  ||«      S |	S )z9Convert HTML to readable text with paragraphs and tables.é2   ú[{}]({})rO   NrH   ú TrR   Útablez<table>ú>z</table>r&   r   rP   rZ   rC   r(   r*   c              3   óB   •K  — | ]  }|‰j                  «       v –— Œ y ­wr\   r]   r_   s     €r    rc   z!render_content.<locals>.<genexpr>Ô   s   øè ø€ Òr°�s˜eŸk™k›mÔ+Ñrùrd   re   r+   z

c              3   ó&   K  — | ]	  }|sŒ|–— Œ y ­wr\   © )r`   rH   s     r    rc   z!render_content.<locals>.<genexpr>Û   s   è ø€ Ò/˜qªQœÑ/ùs   ‚Šz\n{3,}r   )Úlenr2   r   r   ÚchildrenrX   r:   rm   Ústrr=   rr   ro   r4   rq   r;   r/   Úsub)r{   rD   r   rs   rF   Úelry   Ú
table_htmlÚatextÚresultrb   s             @r    Úrender_contentr‘   ·   s  ø€ áœ3˜|×1Ñ1Ó3Ó4°rÒ9Ø× Ñ  ¨Ó,Ð,ä˜ }Ó5€DØ€Eà�m‰mó (ˆØ�7‰7ˆ?Ø—8‘8“:ˆDÚØ—‘˜TÕ"Ø�W‰W˜Š^Ø—;‘;˜s¨$�;Ó/ˆDÚØ—‘˜TÕ"Ø�W‰W˜Òä˜R›ˆJØ�L‰L˜ Z°
×0@Ñ0@ÀÓ0EÐ0FÐ%G×%NÑ%NÈzÐ[\Ó%]Ð^_Ñ%`Ñ`ÐcmÑmÕnØ�W‰W˜ÒØ—;‘;˜s¨$�;Ó/ˆDÚØ—‘˜TÕ"Ø�W‰W˜Œ^Ø—F‘F˜6 2Ó&ˆEØ—K‘K d�KÓ+ˆEÛ› u×'7Ñ'7¸Ö'EÜÓrÐ7qÔrÔrØ—L‘L ×!2Ñ!2°5¸%Ó!@ÖAØ×%Ñ% fÔ-Ø—L‘L ×!2Ñ!2°5¸%Ó!@ÖAà—L‘L Ö'ð5(ð8 �[‰[Ñ/ EÔ/Ó/×5Ñ5Ó7€FÜ�V‰V�I˜v vÓ.€Fä
ˆ6�<‰<‹>Ó˜RÒØ× Ñ  ¨Ó,Ð,Ø€Mr"   c                  ój   — t        t        j                  «      dkD  xr t        j                  d   dk(  S )Nr&   Úincremental)r‰   ÚsysÚargvrˆ   r"   r    Úis_incrementalr–   ã   s'   € ÜŒs�x‰x‹=˜1ÑÒ=¤§¡¨!¡°Ñ!=Ð=r"   c                  óÚ	  — t        «       } t        dj                  t        | t        «      «       g }t        dt        dz   «      D ]ª  }|dk(  rdj                  t        t        «      }ndj                  t        t        |dz
  «      }t        dj                  ||«      «       	 t        |«      }t        |«      }t        dj                  t        |«      «      «       |s n|j                  |«       Œ¬ t        dj                  t        |«      «      «       |st        d	«       y | rÛt        j                  «       t        t         ¬
«      z
  }t        dj                  |j#                  «       «      «       g }t%        |«      D ]X  \  }	\  }
}}	 t        |«      }t'        ||«      }|d   }|r0	 t        j(                  |d«      }||k\  r|j+                  |
||f«       ŒZ |}t        dj                  t        |«      «      «       n	 g }t%        |«      D ]‡  \  }	\  }
}}t        dj                  |	dz   t        |«      |
d d «      «       	 t        |«      }t'        ||«      }|d   s|
|d<   |d   s||d<   t/        |d   |d   |«      |d<   |j+                  |«       Œ‰ t        dj                  t        |«      «      «       |st        d«       y t1        j2                  dddd¬«      }dj                  t        t        |«      «      }|D ]X  }|d   |d   |d   |d   t        |d   |j5                  dg «      dœ}|j7                  t9        j:                  |d¬ «      d!z   «       ŒZ |j=                  «        t        d"j                  |j>                  «      «       tA        jB                  d#j                  |j>                  |«      «      }|d$k(  rt        d%«       n/t        d&j                  |«      «       tE        jF                  d«       	 tA        jH                  |j>                  «       y # t        $ r%}t        dj                  |«      «       Y d }~�Œd }~ww xY w# t,        $ r |j+                  |
||f«       Y �Œ›w xY w# t        $ r Y �Œw xY w# t        $ rL}t        dj                  |«      «       |j+                  |
|dj                  |
|«      g |dœ«       Y d }~�ŒÉd }~ww xY w# tJ        $ r Y y w xY w)'Nz2[{}] Starting crawl (incremental={}, max_pages={})r&   z{}{}/index.htmz{}{}/index_{}.htmz  Fetching page {}: {}z    ERROR: {}z    Found {} itemsz
  Total items from list: {}z  No items found, exiting)Údaysz  Incremental mode: cutoff = {}ri   ú%Y-%m-%dz$  After incremental filter: {} itemsz  [{}/{}] Fetching: {}...é(   r‚   rh   rD   r)   z
  Total valid items: {}z  No items to import, exitingÚwz.jsonlFz/tmp)ÚmodeÚsuffixÚdeleteÚdiru
   {} ({}æ�¡)rk   rj   )rD   Úpage_urlr)   Úpublish_dateÚ	site_namerk   rj   )Úensure_asciiú
z  JSONL written: {}z3python3 /root/gov_crawler/import_jsonl.py '{}' '{}'r   z  OK Import completez  FAIL Import failed (exit={}))&r–   Úprintr   Ú	SITE_NAMEÚ	MAX_PAGESÚranger5   r6   r!   r   rM   r‰   Úextendr   Únowr   ÚINCREMENTAL_DAYSri   Ú	enumerater   Ústrptimer:   Ú
ValueErrorr‘   ÚtempfileÚNamedTemporaryFilero   ÚwriteÚjsonÚdumpsÚcloserX   ÚosÚsystemr”   ÚexitÚunlinkÚOSError)r“   Ú	all_itemsÚpager    r@   ÚerA   Úcutoff_dateÚfilteredÚidxrD   r   Ú_ÚdetailÚdÚdtÚresultsÚdate_from_listÚtmpÚlabelr   ÚlineÚrets                          r    ÚmainrÊ   ç   s™  € Ü Ó"€KÜ	Ð
>×
EÑ
EÄiÐQ\Ô^gÓ
hÔið €IÜ�aœ Q™Ó'ò  ˆØ�1Š9Ø'×.Ñ.¬x¼ÓC‰Hð +×1Ñ1´(¼IÀtÈaÁxÓPˆHäÐ&×-Ñ-¨d°HÓ=Ô>ð	Ü˜“?ˆDô ˜4Ó ˆÜÐ"×)Ñ)¬#¨e«*Ó5Ô6ÙÙØ×Ñ˜Õð# ô& 
Ð
)×
0Ñ
0´°Y³Ó
@ÔAÙÜÐ)Ô*Øñ Ü—l‘l“n¤yÔ6FÔ'GÑGˆÜÐ/×6Ñ6°{×7GÑ7GÓ7IÓJÔKàˆÜ$-¨iÓ$8ò 	Ñ ˆC‘�%˜˜aðÜ˜S“z�Ü% d¨CÓ0�Ø˜6‘N�Ùð9Ü%×.Ñ.¨q°*Ó=˜Ø Ò,Ø$ŸO™O¨U°C¸¨OÔ<øð	ð ˆ	ÜÐ4×;Ñ;¼CÀ	»NÓKÕLð 	ð €GÜ-6°yÓ-Aò Ñ)ˆÑ)ˆe�S˜.ÜÐ)×0Ñ0°°q±¼#¸i».È%ÐPSÐQSÈ*ÓUÔVð		Ü˜“:ˆDô ˜d CÓ(ˆØ�gŠØ#ˆF�7‰OØ�fŠ~Ø+ˆF�6‰Nä*¨6°)Ñ+<¸fÀW¹oÈsÓSˆˆyÑØ�‰�vÕð)ô, 
Ð
%×
,Ñ
,¬S°«\Ó
:Ô;ÙÜÐ-Ô.Øô ×
%Ñ
%¨3°xÈÐSYÔ
Z€CØ×Ñ¤	¬3¨w«<Ó8€EØò 
?ˆà�w‘ZØ˜,™Ø˜‘|Ø˜f™IÜ"Ø˜L™/ØŸ5™5 °Ó3ñ
ˆð 	�	‰	”$—*‘*˜T°Ô6¸Ñ=Õ>ð
?ð ‡I�I„KÜ	Ð
×
&Ñ
& s§x¡xÓ
0Ô1ô �)‰)ÐI×PÑPÐQT×QYÑQYÐ[`ÓaÓ
b€CØ
ˆa‚xÜÐ$Õ%äÐ.×5Ñ5°cÓ:Ô;Ü�‰�ŒðÜ
�	‰	�#—(‘(Õøô ò 	Ü�/×(Ñ(¨Ó+Ô,Ýûð	ûô< &ò 9Ø Ÿ™¨°°Q¨×8ð9ûäò Úðûô ò 	Ü�/×(Ñ(¨Ó+Ô,Ø�N‰NØ¨Ø%×,Ñ,¨U°CÓ8Ø!°ñô õ
 ûð	ûôd ò Ùðúss   Â!P!Æ	Q6Æ(/QÉRÐS Ð!	QÐ*Q
Ñ
QÑQ3Ñ/Q6Ñ2Q3Ñ3Q6Ñ6	RÒRÒ	SÒASÓSÓ	S*Ó)S*c                 óX   — 	 t        j                  | d«      }||k\  S # t        $ r Y yw xY w)Nr™   T)r   r­   r®   )Údate_strÚcutoffrÂ   s      r    Ú_date_filterrÎ   [  s5   € ðÜ×Ñ˜h¨
Ó3ˆØ�F‰{ÐøÜò Ùðús   ‚ �	)¨)Ú__main__)Ú__doc__rµ   r/   r²   r”   r   r¯   r   r   Úbs4r   r5   r6   r¦   r«   r§   ÚPER_PAGEÚHEADERSr   r!   r$   rM   r   r‘   r–   rÊ   rÎ   Ú__name__rˆ   r"   r    ú<module>rÕ      s™   ðñ÷ /× .× .ß (Ý à#€Ø€	Ø$€	ØÐ Ø€	Ø€ð 	Ð
{ð€ò PÐRYÑY€	ò"òò=ò@GòT)òX>òqòhð ˆzÒÙ…Fð r"   