Ë
    ;{€j—#  ã                   óZ  — 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m	Z	 ddl
mZ ddlmZ dZdZdZd	Zd
Z ej&                  «        e	d¬«      z
  j)                  d«      Zej,                  j/                  dd«      ZdddœZd„ Zd„ Zd#d„Zd$d„Zd%d„Zd„ Zd„ Z d&d„Z!e"dk(  rƒejF                  dd Z$dZ%dZ&ddjO                  e$«      v r7 e( ejR                  d djO                  e$«      «      jU                  d«      «      Z%d!e$v re$e$jW                  d!«      dz      Z& e!e%e&¬"«       yy)'u-  
æ¹›æ±Ÿå¸‚é�‚æºªåŽ¿åŸŽå¸‚ç®¡ç�†å’Œç»¼å�ˆæ‰§æ³•å±€ - æ”¿åºœä¿¡æ�¯å…¬å¼€å¹³å�° å·¥ä½œåŠ¨æ€� (suixi.gov.cn/zjsxcgj/gkmlpt)
CMS: gkmlpt Vue SPA API (å�Œ cnts/fogang /gkmlpt/api/all/{categoryId})
åˆ—è¡¨: GET /gkmlpt/api/all/5971?page=N&pageSize=100  JSON (211æ�¡, 2020-05~)
è¯¦æƒ…: GET /gkmlpt/api/post/{id}  JSON (content=HTML, date=å­—ç¬¦ä¸²)
å¤–é“¾: type="url" æ�¡ç›® (å¾®ä¿¡æ–‡ç«  mp.weixin.qq.com) æŠ“ä¸�åˆ°æ­£æ–‡ -> æ ‡é¢˜+URLå†…åµŒæ®µ
æ­£æ–‡: .article-content / #zoom (HTML fallback)
ç”¨æ³•: python3 crawl_suixi_cgj_gzdt.py [--pages=N] [--json out.jsonl]
é    N)ÚdatetimeÚ	timedelta)ÚBeautifulSoup)Úurljoinu4   é�‚æºªåŽ¿åŸŽå¸‚ç®¡ç�†å’Œç»¼å�ˆæ‰§æ³•å±€-å·¥ä½œåŠ¨æ€�zhttp://www.suixi.gov.cnz3http://www.suixi.gov.cn/zjsxcgj/gkmlpt/api/all/5971zwww.suixi.gov.cnu   å¹¿ä¸œiG  )Údaysú%Y-%m-%dÚDB_PATHz/root/search.dbzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36z,http://www.suixi.gov.cn/zjsxcgj/gkmlpt/index)z
User-AgentÚRefererc                 ó2   — t        dt        › d| › �d¬«       y )Nú[z] T)Úflush)ÚprintÚ	SITE_NAME)Úmsgs    ú)/root/gov_crawler/crawl_suixi_cgj_gzdt.pyÚlogr      s   € Ü	ˆAŒiˆ[˜˜3˜%Ð
 ¨Ö-ó    c                 ó´   — t        j                  dd| xs d«      } t        j                  dd| «      } t        j                  dd| «      j                  «       } | S )Nz&nbsp;|&#160;|\u200b|\ufeffÚ z\s+ú u   \.\.\.|â€¦$)ÚreÚsubÚstrip)Úts    r   Úclean_titler       sK   € Ü
