Ë
    +'˜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ZddlmZ ddl	m
Z
 ej                  j                  dej                  j                  ej                  j                  e«      «      «       ddlmZmZmZmZmZmZ dZdZdZd	ZdZ ej8                  d
d«      Zd„ Zd„ Zd„ Z d„ Z!d„ Z"d„ Z#d)d„Z$e%dk(  �r/ddl&Z& e&jN                  de› �¬«      Z(e(jS                  de*d¬«       e(jS                  ddd¬«       e(jW                  «       Z,e,jZ                  r� e«       Z.e.j_                  d«      ja                  «       d   Z1e.j_                  def«      ja                  «       d   Z2 e3de1› d e› d!e2› d"�«       e.ji                  «         ejj                  d«        e3d#e› d$�«        ej                  «       Z6 e$e,jn                  ¬%«        e3d& ej                  «       e6z
  d'›d(�«       yy)*u/  
crawl_lc_sthj_v2.py â€” é™µå·�åŽ¿äººæ°‘æ”¿åºœ-éƒ¨é—¨å·¥ä½œï¼ˆçŽ¯å¢ƒä¿�æŠ¤ç›¸å…³ï¼‰
==========================================================
åˆ—è¡¨é¡µ: http://xxgk.lczf.gov.cn/lczxdw/lcsthjj/fdzdgknr/gzdt/
ç»“æž„:   ul.list-items-box-inner > li (20æ�¡ï¼Œå”¯ä¸€é¡µï¼Œæ— åˆ†é¡µ)
è¯¦æƒ…é¡µ: div#Zoom æ­£æ–‡
å­˜å‚¨:   /root/search.db (gov_raw + gov_search_v3)

ç”¨æ³•:
    python3 crawl_lc_sthj_v2.py              # å…¨é‡�çˆ¬
    python3 crawl_lc_sthj_v2.py --limit=5    # æµ‹è¯•å�ªçˆ¬5æ�¡
    python3 crawl_lc_sthj_v2.py --stats      # æŸ¥çœ‹ search.db ç»Ÿè®¡
é    N)Úurljoin)ÚBeautifulSoup)Ú
fetch_pageÚ
parse_dateÚ
clean_htmlÚextract_date_from_htmlÚextract_content_by_selectorÚ
save_jsonlu   é™µå·�åŽ¿-éƒ¨é—¨å·¥ä½œzhttp://xxgk.lczf.gov.cnz5http://xxgk.lczf.gov.cn/lczxdw/lcsthjj/fdzdgknr/gzdt/z#ZoomÚ	SEARCH_DBz/root/search.dbc                  ó  — t         j                  j                  t        «      } | rt        j                  | d¬«       t        j                  t        d¬«      }|j                  d«       |j                  d«       |j                  d«       |S )u'   èŽ·å�– search.db è¿žæŽ¥ï¼ˆWAL æ¨¡å¼�ï¼‰T)Úexist_oké   )ÚtimeoutzPRAGMA journal_mode=WALzPRAGMA synchronous=NORMALzPRAGMA busy_timeout=30000)ÚosÚpathÚdirnameÚDB_PATHÚmakedirsÚsqlite3ÚconnectÚexecute)Údb_dirÚconns     ú%/root/gov_crawler/crawl_lc_sthj_v2.pyÚget_dbr   1   sa   € ä�W‰W�_‰_œWÓ%€FÙÜ
�‰�F TÕ*Ü�?‰?œ7¨BÔ/€DØ‡L�LÐ*Ô+Ø‡L�LÐ,Ô-Ø‡L�LÐ,Ô-Ø€Kó    c                 óâ   — | j                  d«       	 | j                  d«       | j                  d«       | j                  d«       | j                  «        t        d«       y# t        $ r Y ŒIw xY w)u=   åˆ›å»º gov_raw + gov_search_v3ï¼ˆFTS5ï¼‰è¡¨ï¼ˆå¦‚ä¸�å­˜åœ¨ï¼‰a9  CREATE TABLE IF NOT EXISTS gov_raw (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        site_name TEXT,
        source_url TEXT,
        page_url TEXT,
        title TEXT,
        publish_date TEXT,
        summary TEXT,
        content TEXT,
        status TEXT,
        category TEXT,
        tags TEXT
    )zOCREATE UNIQUE INDEX IF NOT EXISTS idx_gov_raw_source_url ON gov_raw(source_url)zACREATE INDEX IF NOT EXISTS idx_gov_raw_site ON gov_raw(site_name)zDCREATE INDEX IF NOT EXISTS idx_gov_raw_date ON gov_raw(publish_date)u     [DB] è¡¨å°±ç»ª: gov_rawN)r   Ú	ExceptionÚcommitÚprint)r   s    r   Úensure_tablesr!   =   si   € ð 	‡L�Lð 	ô 
