Ë
    ¸¬uj7.  ã                   óV  — 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dlZdZdZdZ ej                  «        ed¬	«      z
  j!                  d
«      ZdZdZd3d„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd4d„Zedk(  �r¡ddlZ ej>                  d¬«      Z e jC                  ddd¬«       e jC                  ddd¬«       e jC                  de"dd ¬!«       e jG                  «       Z$ e%d"«        e%d#e› �«       e$jL                  r	 e%d$«       ne$jN                  r	 e%d%«       n e%d&«        e«       Z(e(s e%d'«        ejR                  d«       e$jN                  re(dd( Z(e$jL                  r] e«       Z* e%d) e+e*«      › �«       e(D � cg c]  } | d*   e*vsŒ| ‘Œ c} Z(e(s e%d+«        ejR                  d«        e%d, e+e(«      › �«       e$jX                  dkD  re(de$jX                  d-z   Z( ee(«      Z-e-r e%d. e+e-«      › d/e› d0�«        ee-«        e%d1 e+e-«      › d2�«       yyc c} w )5u„  
crawl_lechang.py - ä¹�æ˜Œå¸‚ç”Ÿæ€�çŽ¯å¢ƒåˆ†å±€ å»ºè®¾é¡¹ç›®çŽ¯å¢ƒå½±å“�è¯„ä»·ä¿¡æ�¯ çˆ¬è™«

ç«™ç‚¹: éŸ¶å…³å¸‚ç”Ÿæ€�çŽ¯å¢ƒå±€ä¹�æ˜Œåˆ†å±€
æ �ç›®: å»ºè®¾é¡¹ç›®çŽ¯å¢ƒå½±å“�è¯„ä»·ä¿¡æ�¯
URL: http://www.lechang.gov.cn/zdlyxxgk/dzjg/sgssthjjlcfj/hjbhxxgk/jsxmhjyxpjxx/
CMS: TRS + 365cyd CDN
ç‰¹ç‚¹: CDNå�ªå…�è®¸æŸ�äº›æº�IPè®¿é—®ï¼Œåˆ—è¡¨index_N.htmlé�™æ€�åˆ†é¡µï¼Œè¯¦æƒ…content/post_XXXX.html
é    N)ÚdatetimeÚ	timedelta)Úurljoinu(   ä¹�æ˜Œå¸‚-å»ºè®¾é¡¹ç›®çŽ¯å¢ƒå½±å“�è¯„ä»·zKhttp://www.lechang.gov.cn/zdlyxxgk/dzjg/sgssthjjlcfj/hjbhxxgk/jsxmhjyxpjxx/z36.158.231.195iG  )Údaysz%Y-%m-%dz	hw-backupz/root/search.dbc                 ób  — dddt        |«      dt        |dz   «      ddt        › �dd	d
dg}| j                  d«      r|j                  | «       n|j                  t	        t
        | «      «       t        j                  |dd|dz   ¬«      }|j                  dk7  s|j                  sy|j                  S )u!   ä½¿ç”¨å›ºå®šIP + æ­£ç¡®Hostè®¿é—®Úcurlz-sLz--connect-timeoutz
--max-timeé   z	--resolvezwww.lechang.gov.cn:80:z-HzHost: www.lechang.gov.cnz-AzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36ÚhttpTé
   ©Úcapture_outputÚtextÚtimeoutr   N)
