Ë
    m }jö  ã                   ó<  — 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 ddlm	Z	 ddl
m
Z
mZ ej                  j                  dej                  j                  dd«      «      Zd	Zed
z   ZdZdZddddddddœZdZdZddiZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zedk(  r e«        yy) u  
crawl_wjq.py â€” ç¬¬å…­å¸ˆäº”å®¶æ¸ å¸‚äººæ°‘æ”¿åºœÂ·é€šçŸ¥å…¬å‘Š
=============================================
JPaaS CMSï¼ŒAPI JSON åˆ†é¡µ

åˆ—è¡¨ APIï¼š/api-gateway/jpaas-publish-server/front/page/build/unit
  paramJson={"pageNo":N,"pageSize":12} æŽ§åˆ¶åˆ†é¡µ
  è¿”å›ž JSON { data: { html: "..." } }

è¯¦æƒ…ï¼š<div class="zw_content"> æ­£æ–‡
      <meta name="PubDate" content="2026-06-12 19:55" /> æ—¥æœŸ

ç”¨æ³•:
    python3 crawl_wjq.py             # å…¨é‡�
    python3 crawl_wjq.py 1           # å¢žé‡�ï¼ˆå�ªçˆ¬é¦–é¡µï¼‰
é    N)ÚBeautifulSoup)Úurljoin)ÚdatetimeÚ	timedeltaÚ	SEARCH_DBÚGOV_DB_PATHz/root/search.dbzhttps://www.wjq.gov.cnz7/api-gateway/jpaas-publish-server/front/page/build/unitu!   ç¬¬å…­å¸ˆäº”å®¶æ¸ å¸‚äººæ°‘æ”¿åºœu   äº”å®¶æ¸ å¸‚é€šçŸ¥å…¬å‘ŠÚbulidstaticÚgXiRWWCDbJQMHYm3xJLgFÚGLcGu6Emt0FbNhQGT3B8eÚcolumnu   å½“å‰�æ �ç›®çš„åˆ—è¡¨ÚnullÚWb3cNQs5RoDi7h7NnZA55)Ú	parseTypeÚwebIdÚtplSetIdÚpageTypeÚtagIdÚeditTypeÚpageIdé   é    z
User-AgentzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36c                 ó    — t        d| › �«       y )Nz[wjq] )Úprint)Úmsgs    ú/root/gov_crawler/crawl_wjq.pyÚlogr   :   s   € Ü	ˆF�3�%ˆ.Õó    c                 ó"   — | j                  «       S ©N©Ústrip)Útitles    r   Úclean_titler#   =   s   € Ø�;‰;‹=Ðr   c                 óØ  — t        t        «      }t        j                  | t        dœd¬«      |d<   	 t        j                  t        |t        d¬«      }|j                  «       }|j                  d
«      r!|j                  di «      j                  d«      sg dfS |d   d   }t        |d«      }g }|j                  d«      D ]î  }|j                  d«      }	|	r|	j                  d«      sŒ(|	d   j                  «       }
|
j                  d«      sd|
j!                  d«      z   }
|	j                  d«      }d}|r&|j                  dd«      xs |j#                  d¬«      }|	j                  d«      }|r|j#                  d¬«      nd}t%        t&        |
«      }|j)                  |t+        |«      |f«       Œð |t-        |«      dkD  fS # t        $ r}t        d| › d|› �«       g dfcY d	}~S d	}~ww xY w)z<Fetch one page via API, return [(url, title, date_str), ...])ÚpageNoÚpageSizeF)Úensure_asciiÚ	paramJsoné   )ÚparamsÚheadersÚtimeoutz  ERROR fetching page ú: NÚsuccessÚdataÚhtmlúhtml.parserÚliÚaÚhrefú/z./ÚpÚ r"   Tr    Úspanr   )ÚdictÚ
API_PARAMSÚjsonÚdumpsÚ	PAGE_SIZEÚrequestsÚgetÚAPI_URLÚHEADERSÚ	Exceptionr   r   Úfind_allÚfindr!   Ú
startswithÚlstripÚget_textr   ÚBASE_URLÚappendr#   Úlen)Úpager*   Úrespr/   Úer0   ÚsoupÚitemsr2   r3   r4   r6   r"   r8   Údate_strÚfull_urls                   r   Úfetch_list_pagerR   @   sÆ  € ä”*Ó€FÜŸ*™*°Ä)Ñ%LØ27ô9€Fˆ;ÑðÜ�|‰|œG¨F¼GÈRÔPˆØ�y‰y‹{ˆð
 �8‰8�IÔ d§h¡h¨v°rÓ&:×&>Ñ&>¸vÔ&FØ�5ˆyÐà�‰<˜Ñ€DÜ˜˜}Ó-€DØ€Eà�m‰m˜DÓ!ò ?ˆØ�G‰G�C‹LˆÙ˜Ÿ™˜fœØØ�‰y�‰Ó ˆØ�‰˜sÔ#Ø˜Ÿ™ TÓ*Ñ*ˆDð �F‰F�3‹KˆØˆÙØ—E‘E˜' 2Ó&Ò@¨!¯*©*¸4¨*Ó*@ˆEð �v‰v�f‹~ˆÙ04�4—=‘= t�=Ô,¸"ˆäœ8 TÓ*ˆØ�‰�h¤¨EÓ 2°HÐ=Õ>ð'?ð* ”#�e“*˜q‘.Ð Ð øôA ò ÜÐ$ T F¨"¨Q¨CÐ0Ô1Ø�5ˆyÕûðús   ²1G Ç	G)Ç
