Ë
    €Ûµjß2  ã                   óô   — 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dlm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!e"dk(  r e!«        yy)uR  
Crawler for è‹�å·žç‹¬å¢…æ¹–ç§‘æ•™åˆ›æ–°åŒº - å…¬å‘Š
CMS: UCAPCONTENT
List: ul > li > a[href] + span (date)
Pagination: createPageHTML, 4 pages, 15/page, ~57 items
Detail: div.c_d_content > UCAPCONTENT

Usage:
    python3 crawl_sipac_dshkjycxq.py             # Full crawl
    python3 crawl_sipac_dshkjycxq.py --max-pages 1  # Incremental
é    N)Údatetime)ÚBeautifulSoupÚTag)Úurljoinz/root/search.dbu%   è‹�å·žç‹¬å¢…æ¹–ç§‘æ•™åˆ›æ–°åŒº-å…¬å‘Šu   å…¬å‘Šu   æ±Ÿè‹�zhttp://www.sipac.gov.cnz9http://www.sipac.gov.cn/szdshkjcxq/gonggao/nav_list.shtmlé   zoMozilla/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   ç´¯è®¡æ¬¡æ•°ï¼šc                 ó:  — g }t        | j                  «      D �]â  }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(  rU|j                  d
d«      }|sŒÜ|j                  dd«      }	t        ||«      }
|j                  |	r	d|	› d|
› d�nd|
› d�«       �Œ|j                  dv r|j                  d«       �Œ=|j                  dv r=|j                  d«      r�Œ^|j                  dd¬«      }|s�Œu|j                  |«       �Œˆ|j                  dk(  r�Œ™|j                  dk(  r|j                  d«      r�Œ»|j                  dd¬«      }|s�ŒÒ|j                  |«       �Œå dj                  |«      j	                  «       S )z>Extract plain text from a <p> tag (excluding embedded tables).ÚaÚhrefÚ T©Ústripú[ú](ú)ÚimgÚsrcÚaltú![ú![]()Úbrú
)ÚspanÚfontÚbÚstrongÚemÚuÚtableú Údiv)ÚlistÚchildrenÚ
isinstanceÚstrr   ÚappendÚnameÚgetÚget_textr   ÚfindÚjoin)Úp_tagÚ
detail_urlÚpartsÚelemÚtr   ÚtextÚfullr   r   Úfull_srcÚtxts               ú*/root/gov_crawler/crawl_sipac_dshkjycxq.pyÚrender_paragraphr6   ,   sÒ  € à€EÜ�U—^‘^Ó$ó %"ˆÜ�dœCÔ Ø—
‘
“ˆAÚØ—‘˜Q•Ø�Y‰Y˜#ÒØ—8‘8˜F BÓ'×-Ñ-Ó/ˆDØ—=‘= t�=Ó,ˆDÙ™Ü˜z¨4Ó0�Ø—‘˜q   b¨¨¨aÐ0Õ1ÚØ—‘˜TÕ"Ø�Y‰Y˜%ÒØ—(‘(˜5 "Ó%ˆCÚØ—h‘h˜u bÓ)�Ü" :¨sÓ3�Ø—‘¹˜r #  b¨¨
°!Ñ4À4ÈÀzÐQRÐASÖTØ�Y‰Y˜'Ñ!Ø�L‰L˜ÖØ�Y‰YÐDÑDà�y‰y˜Ô!ÙØ—-‘- ¨4�-Ó0ˆCÛØ—‘˜SÖ!ð �y‰y˜GÒ#Ùà�y‰y˜EÒ! d§i¡i°Ô&8ÙØ—-‘- ¨4�-Ó0ˆCÛØ—‘˜SÖ!ðK%"ðL �8‰8�E‹?× Ñ Ó"Ð"ó    c                 óÊ   — g }| j                  d«      D ]L  }t        |«      }t        |j                  d¬«      «      dk\  r|j	                  |«       |j                  «        ŒN |S )zWExtract <table> elements and return as raw HTML strings, then remove them from content.r   Tr   é   )Úfind_allr%   Úlenr)   r&   Ú	decompose)Úcontent_divÚtablesr   Ú
table_htmls       r5   Úextract_tables_as_htmlr@   X   s_   € à€FØ×%Ñ% gÓ.ò ˆÜ˜“Zˆ
Üˆu�~‰~ Dˆ~Ó)Ó*¨bÒ0Ø�M‰M˜*Ô%Ø�‰Õð	ð
 €Mr7   c                 óü   — g }| j                  d«      D ]e  }|j                  dd«      }|sŒt        ||«      }|j                  dd«      }|j                  |r	d|› d|› d�nd|› d�«       |j	                  «        Œg |S )	z;Extract <img> tags from content_div and return as markdown.r   r   r   r   r   r   r   r   )r:   r(   r   r&   r<   )r=   r-   Úimgsr   r   r3   r   s          r5   Úextract_imagesrC   c   sˆ   € à€DØ×#Ñ# EÓ*ò ˆØ�g‰g�e˜RÓ ˆÚÜ˜z¨3Ó/ˆHØ—'‘'˜% Ó$ˆCØ�K‰K±3˜"˜S˜E  H :¨QÑ/¸dÀ8À*ÈAÐ<NÔOØ�M‰M�Oðð €Kr7   c                 óœ  ‡