ÚstrÚ
WORKING_IPÚ
startswithÚappendr   ÚBASE_URLÚ
subprocessÚrunÚ
returncodeÚstdout)Úurlr   ÚcmdÚrs       ú"/root/gov_crawler/crawl_lechang.pyÚ	fetch_urlr      s¡   € ð 	�Ð*¬C°«L¸,ÌÈGÐTUÉIËØÐ-¬j¨\Ð:ØÐ(ØÐð	€Cð ‡~�~�fÔØ�
‰
�3�à�
‰
”7œ8 SÓ)Ô*ä�‰�s¨4°dÀGÈBÁJÔO€AØ‡|�|�qÒ §¢ØØ�8‰8€Oó    c                 ól   — | dk(  rt         }t        |«      S t        t         d| › d�«      }t        |«      S )u   èŽ·å�–åˆ—è¡¨é¡µHTMLé   Úindex_z.html)r   r   r   )Úpage_numr   s     r   Úfetch_list_pager#   .   s;   € à�1‚}Üˆô �S‹>Ðô ”h &¨¨
°%Ð 8Ó9ˆÜ�S‹>Ðr   c                 óZ  — | sg S g }t        j                  d| t         j                  «      }|sg S |j                  d«      }t        j                  dt         j                  «      }|j                  |«      D �]1  }|j                  d«      }t        j                  d|«      }|r|j                  d«      j                  «       nd}t        j                  d|«      }	|	r#|	j                  d«      }
|	j                  d«      }nnt        j                  d|t         j                  «      }|rF|j                  d«      }
t        j                  d	d|j                  d«      «      j                  «       }nŒ÷|r|
sŒü|j                  ||
j                  d
«      r|
nt        t        |
«      |dœ«       �Œ4 |S )u   ä»Žåˆ—è¡¨é¡µæ��å�–æ–‡ç« æ�¡ç›®z-<ul[^>]*class="comlist3[^"]*"[^>]*>(.*?)</ul>r    z<li[^>]*>(.*?)</li>z<span>([^<]+)</span>Ú z)<a[^>]*href="([^"]*)"[^>]*title="([^"]*)"é   z$<a[^>]*href="([^"]*)"[^>]*>(.*?)</a>ú<[^>]+>r
   )Útitler   Údate)ÚreÚsearchÚDOTALLÚgroupÚcompileÚfinditerÚstripÚsubr   r   r   r   )ÚhtmlÚitemsÚul_matchÚ
ul_contentÚ
li_patternÚli_matchÚli_htmlÚdate_mÚpub_dateÚa_mr   r(   Úa_m2s                r   Úparse_list_pager=   6   sa  € áØˆ	Ø€Eä�y‰yÐIÈ4ÔQS×QZÑQZÓ[€HÙØˆ	à—‘ Ó"€Jä—‘Ð2´B·I±IÓ>€JØ×'Ñ'¨
Ó3ó ˆØ—.‘. Ó#ˆä—‘Ð2°GÓ<ˆÙ.4�6—<‘< “?×(Ñ(Ô*¸"ˆä�i‰iÐDÀgÓNˆÙØ—)‘)˜A“,ˆCØ—I‘I˜a“L‰Eô —9‘9ÐDÀgÌrÏyÉyÓYˆDÙØ—j‘j “m�ÜŸ™˜z¨2¨t¯z©z¸!«}Ó=×CÑCÓE‘àá™CØà�‰ØØŸ.™.¨Ô0‘3´g¼hÈÓ6LØñ
ö 	ð-ð6 €Lr   c           	      ó~  — t        | d   d¬«      }|syd|v sd|v sd|v rt        d| d   › �«       yt        j                  d	|«      }|r|j	                  d
«      | d<   t        j                  d|«      }|r|j	                  d
«      dd | d<   t        j                  d|t        j
                  «      }|sy|j	                  d
«      j                  «       }t        j                  dd|«      }t        j                  dd|«      j                  «       }|rt        |«      dk  ryg }t        j                  dt        j
                  «      }|j                  |«      D ]F  }	|j                  d|	j	                  d
«      › d|	j	                  d«      j                  «       › d�«       ŒH t        j                  dt        j
                  «      }