�‰Ð-¨r°1²7¸Ó;€AÜ
�‰ˆv�s˜AÓ€AÜ
�‰ˆ~˜r 1Ó%×+Ñ+Ó-€AØ€Hr   c                 ó`   — t        j                  | t        |¬«      }d|_        |j                  S )N©ÚheadersÚtimeoutúutf-8)ÚrequestsÚgetÚHEADERSÚencodingÚtext)Úurlr   Úrs      r   Úfetchr(   '   s$   € Ü�‰�S¤'°7Ô;€AØ€A„JØ�6‰6€Mr   c                 óD  — 	 t        j                  t        › d| › d|› �t        d¬«      }|j	                  «       }|j                  dg «      t        |j                  di «      j                  dd«      «      fS # t        $ r}t        d	| › d
|› �«       g dfcY d }~S d }~ww xY w)Nz?page=z
&pageSize=é   r   ÚarticlesÚclassifyÚ
post_countr   zAPI Pú ERR: )r!   r"   ÚAPI_URLr#   ÚjsonÚintÚ	Exceptionr   )ÚpageÚ	page_sizer'   ÚjÚes        r   Ú
fetch_listr7   -   s™   € ðÜ�L‰LœG˜9 F¨4¨&°
¸9¸+ÐFÔPWÐacÔdˆØ�F‰F‹HˆØ�u‰u�Z Ó$¤c¨!¯%©%°
¸BÓ*?×*CÑ*CÀLÐRSÓ*TÓ&UÐUÐUøÜò Üˆe�D�6˜ ˜sÐ#Ô$Ø�1ˆu�ûðús   ‚A4A7 Á7	BÂ BÂBÂBc                 ó´  — | syt        | d«      }|j                  dd¬«      D ]X  }|j                  dd«      }|j                  d¬«      xs d}|xs t        }t        ||«      }|j                  d	|› d
|› d�«       ŒZ |j                  g d¢«      D ]  }|j                  «        Œ g }	|j                  ddg«      D ]y  }
|
j                  dk(  r|	j                  t        |
«      «       Œ-|
j                  dk(  sŒ=|
j                  d«      rŒO|
j                  dd¬«      }|sŒe|	j                  d|› d�«       Œ{ |	rdj                  |	«      S | j                  «       S )uS   HTML -> æ–‡æœ¬, é™„ä»¶/é“¾æŽ¥ä¿�ç•™å†…åµŒURL (ç”¨æˆ·å��å¥½: HTMLå�¯ç‚¹å‡»é“¾æŽ¥æ®µ)r   úhtml.parserÚaT)Úhrefr;   ©r   u   é™„ä»¶z<p><a href="z">z</a></p>)ÚspanÚbÚstrongÚfontÚemÚiÚuÚsÚtableÚp)Ú	separatorr   ú<p>z</p>z

)r   Úfind_allr"   Úget_textÚBASE_URLr   Úreplace_withÚunwrapÚnameÚappendÚstrÚfind_parentÚjoinr   )Úcontent_htmlÚpage_urlÚsoupÚa_tagr;   r%   ÚbaseÚfull_urlÚtagÚpartsÚelr   s               r   Úextract_clean_textr\   7   sK  € áØÜ˜ }Ó5€DØ—‘˜s¨�Ó.ò FˆØ�y‰y˜ Ó$ˆØ�~‰~ Dˆ~Ó)Ò5¨XˆØÒ#œ8ˆÜ˜4 Ó&ˆØ×Ñ˜\¨(¨°2°d°V¸8ÐDÕEðFð �}‰}ÒQÓRò ˆØ�
‰
�ðà€EØ�m‰m˜W c˜NÓ+ò ,ˆØ�7‰7�gÒØ�L‰Lœ˜R›Õ!Ø�W‰W˜‹^ B§N¡N°7Õ$;Ø—‘ b°�Ó5ˆAÚØ—‘˜s 1 # T˜]Õ+ð,ñ "'ˆ6�;‰;�uÓÐ@¨L×,>Ñ,>Ó,@Ð@r   c                 ó�  — 	 t        j                  t        › d| › �t        d¬«      }|j	                  «       }t        |j                  dd«      «      }|j                  dd«      }|rt        |«      dd nd}|j                  d	d«      xs d}|rt        ||«      nd}|||fS # t        $ r}	t        d
| › d|	› �«       Y d}	~	yd}	~	ww xY w)uM   ä¼˜å…ˆ API è¯¦æƒ…; è¿”å›ž (title, publish_date, content) æˆ– (None,None,None)z/zjsxcgj/gkmlpt/api/post/r*   r   Útitler   ÚdateNé
   Úcontentz  api detail r.   )NNN)
r!   r"   rK   r#   r0   r   rP   r\   r2   r   )
Úart_idrT   r'   r5   r^   ÚdÚpubrS   ra   r6   s
             r   Úparse_detail_apire   O   sÆ   € ð Ü�L‰LœH˜:Ð%>¸v¸hÐGÔQXÐbdÔeˆØ�F‰F‹HˆÜ˜AŸE™E '¨2Ó.Ó/ˆØ�E‰E�&˜"ÓˆÙŒc�!‹f�S�b‰k BˆØ—u‘u˜Y¨Ó+Ò1¨rˆÙ@LÔ$ \°8Ô<ÐRTˆØ�c˜7Ð"Ð"øÜò  Üˆm˜F˜8 6¨!¨Ð-Ô.Üûð ús   ‚BB! Â!	CÂ*C Ã Cc                 óÜ  — ddddœ}t        | d«      }|j                  d«      }|r<|j                  d¬«      }t        j                  dd|«      }|j                  «       |d<   |j                  dd	d
i¬«      }|r|j                  d«      r|d   d d |d<   |j                  dd¬«      }|s|j                  dd¬«      }|s|j                  dd¬«      }|rt        t        |«      |«      |d<   |S )Nr   )r^   Úpublish_datera   r9   r^   Tr<   uC   [_\-â€”]\s*(å·¥ä½œåŠ¨æ€�|æ”¿åºœä¿¡æ�¯å…¬å¼€å¹³å�°|é€šçŸ¥å…¬å‘Š)\s*$ÚmetarN   ÚPubDate)Úattrsra   r`   rg   Údivzarticle-content)Úclass_Úzoom)Úid)	r   ÚfindrJ   r   r   r   r"   r\   rP   )ÚhtmlrT   ÚresultrU   Ú	title_tagr   Ú	meta_dateÚcontent_divs           r   Úparse_detail_htmlru   _   sø   € Ø¨2¸"Ñ=€FÜ˜˜}Ó-€DØ—	‘	˜'Ó"€IÙØ×Ñ TÐÓ*ˆÜ�F‰FÐYÐ[]Ð_`ÓaˆØŸ'™'›)ˆˆw‰Ø—	‘	˜&¨°Ð(;�	Ó<€IÙ�Y—]‘] 9Ô-Ø!*¨9Ñ!5°c°rÐ!:ˆˆ~ÑØ—)‘)˜EÐ*;�)Ó<€KÙØ—i‘i ¨i�iÓ8ˆÙØ—i‘i ¨&�iÓ1ˆÙÜ.¬s°;Ó/?ÀÓJˆˆyÑØ€Mr   é   c                 ó˜	  — t        d| › dt        › �«       g }t        «       }d}t        d| dz   «      D �]w  }t	        |«      \  }}d}|D �]  }|j                  d«      }	t        |j                  dd«      «      }
|j                  dd«      }|r/	 t        j                  t        |«      «      j                  d	«      }nd}|j                  dd«      }|dk(  rL|j                  dd«      xs |j                  dd«      xs d}|j                  d«      st!        t"        |«      }nt"        › d|	› d�}|sŒç||vsŒì|j%                  |«       |j'                  |
|||	|dœ«       |dz  }�Œ t        d|› dt)        |«      › d|› dt)        |«      › d|› d�«       |s nt+        j,                  d«       �Œz g }t/        |d«      D �]@  \  }}|d   r|d   t        k  rŒ|j                  d«      }|j                  d«      dk(  rU|d   }
|d   }d|
› d|› d�}|j'                  |
||d   |t0        dd œ«       |d
z  dk(  rt        d!|› d"t)        |«      › �«       Œ“	 t3        ||d   «      \  }
}}|s4t5        |d   «      }t7        ||d   «      }|
xs |d   }
|xs |d#   }|d$   }|j'                  |
xs |d   |d   |xs |d   |t0        dd œ«       |d
z  dk(  rt        d!|› d"t)        |«      › �«       t+        j,                  d(«       �ŒC |rct;        |d)d*¬+«      5 }|D ]+  }|j=                  t?        j@                  |d,¬-«      d.z   «       Œ- 	 d d d «       t        d/t)        |«      › d0|› �«       y tC        jD                  tF        «      }|jI                  d1«       |jK                  «       }dx}}|D ]W  }	 |jI                  d2|d3   |d4   |d4   |d   |d#   |d$   |d$   xs dd d5 |d6   d7f	«       |jL                  dkD  r|dz  }n|dz  }ŒY |jO                  «        |jQ                  «        t        d9|› d:|› d;�«       y # t        t        t        f$ r t        |«      d d
 }Y �Œ™w xY w# t8        $ r.}t        d%|d   d&d  › d'|› �«       |d   |d   d}}}