— g }| j                  ddg«      D ]  }|j                  «        Œ t        | «      }t        | |«      }t	        | j
                  «      D �]Ÿ  }|j                  €Œ|j                  j                  «       }|dk(  rDt        ||«      Š
‰
sŒ?t        ˆ
fd„t        D «       «      rŒX|r‰
|d   vsŒb|j                  ‰
«       Œt|dv rÛ|j                  ddgd¬	«      D ]Á  }|j                  dk(  rDt        ||«      Š
‰
sŒ!t        ˆ
fd
„t        D «       «      rŒ:|r‰
|d   vsŒD|j                  ‰
«       ŒV|j                  dk(  sŒf|j                  d«      rŒx|j                  dd¬«      Š
‰
sŒŽt        ˆ
fd„t        D «       «      rŒ§|r‰
|d   vsŒ±|j                  ‰
«       ŒÃ �ŒS|j                  dd¬«      Š
‰
s�Œjt        ˆ
fd„t        D «       «      r�Œ„|r	‰
|d   vs�Œ�|j                  ‰
«       �Œ¢ dj                  |«      }	|r|	ddj                  |«      z   z  }	|r|	ddj                  |«      z   z  }	|	j                  «       S )NÚscriptÚstyleÚpc              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­w©N© ©Ú.0Úskr4   s     €r5   ú	<genexpr>z"extract_content.<locals>.<genexpr>…   ó   øè ø€ Ò>¨R˜r SœyÑ>ùó   ƒéÿÿÿÿ)r!   ÚsectionÚcenterÚucapcontentr   F)Ú	recursivec              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­wrI   rJ   rK   s     €r5   rN   z"extract_content.<locals>.<genexpr>Ž   ó   øè ø€ Ò&F°R r¨S¤yÑ&FùrP   r    Tr   c              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­wrI   rJ   rK   s     €r5   rN   z"extract_content.<locals>.<genexpr>–   rW   rP   c              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­wrI   rJ   rK   s     €r5   rN   z"extract_content.<locals>.<genexpr>œ   rO   rP   ú

)r:   r<   r@   rC   r"   r#   r'   Úlowerr6   ÚanyÚ
SKIP_TEXTSr&   Úfind_parentr)   r+   r   )r=   r-   r.   ÚsÚtable_htmlsÚ	img_linesÚchildÚtnÚsubÚresultr4   s             @r5   Úextract_contentrf   p   s  ø€ Ø€Eð ×!Ñ! 8¨WÐ"5Ó6ò ˆØ	�‰�ðô )¨Ó5€Kô ˜{¨JÓ7€Iô �k×*Ñ*Ó+ó  &ˆØ�:‰:ÐØØ�Z‰Z×ÑÓˆà�Š9Ü" 5¨*Ó5ˆCÚœ3Ó>´:Ô>Õ>á ¨5°©9Ò 4Ø—L‘L Õ%àÐ>Ñ>Ø—~‘~ s¨F m¸u�~ÓEò .�Ø—8‘8˜s’?Ü*¨3°
Ó;�CÚ¤3Ó&F¼:Ô&FÕ#FÙ$¨°5¸±9Ò(<Ø!ŸL™L¨Õ-Ø—X‘X Ó'à—‘ sÔ+Ø ØŸ,™, s°$˜,Ó7�CÚ¤3Ó&F¼:Ô&FÕ#FÙ$¨°5¸±9Ò(<Ø!ŸL™L¨Õ-ò.ð  —.‘. ¨D�.Ó1ˆCÛœ3Ó>´:Ô>Ö>Ù ¨5°©9Ó 4Ø—L‘L Ö%ðA &ðF �[‰[˜Ó€FÙØ�&˜6Ÿ;™; {Ó3Ñ3Ñ3ˆÙØ�&˜6Ÿ;™; yÓ1Ñ1Ñ1ˆà�<‰<‹>Ðr7   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   ú/rQ   ú?r   )r'   Úurl)
Úsetr:   ÚreÚsearchÚIr   r)   ÚsplitÚaddr&   )Úsoupr-   ÚattsÚseenr
   r   Úfull_urlr'   s           r5   Úextract_attachmentsru   ¬   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°(Ñ;Õ<ð=ð €Kr7   c                 óÔ  — 	 t        j                  | t        d¬«      }d|_        t        |j                  d«      }d}|j                  d	d