G$ÇG)Ç$G)c                 ó  — 	 t        j                  | t        d¬«      }d|_        |j                  }t        |d«      }d	}|j                  d
d¬«      }|rt        |«      }d	}|j                  dddi¬«      }|rM|j                  d«      r<|d   j                  «       }	t        j                  d|	«      }
|
r|
j                  d«      }|st        d| › �«       d|fS ||fS # t
        $ r}t        d| › d|› �«       Y d}~yd}~ww xY w)z/Return (content_html, date_str) or (None, None)r)   )r+   r,   zutf-8z  ERROR fetching r-   N)NNr1   r7   ÚdivÚ
zw_content)Úclass_ÚmetaÚnameÚPubDate)ÚattrsÚcontentz(\d{4}-\d{2}-\d{2})é   z  WARNING: no content for )r>   r?   rA   ÚencodingÚtextrB   r   r   rD   Ústrr!   ÚreÚmatchÚgroup)ÚurlrL   r0   rM   rN   Úcontent_htmlrT   rP   rW   ÚrawÚms              r   Úfetch_detailrg   k   s  € ðÜ�|‰|˜C¬¸"Ô=ˆØˆŒØ�y‰yˆô
 ˜˜}Ó-€Dð €LØ
�)‰)�E ,ˆ)Ó
/€CÙ
Ü˜3“xˆð €HØ�9‰9�V F¨IÐ#6ˆ9Ó7€DÙ�—‘˜Ô#Ø�9‰o×#Ñ#Ó%ˆÜ�H‰HÐ+¨SÓ1ˆÙØ—w‘w˜q“zˆHáÜÐ(¨¨Ð.Ô/Ø�Xˆ~Ðà˜Ð!Ð!øô3 ò ÜÐ ˜u B q cÐ*Ô+Üûðús   ‚/C Ã	DÃ&C<Ã<Dc           
      óÄ  — ddl }| st        d«       yt        dt        › �«       |j                  t        «      }|j	                  «       }d}| D ]-  \  }}}}	 |j                  dt        ||||t        f«       |dz  }Œ/ |j                  «        |j                  «        t        d	|› d
t        | «      › d�«       |S # t        $ r}	t        d|› d|	› �«       Y d}	~	ŒŒd}	~	ww xY w)zUpsert records into search.dbr   NzNo items to savezOpening DB: zœINSERT OR REPLACE INTO gov_raw
                   (site_name, page_url, title, publish_date, content, category)
                   VALUES (?, ?, ?, ?, ?, ?)r\   z  DB error for r-   zSaved r5   z records to DB)Úsqlite3r   ÚDB_PATHÚconnectÚcursorÚexecuteÚ	SITE_NAMEÚSOURCErB   ÚcommitÚcloserJ   )
rO   ri   ÚconnÚcÚinsertedrc   r"   rP   rd   rM   s
             r   Ú
save_to_dbru   Œ   sñ   € ãáÜÐÔØäˆ,”w�iÐ Ô!Ø�?‰?œ7Ó#€DØ�‰‹€Aà€HØ.3ò .Ñ*ˆˆU�H˜lð	.Ø�I‰Ið0ô ØØØØ Üðô	ð ˜‰M‰Hð.ð& 	‡K�K„MØ‡J�J„LÜˆ&��
˜!œC ›J˜< ~Ð6Ô7Ø€Oøô ò 	.Ü�/ #  b¨¨Ð,×-Ñ-ûð	.ús   Á%B;Â;	CÃCÃCc                  ó  — t        t        j                  «      dkD  xr t        j                  d   dk(  } t        j                  «       t        d¬«      z
  j                  d«      }t        d|› �«       g }t        dt        dz   «      D ]à  }t        |«      \  }}|st        d|› d�«        n¿|D ���cg c]  \  }}}|sŒ
