Ë
    ¸¬uj#  ã                   óP  — 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mZmZ ddlm	Z	 dZ
 ej                  «        ed¬«      z
  j                  d«      Zd	d
ddœZddddddœZ ej                   «       Zej$                  j'                  e«       d„ Zd„ Zd„ Zd„ Zd„ Zedk(  r e«        yy)u  
é¹¤å±±å¸‚äººæ°‘æ”¿åºœ - å¤šä¸ªå­�ç«™ç»Ÿä¸€çˆ¬è™«
CMS: æ±‰æž—Hanweb (é�™æ€�HTMLåˆ†é¡µ)
è¯¦æƒ…: æ ‡é¢˜<meta ArticleTitle> / æ­£æ–‡div#zoom .TRS_UEDITOR
ç”¨æ³•: python3 crawl_heshan.py [site_key]
      ä¸�ä¼ å�‚æ•°é»˜è®¤çˆ¬çŽ¯è¯„ä¿¡æ�¯ï¼Œä¼ å…·ä½“keyçˆ¬å¯¹åº”å­�ç«™
é    N)ÚdatetimeÚ	timedelta)ÚBeautifulSoupzhttps://www.heshan.gov.cniG  )Údaysú%Y-%m-%dzoMozilla/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   heshan.gov.cn-çŽ¯è¯„ä¿¡æ�¯z$/zwgk/zdlyxxgk/hjbhxxgk/jsxmhjyxpjxxÚhjxxé   )õ   å�¤åŠ³é•‡-é€šçŸ¥å…¬å‘Šz/zwgk/xxgk/hssglz/qt/tzggõ   é€šçŸ¥å…¬å‘Šr   )u   å�¤åŠ³é•‡-å…¶ä»–ä¿¡æ�¯z/zwgk/xxgk/hssglz/qtu   å…¶ä»–r   )õ   é¾™å�£é•‡-éƒ¨é—¨æ–‡ä»¶z/zwgk/xxgk/hsslkz/bmwju   éƒ¨é—¨æ–‡ä»¶r   )õ"   é¾™å�£é•‡-å·¥ä½œåŠ¨æ€�é€šçŸ¥å…¬å‘Šz/zwgk/xxgk/hsslkz/gzdt/tzggr   r   )õ   çŽ¯è¯„ä¿¡æ�¯r   u   å�¤åŠ³é•‡-å…¶ä»–r   r   c                 ó¦   — 	 t         j                  | d¬«      }d|_        |j                  S # t        $ r}t        d| › d|› �«       Y d }~y d }~ww xY w)Né   )Útimeoutzutf-8z  [ERR] fetch failed: z - )ÚsessionÚgetÚencodingÚtextÚ	ExceptionÚprint)ÚurlÚrÚes      ú!/root/gov_crawler/crawl_heshan.pyÚfetchr   (   sR   € ðÜ�K‰K˜ RˆKÓ(ˆØˆŒ
Ø�v‰vˆøÜò ÜÐ& s e¨3¨q¨cÐ2Ô3Üûðús   ‚), ¬	AµAÁAc                 ó,  — t         › | › d�}t        |«      }|syt        |d«      }d}|j                  dd¬«      D ]j  }|j	                  d¬«      }|d   }d	|v sd
|v sŒ#t        j                  d|«      }|sŒ<t        |j                  d«      «      }t        d|› d|› d�«       |c S  |j                  dd¬«      D ]B  }|d   }t        j                  d|«      }|sŒ!t        |j                  d«      «      }	|	|kD  sŒA|	}ŒD |dkD  rt        d|› d�«       |S )z'Auto-detect total pages from first pageú/index.htmlé   úhtml.parserÚaT©Úhref©Ústripr$   u   æœ€å�Žä¸€é¡µu   æœ«é¡µzindex_(\d+)\.htmlz  Last page link: z => z pagesz  Max page link: index_ú.html)
ÚBASE_URLr   r   Úfind_allÚget_textÚreÚsearchÚintÚgroupr   )
Ú	list_pathr   ÚhtmlÚsoupÚmax_pager"   Útxtr$   ÚmÚps
             r   Úget_total_pagesr6   1   s1  € äˆJ�y�k Ð
