Ë
    €ÛµjÁ0  ã                   óª  — 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
 ddlmZ ddlZ ej                  «       Zej#                  dedd¬«       ej'                  «       \  ZZej,                  dkD  rej,                  nd	Zd
ZdZdZdZdZdZd	ZddddœZg d¢Zd„ Z d„ Z!d„ Z"d„ Z#d„ Z$d„ Z%d„ Z&d„ Z'd„ Z(d„ Z)d„ Z*d „ Z+e,d!k(  r e+«        yy)"um  
Crawler for æ€�å�—åŽ¿äººæ°‘æ”¿åºœ - é€šçŸ¥å…¬å‘Š
CMS: TRS (è´µå·žæ”¿åºœç»Ÿä¸€å¹³å�°)
List: ul.NewsList > li > a[href] + span (date)
Pagination: index_{N}.html, 20/page, ~101 pages
Detail: div.Article_Con > font#Zoom > div.trs_editor_view

Usage:
    python3 crawl_sinan_tzgg.py             # Full crawl
    python3 crawl_sinan_tzgg.py --max-pages 1  # Incremental
é    N)Údatetime)ÚBeautifulSoup)Úurljoinú--pagesu   é™�åˆ¶é¡µæ•°)ÚtypeÚdefaultÚhelpée   z/root/search.dbu"   æ€�å�—åŽ¿äººæ°‘æ”¿åºœ-é€šçŸ¥å…¬å‘Šu   é€šçŸ¥å…¬å‘Šu   è´µå·žzhttp://www.sinan.gov.cnz,http://www.sinan.gov.cn/xwzx/tzgg/index.htmlzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36z?text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8zzh-CN,zh;q=0.9,en;q=0.8)z
User-AgentÚAcceptzAccept-Language)u   ã€�æ‰“å�°æœ¬é¡µã€‘u   ã€�å…³é—­çª—å�£ã€‘u   æ‰“å�°æœ¬é¡µu   å…³é—­çª—å�£u   è½¬è½½åˆ†äº«ï¼šu   æµ�è§ˆé‡�ï¼šu   ç›¸å…³é™„ä»¶ï¼šu   ç›¸å…³ç¨¿ä»¶ï¼šu   æ‰«ä¸€æ‰«åœ¨æ‰‹æœºæ‰“å¼€u	   é™„ä»¶ï¼šu   ç´¯è®¡æ¬¡æ•°ï¼šu	   å­—å�·ï¼šc                 óD  — g }| j                   D �]p  }t        |t        «      r%|j                  «       }|sŒ'|j	                  |«       Œ9|j
                  dk(  rp|j                  dd«      j                  «       }|j                  d¬«      }|r'|r%t        ||«      }|j	                  d|› d|› d�«       Œ£|sŒ¦|j	                  |«       Œ¸|j
                  d	k(  rR|j                  d
d«      }|sŒÜ|j                  dd«      }	t        ||«      }
|j	                  |	rd|
› d�nd|
› d�«       �Œ|j
                  dk(  r|j	                  d«       �Œ;t        |d«      s�ŒI|j                  dd¬«      }|s�Œ`|j	                  |«       �Œs dj                  |«      j                  «       S )NÚaÚhrefÚ T©Ústripú<p><a href="ú">ú</a></p>ÚimgÚsrcÚaltõ   ">æŸ¥çœ‹å›¾ç‰‡</a></p>Úbrú
Úget_textú )ÚchildrenÚ
isinstanceÚstrr   ÚappendÚnameÚgetr   r   ÚhasattrÚjoin)Úp_tagÚ
detail_urlÚpartsÚelemÚtr   ÚtextÚfullr   r   Úfull_srcs              ú%/root/gov_crawler/crawl_sinan_tzgg.pyÚrender_paragraphr.   3   sv  € Ø€EØ—‘ó  ˆÜ�dœCÔ Ø—
‘
“ˆAÚØ—‘˜Q•Ø�Y‰Y˜#ÒØ—8‘8˜F BÓ'×-Ñ-Ó/ˆDØ—=‘= t�=Ó,ˆDÙ™Ü˜z¨4Ó0�Ø—‘˜|¨D¨6°°D°6¸ÐBÕCÚØ—‘˜TÕ"Ø�Y‰Y˜%ÒØ—(‘(˜5 "Ó%ˆCÚØ—h‘h˜u bÓ)�Ü" :¨sÓ3�Ø—‘ÑPS˜|¨H¨:Ð5KÑLÐ[gÐhpÐgqð  rHð  ZIö  JØ�Y‰Y˜$ÒØ�L‰L˜ÖÜ�T˜:Ö&Ø—‘˜c¨�Ó.ˆAÛØ—‘˜Q–ð1 ð2 �8‰8�E‹?× Ñ Ó"Ð"ó    c                 óÊ   — g }| j                  d«      D ]L  }t        |«      }t        |j                  d¬«      «      dk\  r|j	                  |«       |j                  «        ŒN |S )NÚtableTr   é   )Úfind_allr   Úlenr   r    Ú	decompose)Úcontent_divr&   Útablesr1   Ú
table_htmls        r-   Úextract_tables_as_htmlr9   Q   s_   € Ø€FØ×%Ñ% gÓ.ò ˆÜ˜“Zˆ
Üˆu�~‰~ Dˆ~Ó)Ó*¨bÒ0Ø�M‰M˜*Ô%Ø�‰Õð	ð
 €Mr/   c                 óö   — g }| j                  d«      D ]b  }|j                  dd«      }|sŒt        ||«      }|j                  dd«      }|j                  |rd|› d�nd|› d�«       |j	                  «        Œd |S )Nr   r   r   r   r   r   )r3   r"   r   r    r5   )r6   r&   Úimgsr   r   r,   r   s          r-   Úextract_imagesr<   [   s’   € Ø€DØ×#Ñ# EÓ*ò ˆØ�g‰g�e˜RÓ ˆÚÜ˜z¨3Ó/ˆHØ—'‘'˜% Ó$ˆCØ�K‰KÉ3˜, x jÐ0FÑGÐVbÐckÐblð  mCð  UDô  EØ�M‰M�Oðð €Kr/   c                 ó*  ‡— g }| j                  ddg«      D ]  }|j                  «        Œ t        | |«      }t        | |«      }t	        | j
                  «      D �]e  }|j                  €Œ|j                  j                  «       }|dk(  rV|j                  d«      rŒBt        ||«      Š‰sŒQt        ˆfd„t        D «       «      rŒj|r‰|d   vsŒt|j                  ‰«       Œ†|dk(  rW|j                  d¬«      }t        |«      d	k\  sŒ¬t        |«      rt        |«      n
t!        |«      }	|	sŒÐ|j                  |	«       Œâ|d
v sŒç|j                  g d¢d¬«      D ]g  }
|
j                  dk(  sŒ|
j                  d«      rŒ%t        |
|«      Š‰sŒ4t        ˆfd„t        D «       «      rŒM|r‰|d   vsŒW|j                  ‰«       Œi �Œh dj#                  |«      }|r|ddj#                  |«      z   z  }|r|ddj#                  |«      z   z  }|j%                  «       S )NÚscriptÚstyleÚpr1   c              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­w©N© ©Ú.0ÚskÚtxts     €r-   ú	<genexpr>z"extract_content.<locals>.<genexpr>y   s   øè ø€ Ò>¨R˜r SœyÑ>ùó   ƒéÿÿÿÿTr   r2   )ÚdivÚsectionÚcenterÚfont)r@   r1   r   )Ú	recursivec              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­wrB   rC   rD   s     €r-   rH   z"extract_content.<locals>.<genexpr>Š   s   øè ø€ Ò&F°R r¨S¤yÑ&FùrI   ú

)r3   r5   r9   r<   Úlistr   r!   ÚlowerÚfind_parentr.   ÚanyÚ
SKIP_TEXTSr    r   r4   Útable_to_mdr   r$   r   )r6   r&   r'   ÚsÚtable_htmlsÚ	img_linesÚchildÚtnÚall_textÚmdÚsubÚresultrG   s               @r-   Úextract_contentra   g   sâ  ø€ Ø€Eà×!Ñ! 8¨WÐ"5Ó6ò ˆØ	�‰�ðô )¨°jÓA€KÜ˜{¨JÓ7€Iä�k×*Ñ*Ó+ó .ˆØ�:‰:ÐØØ�Z‰Z×ÑÓˆà�Š9Ø× Ñ  Ô)ØÜ" 5¨*Ó5ˆCÚœ3Ó>´:Ô>Õ>Ù ¨5°©9Ò 4Ø—L‘L Õ%à�7Š]Ø—~‘~¨D�~Ó1ˆHÜ�8‹} Ó"Ü+6°uÔ+=”[ Ô'Ä3ÀuÃ:�ÚØ—L‘L Õ$àÐ7Ò7Ø—~‘~Ò&;Àt�~ÓLò .�Ø—8‘8˜s“?Ø—‘ wÔ/Ø Ü*¨3°
Ó;�CÚ¤3Ó&F¼:Ô&FÕ#FÙ$¨°5¸±9Ò(<Ø!ŸL™L¨Õ-ò.ð+.ð< �[‰[˜Ó€FÙØ�&˜6Ÿ;™; {Ó3Ñ3Ñ3ˆÙØ�&˜6Ÿ;™; yÓ1Ñ1Ñ1ˆà�<‰<‹>Ðr/   c                 ó   — t        | «      S )u'   ä¿�ç•™ HTML è¡¨æ ¼ç»“æž„ï¼ˆä¸�è½¬ mdï¼‰)r   )r1   ÚargsÚkwargss      r-   rW   rW   —   s   € äˆu‹:Ðr/   c                 ó„  — g }t        «       }| j                  dd¬«      D ]�  }|d   }t        j                  d|t        j                  «      sŒ.t        ||«      }|j                  d¬«      xs& |j                  d«      d   j                  d	«      d
   }||vsŒy|j                  |«       |j                  ||dœ«       ŒŸ |S )Nr   T)r   r   z&\.(pdf|doc|docx|xls|xlsx|rar|zip|txt)$r   ú/rJ   ú?r   )r!   Úurl)
Úsetr3   ÚreÚsearchÚIr   r   ÚsplitÚaddr    )Úsoupr&   ÚattsÚseenr   r   Úfull_urlr!   s           r-   Úextract_attachmentsrs   ›   s²   € Ø€DÜ‹5€DØ�]‰]˜3 Tˆ]Ó*ò =ˆØ�‰yˆÜ�9‰9Ð>ÀÄbÇdÁdÕKÜ˜z¨4Ó0ˆHØ—:‘: D�:Ó)ÒN¨T¯Z©Z¸«_¸RÑ-@×-FÑ-FÀsÓ-KÈAÑ-NˆDØ˜tÒ#Ø—‘˜Ô"Ø—‘ T°(Ñ;Õ<ð=ð €Kr/   c                 óˆ  — 	 t        j                  | t        d¬«      }d|_        t        |j                  d«      }d}|j                  d	d
di¬«      }|r$|j                  d«      r|d   j                  «       }|s'|j                  dd¬«      }|r|j                  d¬«      }d}|j                  d	d
di¬«      }|r'|j                  d«      r|d   j                  «       d d }|j                  dd¬«      }|r|j                  dd¬«      }	|	r|	}t        || «      }
|rt        || «      }nd}t        |j                  «       «      dk  rŒd| › d|› d�}|j!                  d«      }g }|D ]R  }|j                  dd«      }|sŒt#        | |«      }|j                  dd«      }|j%                  |rd|› d�nd|› d�«       ŒT |r|ddj'                  |«      z   z  }|
r-|
D ](  }d |d
   › d!|d"   › d#�}||vsŒ|d$|d
   › d!|d"   › d#�z  }Œ* ||||
fS # t        $ r1}t        d| › d|› �t        j                  ¬«       d d d g fcY d }~S d }~ww xY w)%Né   ©ÚheadersÚtimeoutúutf-8z  fetch_detail error ú: ©Úfileúhtml.parserr   Úmetar!   ÚArticleTitle)ÚattrsÚcontentrK   ©Úclass_Tr   ÚPubDateé
   ÚArticle_ConrN   ÚZoom)Úidr   r   r   r   r   r   r   rQ   ú[z](rh   ú)u   

é™„ä»¶ï¼š[)Úrequestsr"   ÚHEADERSÚencodingÚ	ExceptionÚprintÚsysÚstderrr   r*   Úfindr   r   rs   ra   r4   r3   r   r    r$   )rh   ÚrÚero   ÚtitleÚmtÚdtÚdate_strr6   ÚzoomÚattachmentsr�   r;   rZ   r   r   r,   r   r   Úinline_markers                       r-   Úfetch_detailrœ   «   s©  € ð$Ü�L‰L˜¤g°rÔ:ˆØˆŒ
ô
 ˜Ÿ™ Ó/€Dð €EØ	�‰�6 &¨.Ð!9ˆÓ	:€BÙ	ˆb�f‰f�YÔØ�9‘×#Ñ#Ó%ˆÙØ�Y‰Y�u ^ˆYÓ4ˆÙØ—K‘K d�KÓ+ˆEð €HØ	�‰�6 &¨)Ð!4ˆÓ	5€BÙ	ˆb�f‰f�YÔØ�i‘=×&Ñ&Ó(¨¨"Ð-ˆð —)‘)˜E¨-�)Ó8€KÙØ×Ñ ¨6ÐÓ2ˆÙØˆKä% d¨CÓ0€KáÜ! +¨sÓ3‰àˆô ˆ7�=‰=‹?Ó˜bÒ Ø    R¨ w¨hÐ7ˆØ�}‰}˜UÓ#ˆØˆ	Øò 	NˆCØ—'‘'˜% Ó$ˆCÚÜ" 3¨Ó,�Ø—g‘g˜e RÓ(�Ø× Ñ ÑTW <°¨zÐ9OÑ!PÐ_kÐltÐkuð  vLð  ^Mõ  Nð	Nñ Ø�v §¡¨IÓ 6Ñ6Ñ6ˆGñ Øò 	EˆAØ  &¡	˜{¨"¨Q¨u©X¨J°aÐ8ˆMØ GÒ+Ø˜^¨A¨f©I¨;°b¸¸5¹¸
À!ÐDÑD‘ð	Eð
 �(˜G [Ð0Ð0øôs ò $ÜÐ% c U¨"¨Q¨CÐ0´s·z±zÕBØ�T˜4 Ð#Õ#ûð$ús   ‚#H È	IÈ&H<È6IÈ<Ic                 ó$   — | dk(  rt         S d| › d�S )Né   z(http://www.sinan.gov.cn/xwzx/tzgg/index_z.html)ÚLIST_URL)Úpage_nums    r-   Úget_list_urlr¡   í   s   € Ø�1‚}ÜˆØ5°h°Z¸uÐEÐEr/   c                 óx  — t        | «      }	 t        j                  |t        d¬«      }d|_        |j                  dk7  r-t        d| › d	|j                  › �t        j                  ¬«       g S t        |j                  d
«      }|j                  dd¬«      }|sg S g }|j                  d«      D ]Ò  }|j                  d«      }|j                  d«      }	|r|j                  d«      sŒ9|d   j                  «       }
|j                  dd«      j                  «       xs |j                  d¬«      }t!        ||
«      }|	r|	j                  d¬«      nd}|r|j#                  «       d   nd}|sŒ¼|sŒ¿|j%                  |||f«       ŒÔ |S # t
        $ r-}t        d|› d|› �t        j                  ¬«       g cY d }~S d }~ww xY w)Nru   rv   ry   z  Error fetching rz   r{   éÈ   ú  Page z: HTTP r}   ÚulÚNewsListr‚   Úlir   Úspanr   r•   r   Tr   r   )r¡   r‹   r"   rŒ   r�   rŽ   r�   r�   r‘   Ústatus_coder   r*   r’   r3   r   r   r   rm   r    )r    rh   r“   r”   ro   r¥   Úitemsr§   r   r¨   r   r•   Úpage_urlr˜   s                 r-   Úextract_list_pager¬   ó   s�  € Ü
�xÓ
 €CðÜ�L‰L˜¤g°rÔ:ˆØˆŒ
ð
 	‡}�}˜ÒÜ�˜�z ¨¯©¨Ð8¼s¿z¹zÕJØˆ	ä˜Ÿ™ Ó/€DØ	�‰�4 
ˆÓ	+€BÙØˆ	à€EØ�k‰k˜$Óò 6ˆØ�G‰G�C‹LˆØ�w‰w�v‹ˆÙ˜Ÿ™˜fœØà�‰y�‰Ó ˆØ—‘�g˜rÓ"×(Ñ(Ó*ÒD¨a¯j©j¸t¨jÓ.DˆÜ˜3 Ó%ˆÙ04�4—=‘= t�=Ô,¸"ˆá*2�8—>‘>Ó# AÒ&¸ˆâ’XØ�L‰L˜% ¨8Ð4Õ5ð6ð  €Løô= ò ÜÐ! #  b¨¨Ð,´3·:±:Õ>Ø�	ûðús   �#F Æ	F9Æ"F4Æ.F9Æ4F9c                  ó€   — t        j                  t        d¬«      } | j                  d«       | j                  d«       | S )Né<   )rx   zPRAGMA journal_mode=WALzPRAGMA busy_timeout=5000)Úsqlite3ÚconnectÚDB_PATHÚexecute)Úconns    r-   Úinit_dbr´     s1   € Ü�?‰?œ7¨BÔ/€DØ‡L�LÐ*Ô+Ø‡L�LÐ+Ô,Ø€Kr/   c                 ó‚  — |r|n|}t        j                  dd|«      j                  «       }|rt        j                  |d¬«      nd}	 | j                  dt        |||j                  «       |||t        |t        f
«      }|j                  dkD  S # t        $ r(}	t        d|	› �t        j                  ¬	«       Y d }	~	yd }	~	ww xY w)
Nz\s+r   F)Úensure_asciiz[]zÍINSERT OR IGNORE INTO gov_raw
               (site_name, source_url, page_url, title, publish_date, summary, content, category, attachments, group_name)
               VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)r   z  DB error: r{   )rj   r_   r   ÚjsonÚdumpsr²   Ú	SITE_NAMEÚCATEGORYÚGROUPÚrowcountrŽ   r�   r�   r‘   )
r³   r•   r«   Úpublish_dater�   rš   ÚsummaryÚatt_jsonÚcurr”   s
             r-   Úsave_articlerÁ   "  s®   € Ù ‰g e€GÜ�f‰f�V˜S 'Ó*×0Ñ0Ó2€GÙ>IŒt�z‰z˜+°EÕ:Èt€HðØ�l‰lð8ô ˜ (¨E¯K©K«M¸<Ø�gœx¨´5ð:ó	
ˆð �|‰|˜aÑÐøÜò Ü�˜Q˜CÐ ¤s§z¡zÕ2Üûðús   ÁAB Â	B>ÂB9Â9B>c            
      óH  — t         } t        t        j                  «      dkD  r	 t	        t        j                  d   «      } t        dt        › d| › �t        j                  ¬«       t        «       }d	}d	}|j                  «        t        d
t        › �t        j                  ¬«       t        d| dz   «      D �][  }t        |«      }|s"t        d|› d�t        j                  ¬«        �n,|t        |«      z  }|D ]Ø  \  }}}|r*|dk  r%t        d|› d|d d › �t        j                  ¬«       Œ3|j                  d|f«      }	|	j!                  «       rŒWt#        |«      \  }
}}}|
xs |}|xs |}|xs	 d|› d|› d�}|xs g }t%        ||||||«      r.|dz  }|dk  r$t        d|› d|d d › �t        j                  ¬«       t'        j(                  d«       ŒÚ t        d|› dt        |«      › d|› d�t        j                  ¬«       |j                  «        �Œ^ |j                  «        |j+                  «        t        d|› d|› �t        j                  ¬«       y # t
        $ rÃ t        j                  d   j                  d«      r?	 t	        t        j                  d   j                  d«      d   «      } nm# t
        $ r Y nbw xY wt        j                  d   dv rIt        t        j                  «      dkD  r-	 t	        t        j                  d   «      } n# t
        $ r Y nw xY wY �Œàw xY w)Nrž   z--pages=ú=)z--max-pagesr   é   z	Scraping z, max pages: r{   r   z  Cleared old data for r¤   z: 0 articles (end)z
2020-01-01z  Skip old: r   é(   z)SELECT id FROM gov_raw WHERE page_url = ?r   r   r   é   z  + é2   g333333Ó?rz   z found, z totalz
Done! Found: z, New: )Ú	MAX_PAGESr4   r�   ÚargvÚintÚ
ValueErrorÚ
startswithrm   r�   r¹   r‘   r´   ÚcommitÚranger¬   r²   Úfetchonerœ   rÁ   ÚtimeÚsleepÚclose)Ú	max_pagesr³   Ú	total_newÚtotal_foundÚpnÚarticlesr•   r«   ÚdaterÀ   Ú	det_titleÚdet_dateÚdet_contentÚdet_attsÚfinal_titleÚ
final_dateÚfinal_contentÚ
final_attss                     r-   Úmainrá   6  sÚ  € Ü€IÜ
Œ3�8‰8ƒ}�qÒð	ÜœCŸH™H Q™KÓ(ˆIô 
ˆI”i�[ ¨i¨[Ð
9ÄÇ
Á
ÕKÜ‹9€DØ€IØ€Kð 	‡K�K„MÜ	Ð#¤I ;Ð
/´c·j±jÕAä�A�y 1‘}Ó%ó  ˆÜ$ RÓ(ˆÙÜ�G˜B˜4Ð1Ð2¼¿¹ÕDÚà”s˜8“}Ñ$ˆà%-ò 	Ñ!ˆE�8˜TÙ˜˜|Ò+Ü˜ T F¨!¨E°#°2¨J¨<Ð8¼s¿z¹zÕJØð —,‘,ÐJÈXÈKÓXˆCØ�|‰|Œ~Øä9EÀhÓ9OÑ6ˆI�x ¨hØ#Ò, uˆKØ!Ò) TˆJØ'Ò[¨\¸(¸À2ÀkÀ]ÐRZÐ+[ˆMØ!š RˆJä˜D +¨x¸À]ÐT^Ô_Ø˜Q‘�	Ø ’>Ü˜D  ¨A¨k¸#¸2Ð.>Ð-?Ð@ÄsÇzÁzÕRä�J‰J�s�Oð+	ô. 	�˜�t˜2œc (›m˜_¨H°Y°K¸vÐFÌSÏZÉZÕXØ�‰ŽðA ðD 	‡K�K„MØ‡J�J„LÜ	ˆO˜K˜=¨°	¨{Ð
;Ä#Ç*Á*ÖMøôu ò 
	Ü�x‰x˜‰{×%Ñ% jÔ1ðÜ #¤C§H¡H¨Q¡K×$5Ñ$5°cÓ$:¸1Ñ$=Ó >‘IøÜ!ò Ùðúä—‘˜!‘Ð :Ñ:¼sÄ3Ç8Á8»}ÈqÒ?PðÜ #¤C§H¡H¨Q¡KÓ 0‘IøÜ!ò Ùðýð
	úsY   ¤I É+L!Ê.J0Ê/L!Ê0	J<Ê9L!Ê;J<Ê<4L!Ë1LÌL!Ì	LÌL!ÌLÌL!Ì L!Ú__main__)-Ú__doc__r‹   rj   r·   r¯   rÐ   Úosr�   r   Úbs4r   Úurllib.parser   ÚargparseÚ_APÚArgumentParserÚ
_AP_PARSERÚadd_argumentrÊ   Úparse_known_argsÚ_AP_ARGSÚ_ÚpagesrÈ   r±   r¹   rº   r»   ÚBASE_URLrŸ   rŒ   rV   r.   r9   r<   ra   rW   rs   rœ   r¡   r¬   r´   rÁ   rá   Ú__name__rC   r/   r-   ú<module>rò      s  ðñ
÷ 2× 1× 1Ó 1Ý Ý Ý  ó ØˆS×ÑÓ!€
Ø 
× Ñ ˜	¨°Q¸^Ð Ô LØ×)Ñ)Ó+�€ˆ!Ø&Ÿn™n¨qÒ0ˆH�NŠN°c€	à
€Ø0€	Ø€Ø€Ø$€Ø9€Ø€	ð DØOØ0ñ€ò€
ò#ò<ò	ò-ò`òò =1òDFò#òPòò(?NðD ˆzÒÙ…Fð r/   