||k\  sŒ|||f‘Œ }	}}}|j                  |	«       | rt        d	t        |	«      › d
�«        no|	rGt        |	«      t        |«      k  r0t        d„ |D «       «      }
|
|k  rt        d„ |D «       «      }||k  r n&|dz  dk(  sŒÆt        d|› dt        |«      › d
�«       Œâ t        dt        |«      › �«       g }t        |d«      D ]k  \  }\  }}}t        d|› dt        |«      › d|d d › d�«       t        |«      \  }}|xs |}|r|j!                  ||||f«       ŒW|j!                  |||df«       Œm t#        |«      }t        dd› �«       t        dt        |«      › d|› d�«       |r9t%        |D �cg c]  }|d   sŒ	|d   ‘Œ c}«      }t        d|d   › d|d    › �«       	 dd l}|j)                  t*        «      }|j-                  d!t.        f«       |j1                  «        |j3                  «        t        d"«       t        d› «       y c c}}}w c c}w # t4        $ r}t        d#|› �«       Y d }~Œ5d }~ww xY w)$Nr\   Ú1iG  )Údaysz%Y-%m-%dz3-year cutoff: zPage z: no data, stoppingzIncremental: page 1 only, z	 articlesc              3   ó.   K  — | ]  \  }}}|sŒ
|–— Œ y ­wr   © ©Ú.0Ú_Úds      r   ú	<genexpr>zmain.<locals>.<genexpr>É   s   è ø€ Ò:¡  A qºœ1Ñ:ùó   ‚Žc              3   ó.   K  — | ]  \  }}}|sŒ
|–— Œ y ­wr   rz   r{   s      r   r   zmain.<locals>.<genexpr>Ì   s   è ø€ Ò<¡7 1 a¨º!œQÑ<ùr€   r)   r   z  Scanned page z, total zTotal articles: ú[r5   z] é2   z...r7   ú
z2==================================================zDone. Total: z articles (saved: ú)é   zDate range: z ~ éÿÿÿÿa  
            INSERT OR REPLACE INTO gov_search(rowid, title, site_name, summary)
            SELECT rowid, title, site_name, 
                   CASE WHEN length(content) > 200 THEN substr(content, 1, 200) ELSE content END
            FROM gov_raw WHERE category = ?
        zFTS index rebuiltzFTS rebuild note: )rJ   ÚsysÚargvr   Únowr   Ústrftimer   ÚrangeÚ	MAX_PAGESrR   ÚextendÚminÚmaxÚ	enumeraterg   rI   ru   Úsortedri   rk   rj   rm   ro   rp   rq   rB   )ÚincrementalÚthree_years_agoÚall_articlesrK   ÚarticlesÚhas_dataÚuÚtr~   ÚfilteredÚearliestÚnewestÚresultsÚirc   r"   rP   rd   Údetail_dateÚ
final_dateÚsavedÚrÚdatesri   rr   rM   s                             r   Úmainr¤   ±   s  € Ü”c—h‘h“- !Ñ#Ò:¬¯©°©°sÑ(:€KÜ—|‘|“~¬	°wÔ(?Ñ?×IÑIÈ*ÓU€OÜˆ/˜/Ð*Ð+Ô,ð €LÜ�aœ Q™Ó'ò NˆÜ,¨TÓ2Ñˆ�(ÙÜ�%˜�vÐ0Ð1Ô2Ùð .6×TÐT¡' ! Q¨º¸qÀOÓ?S�Q˜˜1’IÐTˆÒTØ×Ñ˜HÔ%áÜÐ,¬S°«]¨O¸9ÐEÔFÙñ œ˜H›¬¨H«Ò5äÑ:¨HÔ:Ó:ˆHØ˜/Ò)äÑ<¨hÔ<Ó<�Ø˜OÒ+Ùà�"‰9˜‹>Ü�/ $  x´°LÓ0AÐ/BÀ)ÐLÕMð3Nô6 Ð
œ3˜|Ó,Ð-Ð.Ô/ð €GÜ%.¨|¸QÓ%?ò 9Ñ!ˆÑ!ˆC�˜Üˆa�ˆs�!”C˜Ó%Ð& b¨¨s°¨¨°CÐ8Ô9Ü$0°Ó$5Ñ!ˆ�kØ Ò, Hˆ
ÙØ�N‰N˜C ¨
°LÐAÕBà�N‰N˜C ¨
°BÐ7Õ8ð9ô �wÓ€Eô ˆ"ˆVˆHˆÔÜˆ-œ˜G›�~Ð%7¸°w¸aÐ@ÔAÙÜ gÖ6 °°1³˜˜!›Ò6Ó7ˆÜˆl˜5 ™8˜* C¨¨b©	 {Ð3Ô4ð&ÛØ�‰œwÓ'ˆØ�‰ð ô
 ˆYô	ð 	�‰ŒØ�
‰
ŒÜÐÔ ô ˆ6ˆ(Õùôw UùòP 7øô  ò &ÜÐ   Ð$×%Ñ%ûð&ús7   Â2K
Â>K
ÃK
È=
KÉKÉ.AK" Ë"	LË+K>Ë>LÚ__main__)Ú__doc__Úosr`   rˆ   r;   r>   Úbs4r   Úurllib.parser   r   r   Úenvironr?   rj   rH   r@   rn   ro   r:   r=   r�   rA   r   r#   rR   rg   ru   r¤   Ú__name__rz   r   r   ú<module>r¬      sØ   ðñó" 
Û 	Û 
Û Û Ý Ý  ß (ð �*‰*�.‰.˜ b§j¡j§n¡n°]ÐDUÓ&VÓ
W€ð $€Ø
ÐNÑ
N€Ø/€	Ø	#€ð Ø$Ø'ØØ$ØØ%ñ€
ð €	Ø€	ð ð 3ð€òòò)!òV"òB#òJIðX ˆzÒÙ…Fð r   