Ë
    ¸¬uj9  ã                   óÚ   — 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ZddlmZ ddl	m
Z
mZ dZ ej                  dd«      ZdZd	Zd
ZddddœZdZd„ Zd„ Zd„ Zd„ Zd„ Zedk(  r e«        yy)u  Crawler for ä¹Œå…°å¯Ÿå¸ƒå¸‚ç”Ÿæ€�çŽ¯å¢ƒå±€ - å�—ç�†å…¬ç¤º (slgs13)
API: POST /rmt/tmpl/api/site/{siteId}/channelid/{channelId}
Content-Type: application/json
Body: {"currpage": N, "pagesize": 9, "params": "..."}
Detail: <div id="content"> with full HTML + PDF attachments
é    N)Údatetime)ÚThreadPoolExecutorÚas_completedu+   ä¹Œå…°å¯Ÿå¸ƒå¸‚ç”Ÿæ€�çŽ¯å¢ƒå±€-å�—ç�†å…¬ç¤ºÚ	SEARCH_DBz/root/search.dbz}https://sthjj.wulanchabu.gov.cn/rmt/tmpl/api/site/34f332e2d1d142309c4b49e54103c4c6/channelid/37c36539d83443ff95b94a6dba9c9552Á   5186ec152b6fdbf8f9925254821388e33f1bf26f04b05fd746e5575a4111485e17dfbdc2e13666401fa60e98f783528276699fa580e601be852d2feac106fe9e0fff607a5aed63d1003c194190192c80b4299bdcb70d22818e92317f41b240666b09a4cbad3eeb99aac8bd71796d1895a0bb14c482c642ae7d2ce1d41492fb7501ecd379aae27643ae4ed1342128b7ee8d4d00a342fbdc88038447bd54b40880c2193091eb0d5614b7b03e9e766cacfd5a5ab8639a392eb94a37b75ebd810216752dbf729663b703e62ae4d766adb9ebab1dd89d2f63d6d53584676662f91b09c5316b1ea39084a892a9eac56a398b322b914e8e79a9f2636420aa3a72140ffed044742f155dfdf851ec44992af5fe68é	   zapplication/json;charset=utf-8ÚXMLHttpRequestú<Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36)zContent-TypezX-Requested-Withú
User-Agent)g333333Ó?g      à?c                 óP   — t        dt        j                  d«      › d| › �d¬«       y )Nú[z%H:%M:%Sz] T)Úflush)ÚprintÚtimeÚstrftime)Úmsgs    ú%/root/gov_crawler/crawl_wulanchabu.pyÚlogr      s#   € Ü	ˆAŒd�m‰m˜JÓ'Ð(¨¨3¨%Ð
0¸Ö=ó    c                 ó”  — | t         t        dœ}	 t        j                  t        |t
        d¬«      }|j                  «       }|j                  d«      dk7  r$t        d	| › d|j                  d
«      › �«       g dfS |j                  dg «      }||j                  dd«      fS # t        $ r}t        d| › d|› �«       g dfcY d}~S d}~ww xY w)z%Fetch one page of list data from API.)ÚcurrpageÚpagesizeÚparamsé   )ÚjsonÚheadersÚtimeoutz  API error page ú: r   NÚerrcodez  API err page ÚerrmsgÚdataÚtotal)
ÚPER_PAGEÚPARAMSÚrequestsÚpostÚAPI_URLÚHEADERSr   Ú	Exceptionr   Úget)Úpage_numÚpayloadÚrr!   ÚeÚitemss         r   Úcrawl_list_pager0   "   sÄ   € à#´ÄVÑL€GðÜ�M‰Mœ'¨¼È"ÔMˆØ�v‰v‹xˆð
 ‡x�x�	Ó˜aÒÜˆo˜h˜Z r¨$¯(©(°8Ó*<Ð)=Ð>Ô?Ø�1ˆuˆà�H‰H�V˜RÓ €EØ�$—(‘(˜7 AÓ&Ð&Ð&øô ò ÜÐ ˜z¨¨A¨3Ð/Ô0Ø�1ˆu�ûðús   �1B Â	CÂ(CÂ<CÃCc                 óÌ  — 	 t        j                  | ddid¬«      }d|_        |j
                  }t        j                  d|«      }t        j                  d|«      }t        j                  d|«      }|r|j                  d«      j                  «       nd}|r"|j                  d«      j                  «       dd nd}|r|j                  d«      j                  «       nd}	t        j                  d|«      }
