Ë
    ¸¬uj'  ã                   óÄ  — 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	m
Z
 d dlmZ dZdZdZ e j                   dd	«      Zd
Zdej&                  v ZdZddddœZ ej.                  e«      Zej3                  «       Z ej6                   e	 e
d¬«      «      «      j9                  d¬«       e
dez  ¬«      z
  Zd„ Zd„ Zd„ Z d„ Z!d„ Z"d„ Z#d„ Z$e%dk(  r e$«        yy)é    N)ÚBeautifulSoup)ÚdatetimeÚtimezoneÚ	timedelta)Úurljoinz4http://zzb.ahhn.gov.cn/index/index/lst/id/10048.htmlzzzb.ahhn.gov.cnu   æ€€å®�å…ˆé”‹ç½‘Ú	SEARCH_DBz/root/search.dbé   z--incrementalé   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)z
User-AgentÚAcceptzAccept-Languageé   )Úhours©Útzinfoim  )Údaysc                  óÖ   — t         › d�} 	 t        j                  | t        d¬«      }d|_        t        j                  d|j                  «      }|rt        d„ |D «       «      S 	 y#  Y yxY w)Nz?id=10048&page=100é   ©ÚheadersÚtimeoutúutf-8z
page=(\d+)c              3   ó2   K  — | ]  }t        |«      –— Œ y ­w)N)Úint)Ú.0Úps     ú/root/gov_crawler/crawl_ahhn.pyú	<genexpr>z get_last_page.<locals>.<genexpr>*   s   è ø€ Ò- !”s˜1—vÑ-ùs   ‚é   )	ÚBASE_URLÚrequestsÚgetÚHEADERSÚencodingÚreÚfindallÚtextÚmax)ÚurlÚrÚpagess      r   Úget_last_pager*   #   sl   € ÜˆJÐ(Ð
)€CðÜ�L‰L˜¤g°rÔ:ˆØˆŒ
Ü—
‘
˜=¨!¯&©&Ó1ˆÙÜÑ- uÔ-Ó-Ð-ð ð øðØØús   ‹AA$ Á$A(c                 ó¾  — g }t        j                  d| «      }|dd  D ]¼  }t        j                  d|t         j                  «      }|sŒ+|j	                  d«      j                  «       }t        j                  dd|j	                  d«      «      j                  «       }t        j                  d|«      }|r|j	                  d«      nd}|j                  |||f«       Œ¾ |S )Nz<div class="newslist yenews">r   z$<a[^>]*href="([^"]+)"[^>]*>(.*?)</a>z<[^>]+>Ú é   z&<span>\s*(\d{4}-\d{2}-\d{2})\s*</span>)r#   ÚsplitÚsearchÚDOTALLÚgroupÚstripÚsubÚappend)	ÚhtmlÚitemsÚpartsÚpartÚmr'   ÚtitleÚdmÚdate_strs	            r   Úparse_list_pager=   /   s¿   € Ø€EÜ�H‰HÐ5°tÓ<€EØ�a�b�	ò -ˆÜ�I‰IÐ=¸tÄRÇYÁYÓOˆÙØØ�g‰g�a‹j×ÑÓ ˆÜ—‘�z 2 q§w¡w¨q£zÓ2×8Ñ8Ó:ˆÜ�Y‰YÐ@À$ÓGˆÙ"$�2—8‘8˜A”;¨"ˆØ�‰�e˜S (Ð+Õ,ð-ð €Ló    c                 ó\  — 	 t        j                  | t        d¬«      }d|_        |j                  }t        |d«      }|j                  d«      }d	}|rK|j                  d
¬«      }dD ]$  }|j                  |«      sŒ|d t        |«        } n |j                  «       }|j                  dt        j                  d«      ¬«      }	|	s&|j                  dt        j                  d«      ¬«      }	|	s&|j                  dt        j                  d«      ¬«      }	|	s&|j                  dt        j                  d«      ¬«      }	d	}
|	rt        |	«      }
d	}g d¢}|D ]-  }t        j                   ||«      }|sŒ|j#                  d«      } n ||
|fS # t
        $ r}t        d| › d|› �«       Y d }~yd }~ww xY w)Nr   r   r   z  [ERROR] fetch ú: )NNNzhtml.parserr:   r,   T)r2   )u   -æ€€å®�å…ˆé”‹ç½‘u   â€”æ€€å®�å…ˆé”‹ç½‘u   -æ€€å®�å…ˆé”‹u   â€”æ€€å®�å…ˆé”‹Úarticlez
