Ë
    ¸¬uj/  ã                   óð  — 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mZ ddl	m
Z
 ddlmZ  ej                  dd«      ZdZd	Zd
ZdZe› d�ZdddddddddddddœZddddœZd„ Zd„ Zd„ Zd „ Zd!„ Zd"„ Zd.d#„Zd/d$„Zd%„ Zed&k(  rq e ejB                  «      d'kD  rejB                  d'   nd(Z"e"d(k(  r e«        ye"d)v r
 ed*¬+«       ye"dk(  r* ed'«      Z#e#re#jI                  d,d«      ndZ% ed-e%› �«       yyy)0uÅ   
Crawler: èŠœæ¹–å¸‚å¼‹æ±ŸåŒºç”Ÿæ€�çŽ¯å¢ƒåˆ†å±€ - è¡Œæ”¿å®¡æ‰¹ (Epoint åŸºå±‚æ”¿åŠ¡å…¬å¼€, catId=1141240)
Fix: content is in yjq.gov.cn page (j-fontContent gkwz_contnet), preserving tables as HTML.
é    N)ÚdatetimeÚ	timedelta)ÚBeautifulSoup)ÚurljoinÚ	SEARCH_DBz/root/search.dbu'   å¼‹æ±ŸåŒºç”Ÿæ€�çŽ¯å¢ƒåˆ†å±€è¡Œæ”¿å®¡æ‰¹u   è¡Œæ”¿å®¡æ‰¹zhttps://www.yjq.gov.cnzhttps://sthjj.wuhu.gov.cnz/wuhu/site/label/8888ÚgrassrootsContentPageListÚ6787891Ú6603431Ú15Ú1Útruez
yyyy-MM-ddÚ50Ú4ÚlistÚ1141240)Ú	labelNameÚsiteIdÚorganIdÚpageSizeÚ	pageIndexÚisDateÚ
dateFormatÚlengthÚtypeÚactionÚisJsonÚcatIdzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36z!application/json, text/plain, */*z0application/x-www-form-urlencoded; charset=UTF-8)z
User-AgentÚAcceptzContent-Typec                 ó2   — t        dt        › d| › �d¬«       y )Nú[z] T)Úflush)ÚprintÚSITE)Úmsgs    ú#/root/gov_crawler/crawl_yjq_xzsp.pyÚlogr&   '   s   € Ü	ˆAŒdˆV�2�c�UÐ
 4Ö(ó    c                 óÚ   — i t         ¥dt        | «      i¥}	 t        j                  t        |t
        dd¬«      }|j                  «       S # t        $ r}t        d|› �«       Y d }~y d }~ww xY w)Nr   é   F)ÚdataÚheadersÚtimeoutÚverifyzAPI error: )	ÚAPI_DATAÚstrÚrequestsÚpostÚAPI_URLÚHEADERSÚjsonÚ	Exceptionr&   )Ú
page_indexr*   ÚrÚes       r%   Úfetch_list_pager9   +   s`   € Ø5ŒhÐ5˜¤S¨£_Ñ5€DðÜ�M‰Mœ'¨´gÀrÐRWÔXˆØ�v‰v‹xˆøÜò Üˆk˜!˜ÐÔÜûðús   —1A	 Á		A*ÁA%Á%A*c                 ó¾   — 	 t        j                  | t        dd¬«      }d|_        |j                  | fS # t
        $ r}t        d| › d|› �«       d | fcY d }~S d }~ww xY w)Nr)   F)r+   r,   r-   zutf-8zFetch error for ú: )r0   Úgetr3   ÚencodingÚtextr5   r&   )Ú
detail_urlr7   r8   s      r%   Úfetch_detailr@   5   sb   € ð Ü�L‰L˜¬W¸bÈÔOˆØˆŒ
Ø�v‰v�zÐ!Ð!øÜò  ÜÐ˜z˜l¨"¨Q¨CÐ0Ô1Ø�ZÐÕûð ús   ‚14 ´	A½AÁAÁAc                 óp   — t        | d«      }|j                  dd„ ¬«      }|rt        t        |«      «      S y)z\Extract content from j-fontContent div. Works for both gkwz_contnet and newscontnet minh500.úhtml.parserÚdivc                 ó.   — | xr d| j                  «       v S )Nzj-fontContent)Úsplit)Úcs    r%   ú<lambda>z&get_content_by_class.<locals>.<lambda>C   s   € °AÒ4V¸/ÈQÏWÉWËYÐ:V€ r'   )Úclass_Ú )r   ÚfindÚ_clean_contentr/   )ÚhtmlÚsoupÚcontent_divs      r%   Úget_content_by_classrO   ?   s7   € ä˜˜}Ó-€Dà—)‘)˜EÑ*V�)ÓW€KÙÜœc +Ó.Ó/Ð/Ør'   c                 ó   — | syt        | d«      }|j                  dd¬«      D ]R  }|j                  dd«      }|j                  d¬«      xs d}t	        t
        |«      }|j                  d	|› d
|› d�«       ŒT |j                  g d¢«      D ]  }|j                  «        Œ g }|j                  ddg«      D ]u  }|j                  dk(  r|j                  t        |«      «       Œ-|j                  dk(  sŒ=|j                  d«      rŒO|j                  dd¬«      }	|	sŒe|j                  |	«       Œw |rdj                  |«      S | j                  «       S )zhConvert content HTML to text. Preserve tables as HTML in original position. separator='' for paragraphs.rI   rB   ÚaT)ÚhrefrR   )Ústripu   é™„ä»¶r    z](ú))ÚspanÚbÚstrongÚfontÚemÚiÚuÚsÚtableÚp)Ú	separatorrS   z

)r   Úfind_allr<   Úget_textr   ÚBASE_URLÚreplace_withÚunwrapÚnameÚappendr/   Úfind_parentÚjoinrS   )
Úcontent_htmlrM   Úa_tagrR   r>   Úfull_urlÚtagÚpartsÚelÚts
             r%   rK   rK   I   s:  € áØÜ˜ }Ó5€Dð —‘˜s¨�Ó.ò 4ˆØ�y‰y˜ Ó$ˆØ�~‰~ Dˆ~Ó)Ò5¨XˆÜœ8 TÓ*ˆØ×Ñ˜Q˜t˜f B x j°Ð2Õ3ð	4ð �}‰}ÒQÓRò ˆØ�
‰
�ðð €EØ�m‰m˜W c˜NÓ+ò  ˆØ�7‰7�gÒØ�L‰Lœ˜R›Õ!Ø�W‰W˜‹^ B§N¡N°7Õ$;Ø—‘ b°�Ó5ˆAÚØ—‘˜Q•ð ñ "'ˆ6�;‰;�uÓÐ@¨L×,>Ñ,>Ó,@Ð@r'   c                 ó´  — ddddœ}t        j                  d| «      }|rn|j                  d«      j                  «       }t        j                  dd|«      j                  «       }t        j                  dd|«      j                  «       }||d<   t        j                  d| «      }|r%|j                  d«      j                  «       d	d
 |d<   t        | «      |d<   |S )z.Extract title, date, content from detail page.rI   ©ÚtitleÚpublish_dateÚcontentz<title>(.*?)</title>é   u'   [_\-â€”]\s*èŠœæ¹–å¸‚ç”Ÿæ€�çŽ¯å¢ƒå±€\s*$u*   [_\-â€”]\s*èŠœæ¹–å¸‚æ”¿åŠ¡å…¬å¼€å¹³å�°\s*$rr   zPubDate.*?content="([^"]+)"Né
   rs   rt   )ÚreÚsearchÚgrouprS   ÚsubrO   )rL   ÚresultÚmrr   s       r%   Úparse_detailr}   e   sÃ   € à¨2¸"Ñ=€FÜ
�	‰	Ð)¨4Ó0€AÙØ—‘˜“
× Ñ Ó"ˆÜ—‘ÐAÀ2ÀuÓM×SÑSÓUˆÜ—‘ÐDÀbÈ%ÓP×VÑVÓXˆØˆˆw‰Ü
�	‰	Ð0°$Ó7€AÙØ!"§¡¨£×!1Ñ!1Ó!3°C°RÐ!8ˆˆ~ÑÜ,¨TÓ2€Fˆ9ÑØ€Mr'   c                 óô  — t        j                  «       t        | dz  ¬«      z
  j                  d«      }t	        d|› d�«       t        d«      }|sy |j                  dd«      }t        t        d	   «      }||z   dz
  |z  }t	        d
|› d|› �«       g }t        dt        |dz   d«      «      D ]Ø  }t        |«      }|s nÉ|j                  dg «      }|D ]€  }	|	j                  d«      xs dd d }
|
|k  rŒ!|	j                  dd«      xs# |	j                  dd«      xs t        › d|	d   › d�}|j                  |	d   |	j                  dd«      |
|dœ«       Œ‚ t	        d|› dt        |«      › d�«       t        j                  d«       ŒÚ t	        dt        |«      › d�«       g }t!        |d«      D ]Ã  \  }}	t#        |	d   «      \  }}|r.t%        |«      }|d   r|d   |	d<   |d   r|d   |	d<   |d    |	d <   nd|	d <   |j                  |	d   |	d   |	d   |	j                  d d«      t&        › d!t(        › �|	d   d"œ«       |dz  dk(  rt	        d#|› d$t        |«      › �«       t        j                  d«       ŒÅ d}d}dd l}|j-                  t.        «      }|j1                  d%«       |j1                  d&«       |j3                  «       }|D ]W  }		 |j1                  d'|	d(   |	d)   |	d)   |	d   |	d   |	d    |	d    xs dd d* t(        f«       |j4                  dkD  r|dz  }n|dz  }ŒY |j9                  «        |j;                  «        t	        d,|› d-|› d.�«       y # t6        $ r}t	        d+|› �«       |dz  }Y d }~Œ®d }~ww xY w)/Nr)   ©Údaysú%Y-%m-%dzFull crawl (cutoff: rT   ru   Útotalr   r   úTotal: z	, pages: iõ  r*   ÚpublishDaterI   rv   Ú	urlDomainÚlinkú/openness/grassroots/Ú	contentIdú.htmlrr   ©Ú
content_idrr   ÚdateÚurlú  Page r;   ú itemsç      à?zAfter filter: r�   rs   rŒ   rt   ú-©rr   Úpage_urlrs   rt   Ú	site_nameÚ
source_urlú
  Detail: ú/úPRAGMA journal_mode=WALúPRAGMA busy_timeout=10000ú‰INSERT OR IGNORE INTO gov_raw (site_name, source_url, page_url, title, publish_date, content, summary, category) VALUES (?,?,?,?,?,?,?,?)r”   r“   éô  ú
DB error: úResult: ú new, ú skipped)r   Únowr   Ústrftimer&   r9   r<   Úintr.   ÚrangeÚminrb   rf   ÚlenÚtimeÚsleepÚ	enumerater@   r}   r#   ÚCOLUMNÚsqlite3ÚconnectÚDB_PATHÚexecuteÚcursorÚrowcountr5   ÚcommitÚclose)Úmonths_backÚcutoffr*   r‚   Ú	page_sizeÚtotal_pagesÚ	all_itemsÚpgÚitemsÚitemÚpub_dater?   ÚenrichedÚidxrL   Ú_ÚdetailÚstoredÚskippedrª   ÚconnrF   r8   s                          r%   Ú	crawl_allrÂ   u   sî  € Ü�l‰l‹nœy¨k¸BÑ.>Ô?Ñ?×IÑIÈ*ÓU€FÜÐ
˜v˜h aÐ(Ô)Ü˜1Ó€DÙØØ�H‰H�W˜aÓ €EÜ”H˜ZÑ(Ó)€IØ˜9Ñ$ qÑ(¨YÑ6€KÜˆ'�%�˜	 + Ð/Ô0à€IÜ�A”s˜;¨™?¨CÓ0Ó1ò ˆÜ˜rÓ"ˆÙÙØ—‘˜ Ó$ˆØò 
	ˆDØŸ™ Ó/Ò5°2°s¸Ð;ˆHØ˜&Ò ØØŸ™ +¨rÓ2ò  I°d·h±h¸vÀrÓ6Jò  IÔQYÐPZÐZoÐptð  vAñ  qBð  pCð  CHð  OIˆJØ×ÑØ" ;Ñ/ØŸ™ '¨2Ó.Ø Ø!ñ	õ ð
	ô 	ˆg�b�T˜œC ›J˜< vÐ.Ô/Ü�
‰
�3�ð#ô& ˆ.œ˜Y›Ð(¨Ð/Ô0à€HÜ˜y¨!Ó,ò ‰	ˆˆTÜ˜t E™{Ó+‰ˆˆaÙÜ! $Ó'ˆFØ�gŠØ & w¡��W‘Ø�nÒ%Ø% nÑ5��V‘Ø$ YÑ/ˆD�ŠOà ˆD�‰Oà�‰Ø˜'‘]Ø˜U™Ø  ™LØ—x‘x 	¨2Ó.Ü ˜6 ¤6 (Ð+Ø˜u™+ñ
ô 	ð �‰8�qŠ=Ü�*˜S˜E ¤3 y£>Ð"2Ð3Ô4Ü�
‰
�3�ð-ð0 €FØ€GÛØ�?‰?œ7Ó#€DØ‡L�LÐ*Ô+Ø‡L�LÐ,Ô-Ø�‰‹€AØò ˆð	Ø�I‰Ið,ð �kÑ" D¨Ñ$4°d¸:Ñ6FØ�g‘  ^Ñ 4°d¸9±oØ�y‘/Ò' R¨¨#Ð.´ð8ô	9ð �z‰z˜AŠ~Ø˜!‘‘à˜1‘�øðð  	‡K�K„MØ‡J�J„LÜˆ(�6�(˜&  	¨Ð2Õ3øô ò 	Ü�*˜Q˜CÐ Ô!Ø�q‰L�Gûð	ús   ËAMÍ	M7ÍM2Í2M7c                 ó‚  — t        d| › d�«       t        d«      }|sy|j                  dd«      }t        t        d   «      }t        ||z   dz
  |z  | «      }t        d|› d	|› d
�«       g }t        d|dz   «      D ]Ò  }t        |«      }|s nÃ|j                  dg «      }|D ]z  }|j                  dd«      xs# |j                  dd«      xs t        › d|d   › d�}	|j                  d«      xs ddd }
|j                  |d   |j                  dd«      |
|	dœ«       Œ| t        d|› dt        |«      › d�«       t        j                  d«       ŒÔ t        dt        |«      › �«       g }t        |d«      D ]Ã  \  }}t        |d   «      \  }}|r.t        |«      }|d   r|d   |d<   |d   r|d   |d<   |d   |d<   nd|d<   |j                  |d   |d   |d   |j                  dd«      t        › dt         › �|d   d œ«       |dz  dk(  rt        d!|› d"t        |«      › �«       t        j                  d«       ŒÅ d}d}ddl}|j%                  t&        «      }|j)                  d#«       |j)                  d$«       |j+                  «       }|D ]W  }	 |j)                  d%|d&   |d'   |d'   |d   |d   |d   |d   xs ddd( t         f«       |j,                  dkD  r|dz  }n|dz  }ŒY |j1                  «        |j3                  «        t        d*|› d+|› d,�«       y# t.        $ r}t        d)|› �«       |dz  }Y d}~Œ®d}~ww xY w)-z0Full crawl: fetch first N pages, no date cutoff.zFull first z pages (no date cutoff)ru   Nr‚   r   r   rƒ   z, crawling first z pagesr*   r…   rI   r†   r‡   rˆ   r‰   r„   rv   rr   rŠ   rŽ   r;   r�   r�   zTotal items: r�   rs   rŒ   rt   r‘   r’   r–   r—   r˜   r™   rš   r”   r“   r›   rœ   r�   rž   rŸ   )r&   r9   r<   r¢   r.   r¤   r£   rb   rf   r¥   r¦   r§   r¨   r@   r}   r#   r©   rª   r«   r¬   r­   r®   r¯   r5   r°   r±   )Úpagesr*   r‚   r´   rµ   r¶   r·   r¸   r¹   r?   rº   r»   r¼   rL   r½   r¾   r¿   rÀ   rª   rÁ   rF   r8   s                         r%   Úcrawl_first_pagesrÅ   Ë   s¿  € äˆ+�e�WÐ3Ð4Ô5Ü˜1Ó€DÙØØ�H‰H�W˜aÓ €EÜ”H˜ZÑ(Ó)€IÜ�u˜yÑ(¨1Ñ,°Ñ:¸EÓB€KÜˆ'�%�Ð)¨+¨°fÐ=Ô>à€IÜ�A�{ Q‘Ó'ò ˆÜ˜rÓ"ˆÙÙØ—‘˜ Ó$ˆØò 	ˆDØŸ™ +¨rÓ2ò  I°d·h±h¸vÀrÓ6Jò  IÔQYÐPZÐZoÐptð  vAñ  qBð  pCð  CHð  OIˆJØŸ™ Ó/Ò5°2°s¸Ð;ˆHØ×ÑØ" ;Ñ/ØŸ™ '¨2Ó.Ø Ø!ñ	õ ð	ô 	ˆg�b�T˜œC ›J˜< vÐ.Ô/Ü�
‰
�3�ðô" ˆ-œ˜I›Ð'Ð(Ô)à€HÜ˜y¨!Ó,ò ‰	ˆˆTÜ˜t E™{Ó+‰ˆˆaÙÜ! $Ó'ˆFØ�gŠØ & w¡��W‘Ø�nÒ%Ø% nÑ5��V‘Ø$ YÑ/ˆD�ŠOà ˆD�‰Oà�‰Ø˜'‘]Ø˜U™Ø  ™LØ—x‘x 	¨2Ó.Ü ˜6 ¤6 (Ð+Ø˜u™+ñ
ô 	ð �‰8�qŠ=Ü�*˜S˜E ¤3 y£>Ð"2Ð3Ô4Ü�
‰
�3�ð-ð0 €FØ€GÛØ�?‰?œ7Ó#€DØ‡L�LÐ*Ô+Ø‡L�LÐ,Ô-Ø�‰‹€AØò ˆð	Ø�I‰Ið,ð �kÑ" D¨Ñ$4°d¸:Ñ6FØ�g‘  ^Ñ 4°d¸9±oØ�y‘/Ò' R¨¨#Ð.´ð8ô	9ð �z‰z˜AŠ~Ø˜!‘‘à˜1‘�øðð  	‡K�K„MØ‡J�J„LÜˆ(�6�(˜&  	¨Ð2Õ3øô ò 	Ü�*˜Q˜CÐ Ô!Ø�q‰L�Gûð	ús   ÊALÌ	L>Ì!L9Ì9L>c                  óÄ  — t        j                  «       t        d¬«      z
  j                  d«      } t	        d| › d�«       t        d«      }|sy |j                  dg «      }|D �cg c]   }|j                  d«      xs d	d d
 | k\  sŒ|‘Œ" }}g }|D ]Ä  }|j                  dd	«      xs# |j                  dd	«      xs t        › d|d   › d�}t        |«      \  }}	|rt        |«      nd	d	d	dœ}
|j                  |
d   xs |j                  dd	«      ||j                  d«      xs d	d d
 |
d   t        › dt        › �|dœ«       t        j                  d«       ŒÆ d}d}dd l}|j!                  t"        «      }|j%                  d«       |j%                  d«       |j'                  «       }|D ]W  }	 |j%                  d|d   |d   |d   |d   |d   |d   |d   xs d	d d t        f«       |j(                  dkD  r|dz  }n|dz  }ŒY |j-                  «        |j/                  «        t	        d|› d |› d!�«       y c c}w # t*        $ r}t	        d|› �«       |dz  }Y d }~Œ³d }~ww xY w)"Né   r   r�   zIncremental (since rT   ru   r*   r„   rI   rv   r…   r†   r‡   rˆ   r‰   rq   rr   rt   r‘   r’   r�   r   r˜   r™   rš   r”   r“   rs   r›   rœ   r�   rž   rŸ   )r   r    r   r¡   r&   r9   r<   rb   r@   r}   rf   r#   r©   r¦   r§   rª   r«   r¬   r­   r®   r¯   r5   r°   r±   )r³   r*   r¸   ÚitÚfilteredr»   r¹   r?   rL   r½   r¾   r¿   rÀ   rª   rÁ   rF   r8   s                    r%   Úcrawl_incrementalrÊ     s˜  € Ü�l‰l‹nœy¨aÔ0Ñ0×:Ñ:¸:ÓF€FÜÐ
˜f˜X QÐ'Ô(Ü˜1Ó€DÙØØ�H‰H�V˜RÓ €EØ"ÖS�r r§v¡v¨mÓ'<Ò'BÀÀCÀRÐ&HÈFÓ&R’ÐS€HÐSà€HØò ˆØ—X‘X˜k¨2Ó.ò  E°$·(±(¸6À2Ó2Fò  EÌXÈJÐVkÐlpÐq|Ñl}Ðk~ð  Dð  KEˆ
Ü˜zÓ*‰ˆˆaÙ'+”˜dÔ#¸2ÈrÐ^`Ñ1aˆØ�‰Ø˜G‘_Ò=¨¯©°¸"Ó(=Ø"Ø!ŸX™X mÓ4Ò:¸¸C¸RÐ@Ø˜iÑ(Ü ˜6 ¤6 (Ð+Ø$ñ
ô 	ô 	�
‰
�3�ðð €FØ€GÛØ�?‰?œ7Ó#€DØ‡L�LÐ*Ô+Ø‡L�LÐ,Ô-Ø�‰‹€AØò ˆð	Ø�I‰Ið,ð �kÑ" D¨Ñ$4°d¸:Ñ6FØ�g‘  ^Ñ 4°d¸9±oØ�y‘/Ò' R¨¨#Ð.´ð8ô	9ð �z‰z˜AŠ~Ø˜!‘‘à˜1‘�øðð  	‡K�K„MØ‡J�J„LÜˆ(�6�(˜&  	¨Ð2Õ3ùòU TøôJ ò 	Ü�*˜Q˜CÐ Ô!Ø�q‰L�Gûð	ús%   Á$ H4ÂH4Æ+AH9È9	IÉIÉIÚ__main__ru   Úincremental)ÚfullÚalliç  )rÄ   r‚   rƒ   )é$   )é   )&Ú__doc__ÚsysÚosr4   rw   r¦   r0   r   r   Úbs4r   Úurllib.parser   Úgetenvr¬   r#   r©   rb   Ú	STHJJ_URLr2   r.   r3   r&   r9   r@   rO   rK   r}   rÂ   rÅ   rÊ   Ú__name__r¥   ÚargvÚmoder*   r<   r‚   © r'   r%   ú<module>rÜ      sG  ðñ÷
 )× (× (ß (Ý Ý  à
ˆ"�)‰)�KÐ!2Ó
3€Ø0€Ø	€Ø#€Ø'€	ØˆJÐ+Ð
,€à,ØØØØØØØØØØØñ€ð DØ1ØFñ€ò)òò òòAò8ó S4ólQ4òh14ðh ˆzÒÙ˜cŸh™h›-¨!Ò+ˆ3�8‰8�AŠ;°€DØˆ}ÒÙÕØ	�Ñ	 Ù Ö$Ø	�ŠÙ˜qÓ!ˆÙ(,�—‘˜ !Ô$°!ˆÙˆg�e�WÐÕð 
ð r'   