|
s|||	dfS |j                  d|
j                  «       «      }|dk(  r|||	dfS d}|dz   }|t        |«      k  re|dkD  r`|||dz    dk(  r|dz  }|dz  }n6|||dz    dk(  r&|dz   t        |«      k  r||dz      dv r|dz  }|dz  }n|dz  }|t        |«      k  r|dkD  rŒ`||
j                  «       |dz    }|||	|fS # t        $ r}t	        d| dd › d	|› �«       Y d}~y
d}~ww xY w)z Crawl a detail page for content.r   r
   r   ©r   r   zutf-8z  ERROR fetch Né<   r   )Ú r4   r4   r4   z+<meta name="ArticleTitle" content="([^"]*)"z&<meta name="PubDate" content="([^"]*)"z,<meta name="ContentSource" content="([^"]*)"é   r4   é
   zid="content"ú>éÿÿÿÿr   é   z</div>é   z<div)ú r7   ú
ú	úú'ú")r%   r*   Úencodingr)   r   ÚtextÚreÚsearchÚgroupÚstripÚfindÚstartÚlen)Úurlr-   r.   ÚhtmlÚtitle_mÚdate_mÚsrc_mÚtitleÚpub_dateÚsourceÚmÚgt_posÚdepthÚiÚcontents                  r   Úcrawl_detailrW   4   s  € ðÜ�L‰L˜ØÐXð'
àôˆð ˆŒ
ð
 �6‰6€Dä�i‰iÐFÈÓM€GÜ�Y‰YÐ@À$ÓG€FÜ�I‰IÐEÀtÓL€Eá(/ˆG�M‰M˜!Ó×"Ñ"Ô$°R€EÙ/5ˆv�|‰|˜A‹×$Ñ$Ó& s¨Ñ+¸2€HÙ',ˆU�[‰[˜‹^×!Ñ!Ô#°"€Fô 	�	‰	�/ 4Ó(€AÙØ�h ¨Ð*Ð*à�Y‰Y�s˜AŸG™G›IÓ&€FØ�‚|Ø�h ¨Ð*Ð*à€EØ�‰
€AØ
Œc�$‹iŠ-˜E AšIØ��!�A‘#ˆ;˜(Ò"Ø�Q‰JˆEØ�‰F‰AØ�!�A�a‘Cˆ[˜FÒ" q¨1¡u¬s°4«yÒ'8¸TÀ!ÀAÁ#¹YÐJpÑ=pØ�Q‰JˆEØ�‰F‰Aà�‰FˆAð Œc�$‹iŠ-˜E A›Ið �1—7‘7“9˜Q˜q™SÐ!€GØ�(˜F GÐ+Ð+øôI ò Üˆn˜S  "˜X˜J b¨¨Ð,Ô-Üûðús   ‚!F< Æ<	G#ÇGÇG#c                 ó¼  — t        j                  t        d¬«      }|j                  d«       |j                  d«       |j	                  «       }d}| D ]C  }	 |j                  dt
        |d   |d   |d	   t
        |d
   f«       |j                  dkD  r|dz  }ŒE |j                  «        |j                  «        |S # t        $ r}t        d|› �«       Y d }~Œ„d }~ww xY w)Nr3   )r   zPRAGMA journal_mode=WALzPRAGMA busy_timeout=5000r   zžINSERT OR IGNORE INTO gov_raw 
                   (site_name, title, page_url, publish_date, source_url, content)
                   VALUES (?, ?, ?, ?, ?, ?)rO   rJ   ÚdaterV   r5   z  ERROR insert: )Úsqlite3ÚconnectÚDB_PATHÚexecuteÚcursorÚ	SITE_NAMEÚrowcountr)   r   ÚcommitÚclose)r/   ÚconnÚcurÚinsertedÚitemr.   s         r   Ú
