Ë
    ¸¬ujá   ã                   ó®   — d 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Z	e	dz   Z
dZdZd	Zd
diZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdd„Zd„ Zedk(  r e«        yy)ué  
å¹¿å¾·å¸‚äººæ°‘æ”¿åºœ - åŸºå±‚æ”¿åŠ¡å…¬å¼€â†’å¸‚ç”Ÿæ€�çŽ¯å¢ƒåˆ†å±€â†’æ‰¹å‡†ç»“æžœä¿¡æ�¯ çˆ¬è™«
URL: https://www.guangde.gov.cn/Jczwgk/showList/548/102002000/page_1.html
CMS: å¹¿å¾·è‡ªå®šä¹‰ åŸºå±‚æ”¿åŠ¡å…¬å¼€å¹³å�°
åˆ—è¡¨: <ul class="m-liststyle2"> â†’ <li><span>DATE</span><a href="..." title="TITLE"></a></li>
åˆ†é¡µ: /page_{n}.html (15æ�¡/é¡µ, 28é¡µå…±416æ�¡)
è¯¦æƒ…: /Jczwgk/show/{id}.html
è¯¦æƒ…ç»“æž„: h1.u-lgtit(æ ‡é¢˜), spanå�‘å¸ƒæ—¶é—´:, div.m-dttexts.j-fontContent#zoom(æ­£æ–‡)
é    N)Úurljoin)ÚBeautifulSoupzhttps://www.guangde.gov.cnz,/Jczwgk/showList/548/102002000/page_{n}.htmlu(   å¹¿å¾·å¸‚äººæ°‘æ”¿åºœ-çŽ¯è¯„æ‰¹å‡†ç»“æžœu   å®‰å¾½z/mnt/data/search.dbz
User-AgentzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36c                 óV   — | syt        j                  dd| «      } | j                  «       S )NÚ z(&middot;|&nbsp;|\s)+ú )ÚreÚsubÚstrip)Útexts    ú)/root/gov_crawler/crawl_guangde_hjpzjg.pyÚ
clean_textr       s'   € ÙØÜ�6‰6Ð*¨C°Ó6€DØ�:‰:‹<Ðó    c                 óÚ  ‡— | syt        | d«      }d}dD ]  }|j                  |«      }|sŒ|} n |sy|j                  d«      D ]  }|j                  «        Œ g }g }t	        |j
                  «      D ]²  }	|	j                  €Œ|	j                  dk(  r|j                  t        |	«      «       Œ:|	j                  d«      r3|	j                  dd¬«      D ]  }
|j                  t        |
«      «       Œ Œ~|	j                  d	v sŒ�|	j                  d¬
«      }
|
sŒ¢|j                  |
«       Œ´ dj                  |«      }g }t        |«      dk  rà|j                  d«      D ]Q  }t        ||d   «      }|j                  dd«      j!                  «       }|rd|› d�nd}|j                  |› d|› �«       ŒS |j                  d«      D ]g  }|d   Št        |‰«      }|j                  d¬
«      xs ‰j#                  d«      d   }t%        ˆfd„dD «       «      sŒQ|j                  d|› d|› �«       Œi |}|r|ddj                  |«      z   z  }|r|ddj                  |«      z   z  }|j!                  «       S )u.   æ��å�–æ­£æ–‡ï¼Œè¡¨æ ¼ä¿�ç•™HTMLï¼Œé™„ä»¶åµŒå…¥r   úhtml.parserN)zdiv.m-dttexts.j-fontContentzdiv.j-fontContentzdiv#zoomzdiv.g-detailboxzdiv.m-dttextszscript, style, linkÚtableT)Ú	recursive)ÚpÚdivÚsectionÚh1Úh2Úh3Úh4©r
   z

iô  zimg[src]ÚsrcÚaltu	   [å›¾ç‰‡: ú]u   [å›¾ç‰‡]r   úa[href]Úhrefú/éÿÿÿÿc              3   ó\   •K  — | ]#  }‰j                  «       j                  |«      –— Œ% y ­w)N)ÚlowerÚendswith)Ú.0Úextr   s     €r   ú	<genexpr>z%clean_content_html.<locals>.<genexpr>a   s"   øè ø€ Òd°#�4—:‘:“<×(Ñ(¨×-Ñdùs   ƒ),)z.pdfz.docz.docxz.xlsz.xlsxu	   [é™„ä»¶: ú] ú
)r   Ú
select_oneÚselectÚ	decomposeÚlistÚchildrenÚnameÚappendÚstrÚfindÚfind_allÚget_textÚjoinÚlenr   Úgetr
   ÚsplitÚany)Úhtml_contentÚ