di¬«      }|r$|j                  d«      r|d   j                  «       }|sL|j                  d«      }|r9|j                  d¬«      }t        j                  dd|«      j                  «       }|}d}|j                  d	d
di¬«      }|r'|j                  d«      r|d   j                  «       d d }|j                  dd¬«      }	|	r|	j                  d«      }
|
r|
}	t        || «      }|	rt!        |	| «      }nd}t#        |j                  «       «      dk  r�d| › d|› d�}|j%                  d«      }g }|D ]U  }|j                  dd«      }|sŒt'        | |«      }|j                  dd«      }|j)                  |r	d|› d|› d �nd!|› d �«       ŒW |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ÚcontentÚtitleTr   u-   \s*[-_â€”|].*(?:é€šçŸ¥å…¬å‘Š|é«˜ç«¯åˆ¶é€ ).*$ÚPubDateé
   r!   Úc_d_content)Úclass_ÚUCAPCONTENTz<p><a href="z">z</a></p>r   r   r   r   r   r   r   rZ   r   rj   u   

é™„ä»¶ï¼š[)Úrequestsr(   ÚHEADERSÚencodingÚ	ExceptionÚprintÚsysÚstderrr   r1   r*   r   r)   rl   rd   ru   rf   r;   r:   r   r&   r+   )rj   ÚrÚerq   r„   ÚmtÚtagr0   Údate_strr=   ÚucapÚattachmentsrƒ   rB   ra   r   r   r3   r   r
   Úinline_markers                        r5   Úfetch_detailr™   ¼   s·  € ð$Ü�L‰L˜¤g°rÔ:ˆØˆŒ
ô
 ˜Ÿ™ Ó/€Dð €EØ	�‰�6 &¨.Ð!9ˆÓ	:€BÙ	ˆb�f‰f�YÔØ�9‘×#Ñ#Ó%ˆÙØ�i‰i˜Ó ˆÙØ—‘ 4�Ó(ˆAÜ—‘ÐGÈÈQÓO×UÑUÓWˆAØˆEð €HØ	�‰�6 &¨)Ð!4ˆÓ	5€BÙ	ˆb�f‰f�YÔØ�i‘=×&Ñ&Ó(¨¨"Ð-ˆð —)‘)˜E¨-�)Ó8€KÙØ×Ñ Ó.ˆÙØˆKä% d¨CÓ0€KáÜ! +¨sÓ3‰àˆô ˆ7�=‰=‹?Ó˜bÒ Ø    R¨ w¨hÐ7ˆØ�}‰}˜UÓ#ˆØˆ	Øò 	YˆCØ—'‘'˜% Ó$ˆCÚÜ" 3¨Ó,�Ø—g‘g˜e RÓ(�Ø× Ñ ¹C 2 c U¨"¨X¨J°aÑ!8ÀtÈHÈ:ÐUVÐEWÕXð	Yñ Ø�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øôw ò $ÜÐ% c U¨"¨Q¨CÐ0´s·z±zÕBØ�T˜4 Ð#Õ#ûð$ús   ‚#H- È-	I'È6&I"ÉI'É"I'c                 ó$   — | dk(  rt         S d| › d�S )Né   z4http://www.sipac.gov.cn/szdshkjcxq/gonggao/nav_list_z.shtml)ÚLIST_URL)Úpage_nums    r5   Úget_list_urlrž      s   € Ø�1‚}ÜˆØAÀ(ÀÈ6ÐRÐRr7   c                 óF  — t        | «      }	 t        j                  |t        d¬«      }d|_        |j                  dk7  r-t        d| › d	|j                  › �t        j                  ¬«       g S t        |j                  d