save_to_dbrg   b   sÜ   € Ü�?‰?œ7¨BÔ/€DØ‡L�LÐ*Ô+Ø‡L�LÐ+Ô,Ø
�+‰+‹-€Cà€HØò (ˆð
	(Ø�K‰Kð0ô ˜D ™M¨4°©;¸¸V¹ÄiÐQUÐV_ÑQ`Ðaô	ð �|‰|˜aÒØ˜A‘�øð(ð 	‡K�K„MØ‡J�J„LØ€Oøô ò 	(ÜÐ" 1 #Ð&×'Ñ'ûð	(ús   ÁA B:Â:	CÃCÃCc                  óx  — t        dt        › �«       t        dt        › �«       t        d«       	 t        j                  dddid¬«      } t        j                  d	| j                  «      }|rt        |j                  d
«      «      nd}t        ddd«      j                  «       dz  }|dkD  r|t        z   d
z
  t        z  nd}t        d|› d|› d�«       g }d
}||k  �r'|d
kD  r)t        j                  t        j                   t"        Ž «       t%        |«      \  }}|st        d|› d�«       nÙ|d   j	                  dd«      }	|	|k  rz|D ])  }
|
j	                  dd«      |k\  sŒ|j'                  |
«       Œ+ t        d|› dt)        |«      › dt)        |D �cg c]  }|j	                  dd«      |k\  sŒ|‘Œ c}«      › d�«       nE|j+                  |«       |dz  dk(  s|d
k(  rt        d|› dt)        |«      › d�«       |d
z  }||k  r�Œ't        dt)        |«      › �«       t        d«       g }d„ }t-        d ¬!«      5 }|D �cg c]  }|j/                  ||«      ‘Œ }}t1        t3        |«      «      D ]R  \  }}|j'                  |j5                  «       «       |d
z   dz  dk(  s|dk(  sŒ6t        d"|d
z   › d#t)        |«      › �«       ŒT 	 d d d «       t        d$«       t7        |«      }t        d%«       t        d&t)        |«      › �«       t        d'|› d(�«       t        d)«       y #  d}Y �ŒšxY wc c}w c c}w # 1 sw Y   ŒpxY w)*NzStarting crawl for zDB: z=== Phase 1: Get list (API) ===ú'https://sthjj.wulanchabu.gov.cn/slgs13/r   r
   r   r2   ztotalcount:\s*(\d+)r5   r   iç  r9   é   éè  éD   zTotal: z items, z pages max, cutoff: 2023-06-17z  Page z: empty, stoppingr8   Ú	inputTimez: reached cutoff (z kept)r6   z: collected z itemszTotal articles from API: z$
=== Phase 2: Crawl detail pages ===c                 ó˜  — | j                  dd«      }d|› d�}	 t        |«      \  }}}}|s=| j                  d«      r,| d   dz  }t        j                  |«      j	                  d«      }||xs | j                  dd«      ||xs d	|xs dd
œS # t
        $ r3}t        d|› d|› �«       || j                  dd«      dddd
œcY d }~S d }~ww xY w)NÚdocnor4   ri   z.htmlrm   rk   z%Y-%m-%drO   u   ä¹Œå…°å¯Ÿå¸ƒå¸‚ç”Ÿæ€�çŽ¯å¢ƒå±€)rJ   rO   rY   rQ   rV   z  ERROR r   )r*   rW   r   Úfromtimestampr   r)   r   )	Úartro   rJ   rO   rP   rQ   rV   Útsr.   s	            r   Ú	fetch_onezmain.<locals>.fetch_one®   sî   € Ø—‘˜ Ó$ˆØ7¸°w¸eÐDˆð	Ü/;¸CÓ/@Ñ,ˆE�8˜V WÙ §¡¨Ô 4Ø˜Ñ%¨Ñ,�Ü#×1Ñ1°"Ó5×>Ñ>¸zÓJ�àØÒ6 #§'¡'¨'°2Ó"6Ø Ø ÒDÐ$DØ"š= bñð øô ò 	Ü�(˜5˜'  A 3Ð'Ô(àØŸ™ ¨"Ó-ØØØñõ ûð	ús   šA2B Â	C	Â(CÂ>C	ÃC	é   )Úmax_workersz	  Detail ú/z
=== Phase 3: Save to DB ===z
=== SUMMARY ===zTotal articles: zSaved: z
 new itemszDone!)r   r_   r\   r%   r*   rC   rD   rB   ÚintrE   r   Ú	timestampr#   r   ÚsleepÚrandomÚuniformÚDELAYr0   ÚappendrI   Úextendr   ÚsubmitÚ	enumerater   Úresultrg   )r-   rR   r"   Ú	cutoff_tsÚtotal_pagesÚall_articlesÚpgr/   Ú_Úlast_tsrf   rU   Úenrichedrs   Úexecutorrq   ÚfuturesÚfutureÚsaveds                      r   Úmainr�   {   sX  € ÜÐ
œi˜[Ð)Ô*Üˆ$ŒwˆiÐÔô Ð)Ô*ðÜ�L‰LÐBØÐXðM
àôˆô �I‰IÐ,¨a¯f©fÓ5ˆÙ#$”�A—G‘G˜A“J”¨!ˆô
 ˜˜q "Ó%×/Ñ/Ó1°DÑ8€IØ8=Àº	�5œ8Ñ# aÑ'¬HÒ4Àr€KÜˆ'�%�˜  Ð-KÐLÔMà€LØ	
€BØ
�Ó
Ø�Š6Ü�J‰J”v—~‘~¤uÐ-Ô.Ü" 2Ó&‰ˆˆqÙÜ�'˜"˜Ð.Ð/Ô0Øð ˜‘)—-‘- ¨QÓ/ˆØ�YÒàò .�Ø—8‘8˜K¨Ó+¨yÓ8Ø ×'Ñ'¨Õ-ð.ô �'˜"˜Ð/´°E³
¨|¸8ÄCÐTYÖHÈqÐ]^×]bÑ]bÐcnÐopÓ]qÐu~Ó]~ÊÒHó  EAð  DBð  BHð  Iô  JØà×Ñ˜EÔ"Ø�‰7�aŠ<˜2 š7Ü�'˜"˜˜\¬#¨lÓ*;Ð)<¸FÐCÔDØ
ˆa‰ˆð+ �Ô
ô. Ð
#¤C¨Ó$5Ð#6Ð7Ô8ô Ð/Ô0Ø€Hòô2 
¨Ô	*ð ;¨hØ>JÖK°s�8—?‘? 9¨cÕ2ÐKˆÐKÜ"¤<°Ó#8Ó9ò 	;‰IˆAˆvØ�O‰O˜FŸM™M›OÔ,Ø�A‘˜‰|˜qÒ  A¨£FÜ�i  !¡˜u A¤c¨,Ó&7Ð%8Ð9Õ:ñ	;÷;ô Ð'Ô(Ü�xÓ €EäÐ
ÔÜÐ
œ3˜x›=˜/Ð*Ô+Üˆ'�%�˜
Ð#Ô$Üˆ%…Møð]Ø‹üò0 I@ùòP L÷;ð ;ús=   ±AL ÆL&Æ,L&È7L0È<L+ÉAL0Ê!L0ÌL#Ì+L0Ì0L9Ú__main__)Ú__doc__r%   r   rC   rZ   r   rz   Úosr   Úconcurrent.futuresr   r   r_   Úgetenvr\   r'   r$   r#   r(   r|   r   r0   rW   rg   r�   Ú__name__© r   r   ú<module>r•      s›   ðñó Û Û 	Û Û Û Û 	Ý ß ?à9€	Ø
ˆ"�)‰)�KÐ!2Ó
3€ð J€ð 
l€Ø€à4Ø(ØPñ€ð
 	€ò>ò'ò$+,ò\ò2Zðz ˆzÒÙ…Fð r   