content-wz)Úclass_z
content-sjÚdiv)u   å�‘å¸ƒï¼š(\d{4}-\d{2}-\d{2})u"   å�‘å¸ƒæ—¶é—´ï¼š(\d{4}-\d{2}-\d{2})u   æ—¥æœŸï¼š(\d{4}-\d{2}-\d{2})r   )r   r    r!   r"   r%   Ú	ExceptionÚprintr   ÚfindÚget_textÚendswithÚlenr2   r#   ÚcompileÚstrr/   r1   )r'   r(   r5   ÚeÚsoupÚ	title_tagr:   ÚtÚsuffixÚcontent_divÚcontent_htmlr<   Údate_patternsÚpatr;   s                  r   Úfetch_detailrU   =   sŸ  € ð Ü�L‰L˜¤g°rÔ:ˆØˆŒ
Ø�v‰vˆô
 ˜˜}Ó-€Dà—	‘	˜'Ó"€IØ€EÙØ×Ñ TÐÓ*ˆØdò 	ˆFØ�z‰z˜&Õ!Ø�nœ˜V›˜Ð%�Ùð	ð —‘“	ˆà—)‘)˜I¬b¯j©j¸Ó.G�)ÓH€KÙØ—i‘i 	´"·*±*¸]Ó2K�iÓLˆÙØ—i‘i ¬b¯j©j¸Ó.G�iÓHˆÙØ—i‘i ¬b¯j©j¸Ó.G�iÓHˆà€LÙÜ˜;Ó'ˆà€Hò€Mð
 ò ˆÜ�Y‰Y�s˜DÓ!ˆÚØ—x‘x “{ˆHÙð	ð �, Ð(Ð(øôQ ò  ÜÐ    R¨ sÐ+Ô,Üûð ús   ‚/F Æ	F+ÆF&Æ&F+c                 ód   — t         j                  d| f«       t         j                  «       d   dkD  S )Nz/SELECT COUNT(*) FROM gov_raw WHERE page_url = ?r   )ÚcÚexecuteÚfetchone)Úpage_urls    r   Úarticle_existsr[   l   s(   € Ü‡I�IÐ?À(ÀÔMÜ�:‰:‹<˜‰?˜QÑÐr>   c                 óH   — 	 t         j                  d| ||df«       y#  Y yxY w)z@Manually sync FTS5 after REPLACE (trigger only fires on INSERT).zWINSERT OR REPLACE INTO gov_search(rowid, title, site_name, summary) VALUES (?, ?, ?, ?)r,   N)rW   rX   )Úrow_idr:   Ú	site_names      r   Úsync_ftsr_   p   s,   € ðÜ	�	‰	ÐkØ˜5 )¨RÐ0õ	2øðÙús   ‚ �!c                 ó²  — t        t        |«      }|j                  dd«      j                  dd«      }d}t        j	                  d|f«       t        j                  «       }|r|d   nd }	 t        j	                  d|| ||t        ||df«       |r|}	nt        j                  }	|	rt        |	| t        «       y# t        $ r}
t        d|
› �«       Y d }
~
y	d }
~
ww xY w)
Nzhttp://r,   zhttps://z)SELECT id FROM gov_raw WHERE page_url = ?r   z©INSERT OR REPLACE INTO gov_raw
            (page_url, title, content, publish_date, site_name, source_url, summary, category)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)Tz  [DB ERROR] F)r   r   ÚreplacerW   rX   rY   Ú	SITE_NAMEÚ	lastrowidr_   rD   rE   )r:   rZ   rR   r<   Úfull_urlÚdisplay_urlÚsummaryÚrowÚexisting_idr]   rL   s              r   Úinsert_articleri   x   sÔ   € Ü”x Ó*€HØ×"Ñ" 9¨bÓ1×9Ñ9¸*ÀbÓI€KØ€Gô ‡I�IÐ9¸H¸;ÔGÜ
�*‰*‹,€CÙ�#�a’& T€KðÜ	�	‰	ð /ð �u˜l¨H´iÀÈgÐWYÐZô	\ñ
 Ø ‰Fä—[‘[ˆFñ Ü�V˜U¤IÔ.ØøÜò Ü�˜a˜SÐ!Ô"Üûðús   Á*A
B5 Â5	CÂ>CÃCc            	      ó$  — d} d}d}t        «       }|t        kD  rt        }t        dt        › �«       t        d|› �«       t        d|dz   «      D �]£  }|dk(  rt        }nt        › d|› �}t        d|› d|› d|› �«       d }t        d	«      D ]'  }	 t        j                  |t        d
¬«      }d|_         n |€Œit        |j                  «      }	|	st        d|› �«       Œ�t        dt        |	«      › d�«       |	D ]ø  \  }
}}t        t        |«      }|r7	 t!        j"                  |d«      }|t$        j'                  d ¬«      k  r|dz  }ŒO	 t)        |«      }t*        r|r|dz  }Œit        d|
d d › d�d¬«       t-        |«      \  }}}|s|
}|sd}t        dd¬«       |s|r|}t/        ||||«      r$|r|dz  }t        d«       n| dz  } t        d«       nt        d«       t        j                  d«       Œú �Œ¦ t0        j3                  «        t0        j5                  «        t        d | › d!|› d"|› �«       y # t        $ rK}|dk  r(t        d|dz   › d�«       t        j                  d	«       nt        d|› d|› �«       d }Y d }~�Œ÷d }~ww xY w#  Y �ŒGxY w)#Nr   z  Pages limited to z  Pages to crawl: 1-r   z?id=10048&page=z  List page ú/r@   r
   é   r   r   r-   z
    Retry z...z  [ERROR] list page z   [WARN] No items found on page z
    Found z itemsz%Y-%m-%dr   z    Fetching: é   ú )Úendu   <p>å†…å®¹åŠ è½½å¤±è´¥</p>z