Y d }~�Œôd }~ww xY w# 1 sw Y   �ŒUxY w# t8        $ r}t        d8|› �«       |dz  }Y d }~�Œd }~ww xY w)<NzCrawl pages=z cutoff=r   é   rn   r^   r   r_   r   r`   ÚtypeÚnormalr&   Úpost_urlÚhttpz/zjsxcgj/gkmlpt/content/post_z.html)r^   r&   Úpub_daterb   ry   ÚPz: z items (z new), total z (post_count=ú)g333333ã?r}   rb   rH   z</p>
<p><a href="u   ">æŸ¥çœ‹åŽŸæ–‡</a></p>u   å·¥ä½œåŠ¨æ€�)r^   rT   rg   ra   Ú	site_nameÚcolumnz  ú/rg   ra   z	  detail iØÿÿÿr.   gš™™™™™Ù?Úwr    )r$   F)Úensure_asciiú
zJSONL: z
 items -> zPRAGMA busy_timeout=10000z˜INSERT OR IGNORE INTO gov_raw (site_name, source_url, page_url, title, publish_date, content, summary, category, script_name) VALUES (?,?,?,?,?,?,?,?,?)r€   rT   iô  r�   zcrawl_suixi_cgj_gzdt.pyz
DB error: zResult: z new, z skipped))r   ÚCUTOFFÚsetÚranger7   r"   r   r   Úfromtimestampr1   ÚstrftimeÚ
ValueErrorÚ	TypeErrorÚOSErrorrP   Ú
startswithr   rK   ÚaddrO   ÚlenÚtimeÚsleepÚ	enumerater   re   r(   ru   r2   ÚopenÚwriter0   ÚdumpsÚsqlite3Úconnectr	   ÚexecuteÚcursorÚrowcountÚcommitÚclose)ÚpagesÚjson_outÚ	items_allÚseenÚtotalrF   ÚartsÚnewr:   Úaidr^   Útsr}   Úatyper&   ÚenrichedÚidxÚitrb   ra   rd   rp   Úd2r6   ÚfÚitemÚconnÚcÚstoredÚskippeds                                 r   Úcrawlr²   t   sJ  € Üˆ,�u�g˜X¤f XÐ.Ô/Ø€IÜ‹5€DØ€EÜ�1�e˜a‘iÓ ó ˆÜ  “m‰ˆˆeØˆØó 	ˆAØ—%‘%˜“+ˆCÜ §¡ g¨rÓ 2Ó3ˆEØ—‘�v˜qÓ!ˆBÙð,Ü'×5Ñ5´c¸"³gÓ>×GÑGÈ
ÓS‘Hð �Ø—E‘E˜& (Ó+ˆEà˜Š~Ø—e‘e˜E 2Ó&ÒE¨!¯%©%°
¸BÓ*?ÒEÀ2�Ø—~‘~ fÔ-Ü!¤(¨CÓ0‘Cä!˜
Ð"?À¸uÀEÐJ�Ú�s $’Ø—‘˜”Ø× Ñ ¨5¸È(Ð^aÐkpÑ!qÔrØ�q‘’ð-	ô. 	ˆa�ˆs�"”S˜“Y�K˜x¨ u¨M¼#¸i».Ð9IÈÐW\ÐV]Ð]^Ð_Ô`ÙÙÜ�
‰
�3Žð;ð> €HÜ˜Y¨Ó*ó )‰ˆˆRØˆjŠ>˜b ™n¬vÒ5ØØ—‘˜Ó!ˆØ�6‰6�&‹>˜UÒ"à�w‘KˆEØ�U‘)ˆCØ˜E˜7Ð"4°S°EÐ9OÐPˆGØ�O‰OØØØ " :¡Ø"Ü&Ø(ñô ð �R‰x˜1Š}Ü�b˜˜˜Qœs 9›~Ð.Ð/Ô0Øð
	BÜ"2°6¸2¸e¹9Ó"EÑˆE�3˜ÙÜ˜R ™YÓ'�Ü& t¨R°©YÓ7�ØÒ,  G¡�ØÒ/˜R Ñ/�Ø˜Y™-�ð 	�‰ØÒ)˜b ™kØ˜5™	ØÒ1 2 j¡>ØÜ"Ø$ñ
ô 	ð �‰8�qŠ=Ü�"�S�E˜œ3˜y›>Ð*Ð+Ô,Ü�
‰
�3ŽðS)ñV Ü�(˜C¨'Ô2ð 	E°aØ ò E�Ø—‘œŸ
™
 4°eÔ<¸tÑCÕDñE÷	Eô 	ˆg”c˜(“m�_ J¨x¨jÐ9Ô:Øä�?‰?œ7Ó#€DØ‡L�LÐ,Ô-Ø�‰‹€AØÐ€FˆWØò ˆð	Ø�I‰Ið.ð �kÑ" D¨Ñ$4°d¸:Ñ6FØ�g‘  ^Ñ 4°d¸9±oØ�y‘/Ò' R¨¨#Ð.°°X±Ð@Yð[ô	\ð �z‰z˜AŠ~Ø˜!‘‘à˜1‘�øðð  	‡K�K„MØ‡J�J„LÜˆ(�6�(˜&  	¨Ð2Õ3øô} #¤I¬wÐ7ò ,Ü" 2›w s¨˜|“Hð,ûôd ò 	BÜ�)˜B˜u™I c d˜OÐ,¨F°1°#Ð6Ô7Ø"$ W¡+¨r°*©~¸r˜�3ŽEûð	Bú÷ 	Eñ 	Eûô. ò 	Ü�*˜Q˜CÐ Ô!Ø�q‰LŽGûð	úsP   Â-P2ÉA	QÌ1RÎ)AR"Ð2"QÑQÑ	RÑ$#RÒRÒRÒ"	S	Ò+SÓS	Ú__main__rx   z--pages=r   z--pages=(\d+)z--json)rž   rŸ   )r*   )éd   )N)rv   N),Ú__doc__r   ÚsysÚosr0   r‘   r—   r!   r   r   Úbs4r   Úurllib.parser   r   rK   r/   ÚDOMAINÚGROUPÚnowrŠ   r†   Úenvironr"   r	   r#   r   r   r(   r7   r\   re   ru   r²   Ú__name__ÚargvÚargsrž   rŸ   rR   r1   ÚsearchÚgroupÚindex© r   r   ú<module>rÅ      s:  ðñ÷ 2× 1× 1Ó 1ß (Ý Ý  àB€	Ø$€Ø
?€Ø	€Ø€Ø
ˆ(�,‰,‹.™9¨%Ô0Ñ
0×	:Ñ	:¸:Ó	F€Ø
�*‰*�.‰.˜Ð$5Ó
6€ð KØDñF€ò.òóóóAò0 ò ó*m4ð` ˆzÒØ�8‰8�A�Bˆ<€DØ€EØ€HØ�S—X‘X˜d“^Ñ#Ù�I�B—I‘IÐ.°·±¸³Ó?×EÑEÀaÓHÓIˆØ�4ÑØ˜Ÿ
™
 8Ó,¨qÑ0Ñ1ˆÙ	� Ö)ð r   