«      }|j                  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}|sŒ¥|sŒ¨|j%                  |||f«       Œ½ |S # t
        $ r-}t        d|› d|› �t        j                  ¬«       g cY d }~S d }~ww xY w)Nrw   rx   r{   z  Error fetching r|   r}   éÈ   ú  Page z: HTTP r   zdiv.listBox ulÚlir
   r   r   r„   r   Tr   )rž   rŠ   r(   r‹   rŒ   r�   rŽ   r�   r�   Ústatus_coder   r1   Ú
select_oner:   r*   r   r)   r   r&   )r�   rj   r‘   r’   rq   ÚulÚitemsr¢   r
   r   r   r„   Úpage_urlr•   s                 r5   Úextract_list_pager¨     su  € Ü
�xÓ
 €CðÜ�L‰L˜¤g°rÔ:ˆØˆŒ
ð
 	‡}�}˜ÒÜ�˜�z ¨¯©¨Ð8¼s¿z¹zÕJØˆ	ä˜Ÿ™ Ó/€DØ	�‰Ð)Ó	*€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�=Ô,¸"ˆâ’XØ�L‰L˜% ¨8Ð4Õ5ð6ð €Løô9 ò ÜÐ! #  b¨¨Ð,´3·:±:Õ>Ø�	ûðús   �#E* Å*	F Å3"FÆF ÆF c                  ó€   — t        j                  t        d¬«      } | j                  d«       | j                  d«       | S )Né<   )rz   zPRAGMA journal_mode=WALzPRAGMA busy_timeout=5000)Úsqlite3ÚconnectÚDB_PATHÚexecute)Úconns    r5   Úinit_dbr°   ,  s1   € Ü�?‰?œ7¨BÔ/€DØ‡L�LÐ*Ô+Ø‡L�LÐ+Ô,Ø€Kr7   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}   )rl   rd   r   ÚjsonÚdumpsr®   Ú	SITE_NAMEÚCATEGORYÚGROUPÚrowcountr�   rŽ   r�   r�   )
r¯   r„   r§   Úpublish_daterƒ   r—   ÚsummaryÚatt_jsonÚcurr’   s
             r5   Úsave_articler½   3  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            
      óf  — 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 �]K  }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                  ¬«       �ŒN |j                  «        |j'                  «        t        d|› d|› �t        j                  ¬«       y # t
        $ rb 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 �Œow xY w)Nr›   )z--max-pagesé   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Ó?r|   z found, z totalz
Done! Found: z, New: )Ú	MAX_PAGESr;   r�   ÚargvÚintÚ
ValueErrorrŽ   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                     r5   ÚmainrÛ   G  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‘}Ó%ó YˆÜ$ 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Ø'ÒI¨Q¨{¨m¸2¸h¸ZÀqÐ+Iˆ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ð?YðB 	‡K�K„MØ‡J�J„LÜ	ˆO˜K˜=¨°	¨{Ð
;Ä#Ç*Á*ÖMøôi ò 	Ü�x‰x˜‰{Ð.Ñ.´3´s·x±x³=À1Ò3DðÜ #¤C§H¡H¨Q¡KÓ 0‘IøÜ!ò Ùðýð		ús5   ¤I É:J0Ê JÊJ0Ê	J)Ê&J0Ê(J)Ê)J0Ê/J0Ú__main__)#Ú__doc__rŠ   rl   r³   r«   rÊ   Úosr�   r   Úbs4r   r   Úurllib.parser   r­   rµ   r¶   r·   ÚBASE_URLrœ   rÃ   r‹   r]   r6   r@   rC   rf   ru   r™   rž   r¨   r°   r½   rÛ   Ú__name__rJ   r7   r5   ú<module>rã      s°   ðñ
÷ 2× 1× 1Ó 1Ý ß "Ý  à
€Ø3€	Ø€Ø€Ø$€ØF€Ø€	ð DØOØ0ñ€ò€
ò)#òXò
ò7òxò ?1òHSò!òLòò(9Nðx ˆzÒÙ…Fð r7   