|
j                  |«      D ]F  }|j                  d|j	                  d
«      › d|j	                  d«      j                  «       › d�«       ŒH |r|ddj                  |«      z   z  }|| d<   | S )u   çˆ¬å�–è¯¦æƒ…é¡µï¼Œæ��å�–æ­£æ–‡r   é   )r   Nu	   åˆ›å®‡ç›¾z403 ForbiddenÚ	error_403z    [CDN BLOCKED] z/<meta\s+name="ArticleTitle"\s+content="([^"]*)"r    r(   z*<meta\s+name="PubDate"\s+content="([^"]*)"r   r)   zid="content1"[^>]*>(.*?)</div>r'   r%   ú\s+zE<a[^>]*href="([^"]+\.(?:doc|docx|pdf|xls|xlsx|zip|rar))"[^>]*>([^<]+)z	<a href="z">r&   z</a>zF<a[^>]*class="nfw-cms-attachment"[^>]*href="([^"]+)"[^>]*alt="([^"]*)"u   <p>é™„ä»¶ï¼š</p>z<br>Úcontent)r   Úprintr*   r+   r-   r,   r0   r1   Úlenr.   r/   r   Újoin)Úitemr2   Útitle_mr9   Ú	content_mÚ	body_htmlÚ	body_textÚattachmentsÚdoc_patternÚdmÚnfw_patternÚnms               r   Úfetch_detailrP   `   s  € ä�T˜%‘[¨"Ô-€DÙØð �dÑ˜o°Ñ5¸ÈÑ9LÜÐ" 4¨¡; -Ð0Ô1Øô �i‰iÐJÈDÓQ€GÙØŸ™ aÓ(ˆˆW‰ô �Y‰YÐDÀdÓK€FÙØ—|‘| A“ s¨Ð+ˆˆV‰ô —	‘	Ð;¸TÄ2Ç9Á9ÓM€IÙØà—‘ Ó"×(Ñ(Ó*€Iô —‘�z 2 yÓ1€IÜ—‘�v˜r 9Ó-×3Ñ3Ó5€Iáœ˜I›¨Ò+Øð €KÜ—*‘*ÐeÔgi×gpÑgpÓq€KØ×"Ñ" 9Ó-ò QˆØ×Ñ˜Y r§x¡x°£{ m°2°b·h±h¸q³k×6GÑ6GÓ6IÐ5JÈ$ÐOÕPðQä—*‘*ÐfÔhj×hqÑhqÓr€KØ×"Ñ" 9Ó-ò QˆØ×Ñ˜Y r§x¡x°£{ m°2°b·h±h¸q³k×6GÑ6GÓ6IÐ5JÈ$ÐOÕPðQáØÐ'¨&¯+©+°kÓ*BÑBÑBˆ	à€Dˆ�OØ€Kr   c                 ó6  — | syg d¢}| D �]   }|d   dd j                  dd«      }|d   j                  dd«      }|j                  dd	«      dd
 j                  dd«      }|j                  dd	«      j                  dd«      }t        j                  dd«      }t        j                  dd|«      }t        j                  dd|«      j                  «       dd j                  dd«      }|j                  d|› d|› d|› d|› d|› d|› d�«       �Œ |j                  d«       |j                  d«       dj                  |«      }	d}
d}t        |
dd¬«      5 }|j                  |	«       ddd«       t        j                  d|
t        › d|› �gddd¬«      }|j                  d k7  rt        d!|j                  dd" › �«       y#t        j                  d$t        d%|› d&|› �gddd'¬«      }|j                  d k7  rt        d(|j                  dd › �«       y#y# 1 sw Y   Œ«xY w))uH   å°†è®°å½•æŽ¨é€�åˆ°è¿œç«¯æœ�åŠ¡å™¨çš„search.dbï¼ˆé€šè¿‡ä¸´æ—¶SQLæ–‡ä»¶ï¼‰N)zPRAGMA journal_mode=WAL;zPRAGMA synchronous=NORMAL;zBEGIN TRANSACTION;r(   iô  ú'z''r   r)   r%   r   rB   r'   ú rA   i,  z‚INSERT OR IGNORE INTO gov_raw (site_name, source_url, page_url, title, publish_date, summary, content, status, category) VALUES ('z', '', 'z', 'z', 'active', '');zCOMMIT;z¦INSERT INTO gov_search(rowid, title, site_name, summary) SELECT r.id, r.title, r.site_name, r.summary FROM gov_raw r WHERE r.id NOT IN (SELECT rowid FROM gov_search);ú
z/tmp/lechang_insert.sqlÚwzutf-8)ÚencodingÚscpú:Té   r   r   zscp error: éd   FÚsshzsqlite3 /root/search.db < z
 && rm -f é<   zsqlite error: )ÚreplaceÚgetÚ	SITE_NAMEr*   r1   r0   r   rE   ÚopenÚwriter   r   ÚREMOTE_HOSTr   rC   Ústderr)ÚrecordsÚ	sql_linesr   r(   r   r)   rB   ÚsourceÚsummaryÚsql_contentÚ	local_sqlÚ