detail_urlÚsoupÚcontentÚselÚcÚtagÚtables_htmlÚ
paragraphsÚchildÚtr   ÚlinksÚimgr   r   ÚlabelÚaÚfull_urlÚfnameÚresultr   s                        @r   Úclean_content_htmlrL   '   sƒ  ø€ áØÜ˜ }Ó5€Dð €Gð4ò ˆà�O‰O˜CÓ ˆÚØˆGÙðñ Øð �~‰~Ð3Ó4ò ˆØ�‰�ðð €KØ€Jô �g×&Ñ&Ó'ò %ˆØ�:‰:ÐØØ�:‰:˜Ò Ø×Ñœs 5›zÔ*ØØ�:‰:�gÔà—^‘^ G°t�^Ó<ò +�Ø×"Ñ"¤3 q£6Õ*ð+àð �:‰:ÐHÒHØ—‘ T�Ó*ˆAÚØ×!Ñ! !Õ$ð!%ð$ �;‰;�zÓ"€Dð €EÜ
ˆ4ƒy�3‚Ø—>‘> *Ó-ò 	+ˆCÜ˜* c¨%¡jÓ1ˆCØ—'‘'˜% Ó$×*Ñ*Ó,ˆCÙ*-�i ˜u AÑ&°:ˆEØ�L‰L˜E˜7 ! C 5Ð)Õ*ð		+ð
 —‘ 	Ó*ò 	>ˆAØ�V‘9ˆDÜ˜z¨4Ó0ˆHØ—J‘J T�JÓ*ÒA¨d¯j©j¸«o¸bÑ.AˆEÜÓdÐ9cÔdÕdØ—‘˜y¨¨¨r°(°Ð<Õ=ð	>ð €FÙØ�&˜6Ÿ;™; {Ó3Ñ3Ñ3ˆÙØ�&˜4Ÿ9™9 UÓ+Ñ+Ñ+ˆà�<‰<‹>Ðr   c           	      ó2  — 	 t        j                  dddddd| gdd¬	«      }|j                  d
k(  r)|j                  r|j                  j	                  dd¬«      S t        d|j                  › d| › �«       y# t        $ r}t        d|› �«       Y d}~yd}~ww xY w)z$Fetch page with curl via subprocess.Úcurlz-sSz-Lz
--max-timeÚ30z-kTé<   )Úcapture_outputÚtimeoutr   úutf-8Úreplace)Úerrorsz  [WARN] curl exit=z for Nz
  [ERROR] )Ú
subprocessÚrunÚ
returncodeÚstdoutÚdecodeÚprintÚ	Exception)ÚurlrK   Úes      r   Ú
fetch_pager_   m   s£   € ðÜ—‘Ø�E˜4 ¨t°TØð!
ð ¨ô,ˆð ×Ñ Ò! f§m¢mØ—=‘=×'Ñ'¨¸	Ð'ÓBÐBÜÐ# F×$5Ñ$5Ð#6°e¸C¸5ÐAÔBØøÜò Ü�
˜1˜#ÐÔÜûðús   ‚AA5 ÁA5 Á5	BÁ>BÂBc                 ó´  — g }t        | d«      }|j                  d«      D ]µ  }|j                  d«      }|j                  d«      }|sŒ(|j                  dd«      }|j                  dd«      xs |j	                  d¬	«      }|rt        |«      d
k  rŒq|r|j	                  d¬	«      nd}	t        |«      }t        t        |«      }
|j                  ||
|	f«       Œ· |S )z3Parse list page, return list of (title, url, date).r   zdiv.m-liststyle2 ul lir   Úspanr   r   ÚtitleTr   é   )
r   r+   r*   r7   r4   r6   r   r   ÚBASE_URLr0   )ÚhtmlÚpage_urlÚitemsr<   ÚlirH   ra   r   rb   ÚdaterI   s              r   Ú
parse_listrj   }   sÒ   € à€EÜ˜˜}Ó-€Dà�k‰kÐ2Ó3ò .ˆØ�M‰M˜)Ó$ˆØ�}‰}˜VÓ$ˆÙØà�u‰u�V˜RÓ ˆØ—‘�g˜rÓ"Ò< a§j¡j°t jÓ&<ˆÙœ˜E›
 QšØá,0ˆt�}‰} 4ˆ}Ô(°bˆä˜5Ó!ˆÜœ8 TÓ*ˆà�‰�e˜X tÐ,Õ-ð!.ð$ €Lr   c                 óB   — t        j                  dd|dz   › d�| «      }|S )z'Get next page URL based on page number.zpage_\d+\.htmlÚpage_é   z.html)r   r	   )Úcurrent_urlÚpage_numÚnext_urls      r   Úget_next_page_urlrq   —   s)   € ô �v‰vÐ'¨5°¸A±°¸eÐ)DÀkÓR€HØ€Or   c           	      ó@  — 	 |j                  dd«      }|j                  dd«      }|dd j                  dd«      }d| › d|› d|› d|› d�	}t        j                  d	t        g|j	                  d