ðØ�‰ÐfÔgð 	‡L�LÐTÔUØ‡L�LÐWÔXØ‡K�K„MÜ	Ð%Õ'øô ò Ùðús   “A" Á"	A.Á-A.c                 óL   — | j                  d|f«      }|j                  «       duS )u   æ£€æŸ¥ page_url æ˜¯å�¦å·²å­˜åœ¨z&SELECT 1 FROM gov_raw WHERE page_url=?N)r   Úfetchone)r   Úpage_urlÚcurs      r   Ú
row_existsr&   X   s&   € à
�,‰,Ð?À(ÀÓ
M€CØ�<‰<‹> Ð%Ð%r   c                 óT  — |j                  d«      xs ddd }|j                  dd«      }|j                  d«      xs ddd }|j                  dd«      }|j                  d	d«      }|sA|r?t        j                  d
d|«      }t        j                  dd|«      j                  «       dd }|j                  dd«      }	 |}| j	                  dt
        |||||||f«       | j	                  d«      j                  «       d   }	|	dkD  ryy# t        $ r}
t        d|
› �«       Y d}
~
yd}
~
ww xY w)uY   æ�’å…¥ä¸€æ�¡è®°å½•åˆ° gov_raw + gov_search_v3

    è¿”å›ž: True=æ–°å¢ž, False=è·³è¿‡
    ÚtitleÚ Niô  ÚurlÚpub_dateé
   ÚcontentÚsummaryz<[^>]+>ú z\s+Úcategoryz¨INSERT OR IGNORE INTO gov_raw
            (site_name, title, source_url, page_url, publish_date, summary, content, category)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)zSELECT changes()r   TFz  [DB ERROR] )	ÚgetÚreÚsubÚstripr   Ú	SITE_NAMEr#   r   r    )r   Úitemr(   r$   Úpublish_dater-   r.   r0   Ú