remote_sqlÚfÚr2s                 r   Úpush_to_serverrm   ‘   sJ  € áØò a€IØó 
ˆØ�'‘
˜4˜CÐ ×(Ñ(¨¨dÓ3ˆØ�‰h×Ñ˜s DÓ)ˆØ�u‰u�V˜RÓ   "Ð%×-Ñ-¨c°4Ó8ˆØ—%‘%˜	 2Ó&×.Ñ.¨s°DÓ9ˆÜ×"Ñ" 3¨Ó-ˆä—&‘&˜ S¨'Ó2ˆÜ—&‘&˜  gÓ.×4Ñ4Ó6°t¸Ð<×DÑDÀSÈ$ÓOˆà×Ñðà�x˜x¨ u¨D°°°t¸D¸6ð BØˆy˜˜W˜IÐ%6ð8ö	
ð
ð  ×Ñ�YÔð ×Ñð	Kôð —)‘)˜IÓ&€Kà)€IØ*€Jä	ˆi˜ wÔ	/ð °1Ø	�‰�Ô÷ô 	�‰˜˜y¬[¨M¸¸:¸,Ð*GÐHÐY]ÐdhÐrtÔu€AØ‡|�|�qÒÜ�˜AŸH™H T c˜NÐ+Ð,Ô-Øä	�‰˜¤Ø5°j°\ÀÈJÈ<ÐXðZà'+°$Àô
D€Bð 
‡}�}˜ÒÜ�˜rŸy™y¨¨#˜Ð/Ð0Ô1àØ÷ð ús   ÅHÈHc                  ó  — g } d}	 t        d|› d�dd¬«       t        |«      }|st        d«       n¸t        |«      }|st        d«       nŸt        t        |«      › d	|d
   d   › d|d   d   › �«       |D ]&  }|d   sŒ	|d   t        k\  sŒ| j                  |«       Œ( |d   d   r#|d   d   t        k  rt        dt        › d�«       n!|dz  }|dkD  rnt        j                  d«       Œãt        dt        | «      › d�«       | S )u4   Phase 1: æ‰«æ��åˆ—è¡¨é¡µï¼Œæ”¶é›†æ‰€æœ‰3å¹´å†…æ–‡ç« r    Tz
List page ú...rS   ©ÚendÚflushzFAIL (empty)zEND (no items)z items, r   r)   ú~éÿÿÿÿz  Cutoff reached (z), stoppingé   g      à?z
Phase 1 done: z items within 3 years)rC   r#   r=   rD   ÚCUTOFF_DATEr   ÚtimeÚsleep)Ú	all_itemsÚpager2   r3   rF   s        r   Ú
run_phase1r{   Ç   s-  € à€IØ€DØ
Ü�
˜4˜& Ð$¨#°TÕ:Ü˜tÓ$ˆÙÜ�.Ô!ØÜ Ó%ˆÙÜÐ"Ô#ØÜ”�U“�˜H U¨1¡X¨fÑ%5Ð$6°a¸¸b¹	À&Ñ8IÐ7JÐKÔLð ò 	'ˆDØ�F‹|  V¡´Ó ;Ø× Ñ  Õ&ð	'ð
 �‰9�VÒ  r¡¨6Ñ!2´[Ò!@ÜÐ&¤{ m°;Ð?Ô@Øà�‰	ˆØ�"Š9Øä�
‰
�3Œð5 ô8 
ÐœS ›^Ð,Ð,AÐ
BÔCØÐr   c                 ó8  — t        | «      }|dk(  rg S g }d}d}ddlm}m}  |d¬«      5 }| D �ci c]  }|j	                  t
        |«      |“Œ }	}t         ||	«      d«      D ]o  \  }
}|	|   }	 |j                  «       }|r(|j                  d«      r|j                  |«       |dz  }n|dz  }|
dz  dk(  s|
|k(  sŒYt        d	|
› d
|› d|› d|› �«       Œq 	 ddd«       t        d|› d|› d�«       |S c c}w # t        $ r}|dz  }Y d}~Œ\d}~ww xY w# 1 sw Y   Œ=xY w)u*   Phase 2: å¹¶å�‘çˆ¬è¯¦æƒ…é¡µï¼Œæ��å�–æ­£æ–‡r   )ÚThreadPoolExecutorÚas_completedr	   )Úmax_workersr    rB   Nru   z  [ú/u   ] âœ…u    â�­ï¸�z
Phase 2 done: z with content, z skipped)rD   Úconcurrent.futuresr}   r~   ÚsubmitrP   Ú	enumerateÚresultr^   r   Ú	ExceptionrC   )r3   ÚtotalÚresultsÚok_countÚ
skip_countr}   r~   ÚexrF   ÚfuturesÚiÚfutÚdetailÚes                 r   Ú
run_phase2r�   ê   sI  € ä�‹J€EØ�‚zØˆ	à€GØ€HØ€JçCá	¨Ô	*ð K¨bØCHÖI¸4�2—9‘9œ\¨4Ó0°$Ñ6ÐIˆÐIÜ¡¨WÓ 5°qÓ9ò 	K‰FˆAˆsØ˜3‘<ˆDð ØŸ™›�Ù˜fŸj™j¨Ô3Ø—N‘N 6Ô*Ø ‘M‘Hà !‘O�Jð �2‰v˜Š{˜a 5›jÜ˜˜A˜3˜a ˜w e¨H¨:°W¸Z¸LÐIÕJñ	K÷Kô" 
Ð˜X˜J o°j°\ÀÐ
JÔKØ€Nùò# Jøô ò  Ø˜a‘•
ûð ú÷Kð KúsL   ªD¯C0ÁDÁ-?C5Â,DÂ:DÃ0DÃ5	DÃ>DÄDÄDÄDÄDc                  ó&  — ddt         › �dt        › dt        › d�g} t        j                  | ddd¬«      }|j
                  d	k(  rE|j                  r9t        d
„ |j                  j                  «       j                  d«      D «       «      S t        «       S )u   æ£€æŸ¥å·²ç»�åœ¨åº“ä¸­çš„URLr[   zroot@zsqlite3 z0 "SELECT page_url FROM gov_raw WHERE site_name='z';"TrY   r   r   c              3   ó^   K  — | ]%  }|j                  «       sŒ|j                  «       –— Œ' y ­w)N)r0   )Ú.0Úlines     r   ú	<genexpr>z!check_existing.<locals>.<genexpr>  s   è ø€ ÒY DÈDÏJÉJÍL�4—:‘:—<ÑYùs   ‚-˜-rT   )
rb   Ú	REMOTE_DBr_   r   r   r   r   Úsetr0   Úsplit)Ússh_cmdr   s     r   Úcheck_existingrš   
  s€   € à˜œk˜]Ð+Øœ)˜Ð$UÔV_ÐU`Ð`dÐeðg€Gä�‰�w¨t¸$ÈÔK€AØ‡|�|�qÒ˜QŸXšXÜÑY¨A¯H©H¯N©NÓ,<×,BÑ,BÀ4Ó,HÔYÓYÐYÜ‹5€Lr   c                 ó*  — t        dt        | «      |«      D ]z  }| |||z    }t        d||z  dz   › dt        | «      dz
  |z  dz   › dt        |«      › d�dd¬	«       t        |«      rt        d