«      dd¬«       y# t
        $ r}t        d| › d|› �«       Y d}~yd}~ww xY w)z8Sync FTS via subprocess stdin (preserves Chinese chars).ú'z''NéÈ   zKINSERT OR REPLACE INTO gov_search(rowid, title, site_name, summary) VALUES(z, 'z', 'z');
Úsqlite3rS   Té
   )ÚinputrQ   rR   z  [FTS ERROR] row_id=ú: )rT   rV   rW   ÚDB_PATHÚencoder\   r[   )	Úrow_idrb   Ú	site_nameÚsummaryÚ	title_escÚsite_escÚsumm_escÚsqlr^   s	            r   Úsync_ftsr‚   ž   sË   € ð5Ø—M‘M # tÓ,ˆ	Ø×$Ñ$ S¨$Ó/ˆØ˜4˜C�=×(Ñ(¨¨dÓ3ˆØ[Ð\bÐ[cÐcfÐgpÐfqÐquÐv~Ðuð  @Dð  EMð  DNð  NSð  TˆÜ�‰˜	¤7Ð+°3·:±:¸gÓ3FÐW[ÐegÖhøÜò 5ÜÐ% f X¨R°¨sÐ3×4Ñ4ûð5ús   ‚A6A9 Á9	BÂBÂBc                 óÀ  — g }t        «       }t        dt        › d| › �«       t        d| dz   «      D ]¹  }t        j                  |¬«      }t        d|› d|› �«       t        |«      }|st        d|› �«        nut        ||«      }|D �cg c]  }|d   |vsŒ|‘Œ }}|D ]  }|j                  |d   «       Œ t        dt        |«      › d	t        |«      › d