no contentÚupdatedÚinsertedÚFAILEDg333333Ó?u   
  âœ… å®Œæˆ�: æ–°å¢ž u	   , æ›´æ–° u	   , è·³è¿‡ )r*   Ú	MAX_PAGESrE   Úranger   r   r    r!   r"   rD   ÚtimeÚsleepr=   r%   rI   r   r   ÚstrptimeÚcutoff_datera   r[   ÚINCREMENTALrU   ri   ÚconnÚcommitÚclose)Ú	total_newÚtotal_updatedÚtotal_skippedÚ	last_pageÚpager'   r(   ÚattemptrL   r6   r:   Úitem_urlÚ	list_daterd   Ú	item_dateÚexistsÚd_titlerR   Údetail_dates                      r   Úmainr‰   •   sÀ  € Ø€IØ€MØ€Mä“€IØ”9ÒÜˆ	ÜÐ#¤I ;Ð/Ô0ä	Ð   Ð
,Ô-ä�a˜ Q™Ó'ó GˆØ�1Š9Ü‰Cä�J˜o¨d¨VÐ4ˆCä�˜T˜F ! I ;¨b°°Ð6Ô7ð ˆÜ˜Q“xò 	ˆGð
Ü—L‘L ¬g¸rÔB�Ø$�”
Ùð		ð ˆ9Øä §¡Ó'ˆÙÜÐ4°T°FÐ;Ô<Øä�
œ3˜u›:˜, fÐ-Ô.à*/ò &	Ñ&ˆE�8˜YÜœx¨Ó2ˆHáðÜ (× 1Ñ 1°)¸ZÓ H�IØ ¤;×#6Ñ#6¸dÐ#6Ó#CÒCØ%¨Ñ*˜Ø ð Dô $ HÓ-ˆFÝ™vØ Ñ"�Øä�N 5¨¨" : ,¨cÐ2¸Õ<Ü1=¸hÓ1GÑ.ˆG�\ ;áØ�ÙØ:�Ü�l¨Õ,Ù¡9Ø'�ä˜g x°¸{ÔKÙØ! QÑ&�MÜ˜)Õ$à ‘N�IÜ˜*Õ%ä�h”ä�J‰J�s�OòM&	ðCGôR 	‡K�K„MÜ‡J�J„Lä	Ð# I ;¨i¸°ÀiÐP]ÈÐ
_Õ`øô{ ò Ø˜Q’;Ü˜J w¨q¡y k°Ð5Ô6Ü—J‘J˜q•MäÐ0°°°b¸¸Ð<Ô=Ø�Aÿùðûð6Úús%   Â#H3Ä4J
È3	JÈ<A JÊJÊ
JÚ__main__)&Úosr#   Úsysru   Úsqlite3r   Úbs4r   r   r   r   Úurllib.parser   r   ÚDOMAINrb   ÚgetenvÚDB_PATHrs   Úargvry   Ú
YEAR_LIMITr!   Úconnectrz   ÚcursorrW   Únowra   rx   r*   r=   rU   r[   r_   ri   r‰   Ú__name__© r>   r   ú<module>rš      s	  ðã 	ðó 
Û 
Û Û Û Ý ß 2Ñ 2Ý  àA€Ø	€Ø€	Ø
ˆ"�)‰)�KÐ!2Ó
3€Ø€	Ø §¡Ð)€Ø€
ð DØOØ'ñ€ð €w‡��wÓ€Ø‡K�KƒM€àˆh�l‰l™8¡I°AÔ$6Ó7Ó8×@Ñ@ÈÐ@ÓMÑPYÐ_bÐeoÑ_oÔPpÑp€ò
òò-)ò^òòò:Xaðt ˆzÒÙ…Fð r>   