-€CÜ�‹:€DÙØä˜˜}Ó-€DØ€Hð �]‰]˜3 Tˆ]Ó*ò  ˆØ�j‰j˜tˆjÓ$ˆØ�‰yˆØ˜SÑ  H°¢OÜ—	‘	Ð.°Ó5ˆAÚÜ˜qŸw™w q›z›?�ÜÐ*¨4¨&°°X°J¸fÐEÔFØ’ð ð �]‰]˜3 Tˆ]Ó*ò ˆØ�‰yˆÜ�I‰IÐ*¨DÓ1ˆÚÜ�A—G‘G˜A“J“ˆAØ�8‹|Ø‘ðð �!‚|ÜÐ'¨ z°Ð7Ô8à€Oó    c                 óD  — g }t        | d«      }|j                  dd¬«      D ]¼  }|d   j                  «       }|j                  dd«      j                  «       }|s|j	                  d¬«      }|rt        |«      d	k  rŒ[d
|vrŒ`|j                  d«      s9|j                  d«      r
t        |z   }nt        |z   dz   |j                  d«      z   }|j                  ||f«       Œ¾ t        «       }g }|D ].  \  }	}|	|vsŒ|j                  |	«       |j                  |	|f«       Œ0 |S )z,Parse list page, return list of (url, title)r!   r"   Tr#   r$   ÚtitleÚ r%   é   zcontent/post_Úhttpú/z./)r   r)   r&   r   r*   ÚlenÚ
startswithr(   ÚlstripÚappendÚsetÚadd)
r0   r/   Úitemsr1   Úa_tagr$   r9   ÚseenÚuniquer   s
             r   Ú
parse_listrH   T   s"  € à€EÜ˜˜}Ó-€Dð —‘˜s¨�Ó.ò $ˆØ�V‰}×"Ñ"Ó$ˆØ—	‘	˜' 2Ó&×,Ñ,Ó.ˆÙØ—N‘N¨�NÓ.ˆEÙœ˜E›
 QšØØ $Ñ&Øà�‰˜vÔ&Ø�‰˜sÔ#Ü $‘‘ä )Ñ+¨cÑ1°D·K±KÀÓ4EÑE�à�‰�d˜E�]Õ#ð!$ô& ‹5€DØ€FØò (‰
ˆˆUØ�dŠ?Ø�H‰H�SŒMØ�M‰M˜3 ˜,Õ'ð(ð €Mr7   c                 ó„  — t        | d«      }d}|j                  dddi¬«      }|r$|j                  d«      r|d   j                  «       }|s%|j	                  d«      }|r|j                  d	¬
«      }|st        d|› �«       yd}|j                  dddi¬«      }|r=|j                  d«      r,t        j                  d|d   «      }|r|j                  d«      }|j	                  d«      }	|	rB|	j                  ddg«      D ]  }
|
j                  «        Œ t        |	«      j                  «       }nt        d|› �«       d}|||fS )z=Parse detail page, return (title, publish_date, content_html)r!   NÚmetaÚnameÚArticleTitle)ÚattrsÚcontentzdiv.title spanTr%   z  [ERR] no title for )NNNr:   ÚPubDatez(\d{4}-\d{2}-\d{2})r    zdiv#zoomÚscriptÚstylez  [WARN] no content div for )r   Úfindr   r&   Ú
select_oner*   r   r+   r,   r.   r)   Ú	decomposeÚstr)r0   r   r1   r9   Ú
meta_titleÚtitle_elÚpub_dateÚ	meta_dater4   Úcontent_divÚtagÚcontent_htmls               r   Úparse_detailr]   u   sG  € ä˜˜}Ó-€Dà€EØ—‘˜6¨&°.Ð)A�ÓB€JÙ�j—n‘n YÔ/Ø˜9Ñ%×+Ñ+Ó-ˆáØ—?‘?Ð#3Ó4ˆÙØ×%Ñ%¨DÐ%Ó1ˆEáÜÐ% c UÐ+Ô,Øà€HØ—	‘	˜&¨°Ð(;�	Ó<€IÙ�Y—]‘] 9Ô-Ü�I‰IÐ,¨i¸	Ñ.BÓCˆÙØ—w‘w˜q“zˆHà—/‘/ *Ó-€KÙØ×'Ñ'¨°7Ð(;Ó<ò 	ˆCØ�M‰M�Oð	ä˜;Ó'×-Ñ-Ó/‰äÐ,¨S¨EÐ2Ô3Øˆà�(˜LÐ(Ð(r7   c                  óT  — dd l } t        t        j                  «      dkD  rt        j                  d   }nd}|t        vrSt        d|› d�«       t        ddj                  t        j                  «       «      › �«       t        j                  d«       t        |   \  }}}}t        j                  dd	«      }t        d
|› �«       t        d|› �«       t        dt        › �«       t        |«      }|dkD  r||k  r|}t        d|› �«       | j                  |«      }|j                  «       }	t        «       }
|	j!                  d|f«      D ]  }|
j#                  |d   «       Œ t        dt        |
«      › �«       d}d}t%        d|dz   «      D �]µ  }|dk(  rt&        › |› d�}nt&        › |› d|› d�}t        d|› d|› d�«       t)        |«      }|st        d«       ŒNt+        ||«      }|s t        d«       |dk(  rt        d«        y  �n=t        dt        |«      › d�«       d}|D ]Þ  \  }}||
v rŒt)        |«      }|st        d|d d › �«       Œ*t-        ||«      \  }}}|sŒ=|r|t        k  r|dz  }ŒNd}|r0	 t/        j0                  |d«      }t3        |j5                  «       «      }	 |	j!                  d |||||||f«       |	j8                  dkD  r|dz  }|dz  }|
j#                  |«       |d"z  dk(  sŒÏ|j=                  «        Œà |j=                  «        t        d#|› d$|› d%|› d&|› d'�	«       t?        j@                  d(«       �Œ¸ t        d)d*› �«       t        d+|› d,|› d-|› �«       |dkD  r8t        d.«       	 |	j!                  d/«       |j=                  «        t        d0«       |jC                  «        t        d2«       y #  t3        |j7                  dd«      «      }Y �Œ:xY w# t:        $ r}t        d!|› �«       Y d }~�Œd }~ww xY w# t:        $ r}t        d1|› �«       Y d }~Œ€d }~ww xY w)3Nr   r    r   zError: unknown site key 'ú'zAvailable: z, Ú	SEARCH_DBz/root/search.dbzSite: zList: zCutoff: zTotal pages: z.SELECT page_url FROM gov_raw WHERE site_name=?zExisting items: r   z/index_r'   z

--- Page z: z ---z  [SKIP] fetch failedz  [SKIP] no items (stopping)z[FATAL] Page 1 empty, abortingz  Found z itemsz  [SKIP] detail failed: é(   r   ú-r:   zƒINSERT OR IGNORE INTO gov_raw (site_name, title, page_url, publish_date, content, date_rank, category) VALUES (?, ?, ?, ?, ?, ?, ?)z  [ERR] insert: é
   z  Page z: +z new (total z, skip ú)g333333Ó?ú
z2==================================================zFinal: z new, u    skipped (è¶…3å¹´) for zFTS rebuild...z4INSERT INTO gov_search(gov_search) VALUES('rebuild')z  FTS rebuilt OKz  [WARN] FTS rebuild: zDone.)"Úsqlite3r>   ÚsysÚargvÚSITE_MAPr   ÚjoinÚkeysÚexitÚosÚgetenvÚCUTOFFr6   ÚconnectÚcursorrB   ÚexecuterC   Úranger(   r   rH   r]   r   Ústrptimer-   Ú	timestampÚreplaceÚrowcountr   ÚcommitÚtimeÚsleepÚclose)rf   Úsite_keyÚ	SITE_NAMEÚ	LIST_PATHÚCATEGORYÚ	MAX_PAGESr`   Útotal_pagesÚconnÚcurÚexistingÚrowÚ	total_newÚ
total_skipÚpage_numÚpage_urlr0   rD   Úpage_newr   Ú
list_titleÚdetail_htmlr9   Údate_strrN   Ú	date_rankÚdtr   s                               r   Úmainr�   ™   s>  € Ûô Œ3�8‰8ƒ}�qÒÜ—8‘8˜A‘;‰à!ˆà”xÑÜÐ)¨(¨°1Ð5Ô6Ü�˜DŸI™I¤h§m¡m£oÓ6Ð7Ð8Ô9Ü�‰�Œä08¸Ñ0BÑ-€Iˆy˜( Iä—	‘	˜+Ð'8Ó9€Iä	ˆF�9�+Ð
ÔÜ	ˆF�9�+Ð
ÔÜ	ˆH”V�HÐ
Ôô " )Ó,€KØ�1‚}˜ yÒ0ØˆÜ	ˆM˜+˜Ð
'Ô(à�?‰?˜9Ó%€DØ
�+‰+‹-€Cô ‹u€HØ�{‰{ÐKÈiÈ\ÓZò ˆØ�‰�S˜‘VÕðä	ÐœS ›]˜OÐ
,Ô-à€IØ€Jä˜!˜[¨1™_Ó-ó CˆØ�qŠ=Ü"˜ I ;¨kÐ:‰Hä"˜ I ;¨g°h°Z¸uÐEˆHä�˜H˜: R¨ z°Ð6Ô7Ü�X‹ˆÙÜÐ)Ô+Øä˜4 Ó+ˆÙÜÐ0Ô2Ø˜1Š}ÜÐ6Ô7ÙÚä�œ˜U›˜ FÐ+Ô,àˆØ$ò (	‰OˆC�Ø�h‰Øä ›*ˆKÙÜÐ0°¸C¸R°Ð0AÐBÔCØä'3°KÀÓ'EÑ$ˆE�8˜WÙØá˜H¤vÒ-Ø˜a‘�
ØàˆIÙð?Ü!×*Ñ*¨8°ZÓ@�BÜ # B§L¡L£NÓ 3�Ið.Ø—‘ð3ð   s¨H°g¸yÈ(ÐSô	ð —<‘< !Ò#Ø ‘M�HØ ‘N�IØ—L‘L Ô%ð ˜"‰} Ó!Ø—‘•ðQ(	ðT 	�‰ŒÜ�˜�z  X J¨l¸9¸+ÀWÈZÈLÐXYÐZÔ[Ü�
‰
�3ŽðGCôJ 
ˆBˆvˆhˆ-ÔÜ	ˆG�I�;˜f Z LÐ0GÈ	À{Ð
SÔTà�1‚}ÜÐÔð	0Ø�K‰KÐNÔOØ�K‰KŒMÜÐ$Ô%ð 	‡J�J„LÜ	ˆ'…NøðK?Ü # H×$4Ñ$4°S¸"Ó$=Ó >“Iûô ò .ÜÐ(¨¨Ð,×-Ò-ûð.ûô& ò 	0ÜÐ*¨1¨#Ð.×/Ñ/ûð	0ús=   É5/N>Ê%AO!Í6,P Î>OÏ!	PÏ*O>Ï>PÐ	P'ÐP"Ð"P'Ú__main__)Ú__doc__rm   r+   rg   ry   Úrequestsr   r   Úbs4r   r(   ÚnowÚstrftimero   ÚHEADERSri   ÚSessionr   ÚheadersÚupdater   r6   rH   r]   r�   Ú__name__© r7   r   ú<module>r�      sÍ   ðñó 
Û 	Û 
Û Û ß (Ý à&€Ø
ˆ(�,‰,‹.™9¨%Ô0Ñ
0×	:Ñ	:¸:Ó	F€ðGàOØ0ñ	€ð gØhØWØeð +Cñ€ð ˆ(×
Ñ
Ó
€Ø ‡�× Ñ �wÔ òò!òFòB")òHzðx ˆzÒÙ…Fð r7   