�«       |j                  |«       Œ» t        dt        |«      › d| › d�«       t        d«      j                  t        «      }	d}
d}d}t        |d«      D �]¹  \  }\  }}}t        d|› dt        |«      › d|d d › d�d¬«       |	j                  d|f«      j!                  «       }|rt        d«       Œ]t        |«      }|st        d«       Œvt#        |d«      }|j%                  d«      }|r|j'                  d¬«      n|}t)        |«      }|}|j%                  d«      }|r7t+        j,                  d|j'                  «       «      }|r|j/                  d«      }t1        ||«      }|rt        |«      d k  r|dz  }|rt        |«      nd}||z  }	 |	j                  d!||xs d"||t        |d d# t2        d$f«       |	j5                  «        |	j                  d%«      j!                  «       d   }t7        ||t        |d d# «       |
dz  }
t        d&|› d'�«       �Œ¼ |	j=                  «        t        d)t        |«      › d*|
› d+|› d,|› �«       y c c}w # t8        $ r)}|	j;                  «        t        d(|› �«       Y d }~�Œ d }~ww xY w)-Nz[START] z	 | pages=rm   )Únz
[LIST] Page rx   z  [FAIL] Cannot fetch page z  Found z items, z newz	
[TOTAL] z items from z pagesru   r   z  [r    r(   é(   z...r   )Úendz+SELECT id FROM gov_raw WHERE source_url = ?zSKIP (exists)zFAIL (fetch)r   z
h1.u-lgtitTr   u   span:contains("å�‘å¸ƒæ—¶é—´")z(\d{4}-\d{1,2}-\d{1,2})rv   z�INSERT INTO gov_raw (title, content, publish_date, source_url, site_name, summary, group_name, industry) VALUES (?,?,?,?,?,?,?,?)r   rt   u   çŽ¯è¯„å…¬ç¤ºzSELECT last_insert_rowid()zOK (z chars)z
DB ERROR: u   
[DONE] æ€»è®¡ u    æ�¡, æ–°å¢ž u    æ�¡, ç©ºæ­£æ–‡ u    æ�¡, æ€»å­—æ•° )Úsetr[   Ú	SITE_NAMEÚrangeÚLIST_URL_TMPLÚformatr_   rj   Úaddr6   ÚextendÚ
__import__Úconnectry   Ú	enumerateÚexecuteÚfetchoner   r*   r4   r   r   ÚsearchÚgrouprL   ÚGROUPÚcommitr‚   r\   ÚrollbackÚclose)ÚpagesÚ	all_itemsÚ	seen_urlsÚpgr]   re   rg   ÚitÚ	new_itemsÚconnÚinsertedÚempty_contentÚtotal_charsÚirb   ri   Úexistingr<   r   Úcontent_titleÚcontent_dateÚdate_elÚmÚbodyÚcontent_lenÚridr^   s                              r   Úcrawlr¬   ª   sŒ  € Ø€IÜ“€Iä	ˆH”Y�K˜y¨¨Ð
0Ô1ä�A�u˜q‘yÓ!ò $ˆÜ×"Ñ" RÐ"Ó(ˆÜ�˜r˜d " S EÐ*Ô+Ü˜#‹ˆÙÜÐ/°¨tÐ4Ô5Ùä˜4 Ó%ˆØ"'ÖB˜B¨2¨a©5¸	Ò+A’RÐBˆ	ÐBØò 	!ˆBØ�M‰M˜"˜Q™%Õ ð	!ô 	�œ˜U›˜ H¬S°«^Ð,<¸DÐAÔBØ×Ñ˜Õ#ð$ô  
ˆJ”s˜9“~Ð& l°5°'¸Ð
@ÔAä�iÓ ×(Ñ(¬Ó1€DØ€HØ€MØ€Kä!*¨9°aÓ!8ó 1$ÑˆÑˆE�3˜Ü��A�3�aœ˜I›Ð' r¨%°°¨*¨°SÐ9¸sÕCà—<‘<Ð MÐPSÈvÓV×_Ñ_ÓaˆÙÜ�MÔ#Øä˜#‹ˆÙÜ�LÔ"Øä˜T =Ó1ˆð �_‰_˜\Ó*ˆÙ35˜Ÿ™¨$˜Ô/¸5ˆÜ" =Ó1ˆð ˆØ—/‘/Ð"AÓBˆÙÜ—	‘	Ð4°g×6FÑ6FÓ6HÓIˆAÙØ Ÿw™w q›z�ô " $¨Ó,ˆá”s˜4“y 2’~Ø˜QÑˆMá#'”c˜$”i¨QˆØ�{Ñ"ˆð	$Ø�L‰Lð TØ ¢
¨¨L¸#¼yÈ-ÐX\ÐY\ÐJ]Ô_dÐftÐuôð �K‰KŒMØ—,‘,Ð;Ó<×EÑEÓGÈÑJˆCÜ�S˜-¬°MÀ$À3Ð4GÔHØ˜‰MˆHÜ�D˜˜ WÐ-Ö.ð]1$ðf 	‡J�J„LÜ	ÐœS ›^Ð,¨M¸(¸ÐCSÐTaÐSbÐbrÐs~Ðrð  Aõ  BùòE Cøôz ò 	$Ø�M‰MŒOÜ�J˜q˜cÐ"×#Ò#ûð	$ús%   ÂL&ÂL&É.BL+Ì+	MÌ4MÍMc                  ó¦   — dd l } | j                  «       }|j                  dt        d¬«       |j	                  «       }t        |j                  «       y )Nr   z--pagesé   )ÚtypeÚdefault)ÚargparseÚArgumentParserÚadd_argumentÚintÚ
parse_argsr¬   r™   )r±   ÚparserÚargss      r   Úmainr¸   þ   sB   € ÛØ×$Ñ$Ó&€FØ
×Ñ˜	¬°QÐÔ7Ø×ÑÓ€DÜ	ˆ$�*‰*Õr   Ú__main__)r®   )Ú__doc__r   ÚsysÚjsonrV   Úurllib.parser   Úbs4r   rd   rŠ   rˆ   r•   ry   ÚHEADERSr   rL   r_   rj   rq   r‚   r¬   r¸   Ú__name__© r   r   ú<module>rÂ      s’   ðñó 
Û 
Û Û Ý  å ð (€ØÐIÑI€Ø6€	Ø€Ø
€ð ð  Dð€ò
òCòLò ò4ò	5óQBòhð ˆzÒÙ…Fð r   