«       nt        d«       t	        j
                  d«       Œ| y)u   åˆ†æ‰¹æŽ¨é€�åˆ°æœ�åŠ¡å™¨r   z  Pushing batch r    r€   z (z records)...rS   Trp   u   âœ…u   â�Œg333333Ó?N)ÚrangerD   rC   rm   rw   rx   )r3   Ú
batch_sizerŒ   Úbatchs       r   Ú
push_batchrŸ     s    € ä�1”c˜%“j *Ó-ò ˆØ�a˜˜*™Ð%ˆÜÐ   J¡¨q¡Ð 1°´C¸³J¸q±LÀ:Ñ3MÈaÑ3OÐ2PÐPRÔSVÐW\ÓS]ÐR^Ð^jÐkÐqtð  }Aõ  	BÜ˜%Ô Ü�%�Lä�%ŒLÜ�
‰
�3�ñr   Ú__main__u   ä¹�æ˜ŒçŽ¯è¯„çˆ¬è™«)Údescriptionz--incrementalÚ
store_trueu!   å¢žé‡�æ¨¡å¼�ï¼šå�ªçˆ¬æœ€æ–°æ�¡ç›®)ÚactionÚhelpz--testu   æµ‹è¯•æ¨¡å¼�ï¼šå�ªçˆ¬é¦–é¡µz--pagesu   æŒ‡å®šé¡µç �æ•°)ÚtypeÚdefaultr¤   u7   === ä¹�æ˜Œå¸‚-å»ºè®¾é¡¹ç›®çŽ¯å¢ƒå½±å“�è¯„ä»· çˆ¬è™« ===zCutoff: u   Mode: å¢žé‡�å¢žé‡�u   Mode: æµ‹è¯• (ä»…1é¡µ)u   Mode: å…¨é‡�zNo items foundr	   zExisting in DB: r   zNothing new to crawlzNew items to crawl: r?   z	
Pushing z records to ro   z
=== Done: z records pushed ===)rY   )é2   ).Ú__doc__Úsysr*   rw   ÚjsonÚosÚhashlibr   r   Úurllib.parser   r   r_   r   r   ÚnowÚstrftimerv   rb   r–   r   r#   r=   rP   rm   r{   r�   rš   rŸ   Ú__name__ÚargparseÚArgumentParserÚparserÚadd_argumentÚintÚ
parse_argsÚargsrC   ÚincrementalÚtestry   ÚexitÚexistingrD   Úpagesr‡   )rŒ   s   0r   ú<module>r½      s]  ðñ÷ (× '× 'ß (Ý  Û ð 7€	ØX€Ø€
Øˆx�|‰|‹~¡	¨uÔ 5Ñ5×?Ñ?À
ÓK€ð €Ø€	óò&ò(òT/òb4òl!òFò@ó	ð ˆzÓÛØ$ˆX×$Ñ$Ð1EÔF€FØ
×Ñ˜°ÐCfÐÔgØ
×Ñ˜¨Ð<YÐÔZØ
×Ñ˜	¨°QÐ=NÐÔOØ×ÑÓ€Dá	ÐCÔEÙ	ˆH�[�MÐ
"Ô#Ø×ÒÙÐ"Õ#Ø	�ŠÙÐ&Õ'áˆnÔñ “€IÙÙÐÔØˆ�‰�Œà‡y‚yØ˜b˜q�Mˆ	ð ×ÒÙ!Ó#ˆÙÐ ¡ X£ Ð0Ô1Ø )ÖF˜1¨Q¨u©X¸XÒ-E’QÒFˆ	ÙÙÐ(Ô)ØˆC�H‰H�QŒKÙÐ$¡S¨£^Ð$4Ð5Ô6à‡z�z�A‚~ØÐ.˜tŸz™z¨B™Ð/ˆ	ñ ˜Ó#€Gñ Ù�
™3˜w›<˜.¨°[°MÀÐEÔFÙ�7Ôá	ˆL™˜W›˜Ð&9Ð
:Õ;ð_ ùò< Gs   Æ	H&ÆH&