source_urlÚaffectedÚes              r   Ú
insert_rowr;   ^   s4  € ð
 �X‰X�gÓÒ$ " d sÐ+€EØ�x‰x˜˜rÓ"€HØ—H‘H˜ZÓ(Ò.¨B°°Ð4€LØ�h‰h�y "Ó%€Gð �h‰h�y "Ó%€GÙ‘wÜ—&‘&˜ S¨'Ó2ˆÜ—&‘&˜  gÓ.×4Ñ4Ó6°t¸Ð<ˆà�x‰x˜
 BÓ'€Hðàˆ
Ø�‰ð /ô ˜˜z¨8°\À7ÈGÐU]Ð^ô	`ð —<‘<Ð 2Ó3×<Ñ<Ó>¸qÑAˆØ�aŠ<àØøÜò Ü�˜a˜SÐ!Ô"Üûðús   Â=AD Ä	D'ÄD"Ä"D'c                 ó  — g }t        | d«      }|j                  dd¬«      }|st        d«       |S |j                  d«      D ]Á  }|j                  d«      }|sŒ|j	                  dd	«      j                  «       }|j                  d
¬«      }|s|j	                  dd	«      }d	}|j                  d«      }	|	r|	j                  d
¬«      }|r!|j                  d«      st        t        |«      }|sŒª|sŒ­|j                  |||dœ«       ŒÃ |S )uâ   ä»Žåˆ—è¡¨é¡µ HTML æ��å�–æ‰€æœ‰æ�¡ç›®

    ul.list-items-box-inner > li
    æ¯�ä¸ª li åŒ…å�«: <a href="./202604/...shtml">æ ‡é¢˜</a> <span>2026-04-29</span>

    è¿”å›ž: [{"title": "...", "url": "...", "date": "..."}, ...]
    úhtml.parserÚulzlist-items-box-inner)Úclass_z*  [WARN] ul.list-items-box-inner not foundÚliÚaÚhrefr)   T)r4   r(   ÚspanÚhttp)r(   r*   Údate)r   Úfindr    Úfind_allr1   r4   Úget_textÚ
startswithr   ÚLIST_URLÚappend)
ÚhtmlÚitemsÚsoupr>   r@   rA   rB   r(   r+   rC   s
             r   Úget_list_itemsrO   ‡   s	  € ð €EÜ˜˜}Ó-€DØ	�‰�4Ð 6ˆÓ	7€BÙÜÐ:Ô;Øˆà�k‰k˜$Óò ˆØ�G‰G�C‹LˆÙØØ�u‰u�V˜RÓ ×&Ñ&Ó(ˆØ—
‘
 �
Ó&ˆÙØ—E‘E˜' 2Ó&ˆEð ˆØ�w‰w�v‹ˆÙØ—}‘}¨4�}Ó0ˆHñ ˜Ÿ™¨Ô/Üœ8 TÓ*ˆDâ’TØ�L‰LØØØ ñõ ð)ð4 €Lr   c                 ó  — t        | «      }|sdddœS t        |t        «      }|rt        |«      dk  rKt	        |d«      }|j                  dd¬«      }|rt        |«      }n|j                  d«      }|rt        |«      }t        |«      }||dœS )	ur   è®¿é—®è¯¦æƒ…é¡µï¼Œè¿”å›žæ­£æ–‡ HTML å’Œå�‘å¸ƒæ—¶é—´

    è¿”å›ž: {"content": "...", "pub_date": "YYYY-MM-DD"}
    r)   )r-   r+   é2   r=   ÚdivÚZoom)ÚidÚbody)r   r	   ÚDETAIL_SELECTORÚlenr   rF   Ústrr   )r*   rL   r-   rN   ÚzoomrU   r+   s          r   Ú
get_detailrZ   ·   s”   € ô
 �c‹?€DÙØ¨2Ñ.Ð.ô *¨$´Ó@€Gñ ”c˜'“l RÒ'Ü˜T =Ó1ˆØ�y‰y˜ 6ˆyÓ*ˆÙÜ˜$“i‰Gà—9‘9˜VÓ$ˆDÙÜ˜d›)�ô & dÓ+€Hà¨HÑ5Ð5r   c                 ó   — t        dt        › �«       t        t        «      }|st        d«       yt        |«      }t        dt	        |«      › d�«       | r|d|  }t        «       }t        |«       d\  }}t        |d«      D �]'  \  }}t        ||d   «      r|dz  }d	}nnt        |d   «      }	|	d
   xs |j                  dd«      }
|d   |d   |	d   |
dœ}t        |t        ¬«      }t        |«       t        ||«      r|dz  }d}n|dz  }d}|j                  «        |j                  dd«      xs t!        «       j                  d
«      xs d}|dz  dk(  s|t	        |«      k(  r+t        d|› dt	        |«      › d|› d|d   dd › d|› �
«       �Œt        d|› d|d   dd › d|› �«       �Œ* |j#                  «        t        d|› d|› �«       ||fS )u$   å…¨é‡�çˆ¬å�–ï¼ˆå�•é¡µï¼Œæ— åˆ†é¡µï¼‰u     åˆ—è¡¨é¡µ: z#  [ERROR] Failed to fetch list page)r   r   u     åˆ—è¡¨é¡µ: æ��å�– õ    æ�¡Né   r*   u   â�­ å·²å­˜åœ¨r+   rE   r)   r(   r-   )r(   r*   r-   r+   )Ú	site_nameu
   âœ… æ–°å¢žu   â�­ å†™å…¥å¤±è´¥é   r   z  [ú/z] r/   é(   z... z  u     âœ… å®Œæˆ�: æ–°å¢žu   , è·³è¿‡)r    rJ   r   rO   rW   r   r!   Ú	enumerater&   rZ   r1   Údictr5   r
   r;   r   ÚlocalsÚclose)Ú	max_itemsrL   rM   r   ÚokÚfailÚir6   ÚstatusÚdetailr+   ÚentryÚentry_with_siteÚdisplay_dates                 r   Úcrawlro   Ø   s  € ä	ˆMœ(˜Ð
$Ô%ä”hÓ€DÙÜÐ3Ô4Øä˜4Ó €EÜ	Ð ¤ U£ ¨DÐ
1Ô2áØ�j�yÐ!ˆô ‹8€DÜ�$Ôà�H€BˆÜ˜U AÓ&ó $H‰ˆˆ4ä�d˜D ™KÔ(Ø�A‰IˆDØ$‰Fä  U¡Ó,ˆFð ˜jÑ)ÒA¨T¯X©X°f¸bÓ-AˆHð ˜g™Ø˜E‘{Ø! )Ñ,Ø$ñ	ˆEô # 5´IÔ>ˆOÜ�Ô'ô ˜$ Ô&Ø�a‘�Ø%‘à˜‘	�Ø+�à�‰Œà—x‘x  rÓ*ÒN¬v«x¯|©|¸JÓ/GÒ/MÈ2ˆØˆq‰5�AŠ:˜œc %›jšÜ�C˜�s˜!œC ›J˜< r¨,¨°q¸¸g¹ÀsÈÐ9KÐ8LÈDÐQWÐPXÐYÖZä�B�|�n A d¨7¡m°C°RÐ&8Ð%9¸¸f¸XÐFÖGðI$HðL 	‡J�J„LÜ	Ð    H¨T¨FÐ
3Ô4Øˆtˆ8€Or   Ú__main__u   çˆ¬è™«: )Údescriptionz--limitu   æµ‹è¯•ï¼šå�ªè·‘ N æ�¡)ÚtypeÚhelpz--statsÚ
store_trueu   æŸ¥çœ‹ search.db ç»Ÿè®¡)Úactionrs   zSELECT COUNT(*) FROM gov_rawz.SELECT COUNT(*) FROM gov_raw WHERE site_name=?u   ðŸ“Š search.db (gov_raw): å…± u    æ�¡, å…¶ä¸­ 'z' r\   u   
ðŸ“¡ [u   ] å¼€å§‹çˆ¬å�–)rf   u   â�± è€—æ—¶: z.1fzs
)N)8Ú__doc__r2   Úsysr   Útimer   ÚjsonÚurllib.parser   Úbs4r   r   Úinsertr   ÚabspathÚ__file__Úcrawler_libr   r   r   r   r	   r
   r5   ÚBASE_URLrJ   rV   ÚPAGE_URL_PATTERNÚgetenvr   r   r!   r&   r;   rO   rZ   ro   Ú__name__ÚargparseÚArgumentParserÚparserÚadd_argumentÚintÚ
parse_argsÚargsÚstatsr   r   r#   ÚtotalÚ
site_countr    re   ÚexitÚt0Úlimit© r   r   ú<module>r’      sã  ðñ÷ (× '× 'Ý  Ý à ‡�‡���2—7‘7—?‘? 2§7¡7§?¡?°8Ó#<Ó=Ô >÷÷ ð %€	Ø%€ØC€ð €ð Ð ð ˆ"�)‰)�KÐ!2Ó
3€ò	ò(ò6&ò"òR)ò`6óB<ð~ ˆzÓÛØ$ˆX×$Ñ$°8¸I¸;Ð1GÔH€FØ
×Ñ˜	¨Ð2IÐÔJØ
×Ñ˜	¨,Ð=VÐÔWØ×ÑÓ€Dà‡z‚zÙ‹xˆØ—‘Ð;Ó<×EÑEÓGÈÑJˆØ—\‘\Ø<¸y¸ló
ç
‰(‹*�Qñˆ
ñ 	Ð.¨u¨g°^ÀIÀ;ÈbÐQ[ÐP\Ð\`ÐaÔbØ�
‰
ŒØˆ�‰�Œá	ˆH�Y�K˜~Ð
.Ô/Ø	ˆ�‰‹€BÙ	�D—J‘JÕÙ	ˆL˜˜Ÿ™› R™¨Ð,¨CÐ
0Õ1ð) r   