Ë
    ÉÚµ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ZddlmZ ddl	m
Z
 ddlmZ dZdZdZd	Zd
ZdZdZddddœZd„ Zd„ Zd„ Zdd„Zd„ Zd„ Zd„ Zedk(  r e«        yy)u•  
Crawler for æ³‰å·žå¸‚æ³‰æ¸¯åŒºäººæ°‘æ”¿åºœ - é¡¹ç›®çŽ¯è¯„ (qg.gov.cn)
CMS: TRS (å¡«é€‰ç³»ç»Ÿ)
List: div.gl_list > ul > li > span(date) + a[href]
Pagination: index_0.htm ~ index_29.htm (15/page, 30 pages ~450 items)
Detail: div.xl_tit (title), div.xl_tit1_l > span:nth(1) (date), div.TRS_Editor (content)
         div.szf_list2 ul li a (attachments)

Usage:
    python3 /root/gov_crawler/crawl_qg_xmhp.py
é    N)Údatetime)ÚBeautifulSoup)Úurljoinz/root/search.dbu   æ³‰æ¸¯åŒº-é¡¹ç›®çŽ¯è¯„u   é¡¹ç›®çŽ¯è¯„u   ç¦�å»ºzhttp://www.qg.gov.cnz/zwgk/zdxxgk/hjbh/xmhpé   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,en;q=0.8)z
User-AgentÚAcceptzAccept-Languagec                 óT   — | dk(  rt         › t        › d�S t         › t        › d| dz
  › d�S )zpage_num is 1-indexedé   ú/z/index_z.htm)ÚBASE_URLÚLIST_DIR)Úpage_nums    ú"/root/gov_crawler/crawl_qg_xmhp.pyÚget_list_urlr   %   s5   € à�1‚}Ü�œH˜: QÐ'Ð'ÜˆZœ�z ¨°!©¨°DÐ9Ð9ó    c                 ó:  — t        | «      }	 t        j                  |t        d¬«      }d|_        t        |j                  d«      }|j                  dd	¬
«      }|s t        d| › �t        j                  ¬«       g S g }|j                  d«      D ]Ñ  }|j                  d«      D ]»  }|j                  d«      }	|j                  d«      }
|	r|	j                  d«      sŒ9|	d   j                  «       }t        ||«      }|	j                  dd«      j                  «       xs |	j                  d¬«      }|
r|
j                  d¬«      nd}|sŒ¥|sŒ¨|j!                  |||f«       Œ½ ŒÓ |S # t        $ r-}t        d|› d|› �t        j                  ¬«       g cY d }~S d }~ww xY w)Né   ©ÚheadersÚtimeoutúutf-8úhtml.parserz  Error fetching ú: ©ÚfileÚdivÚgl_list©Úclass_z  No gl_list found on page ÚulÚliÚaÚspanÚhrefÚtitleÚ T©Ústrip)r   ÚrequestsÚgetÚHEADERSÚencodingr   ÚtextÚ	ExceptionÚprintÚsysÚstderrÚfindÚfind_allr'   r   Úget_textÚappend)r   ÚurlÚrÚsoupÚer   Úitemsr   r    r!   r"   r#   Úpage_urlr$   Údate_strs                  r   Úextract_list_pager<   ,   sv  € Ü
�xÓ
 €CðÜ�L‰L˜¤g°rÔ:ˆØˆŒ
Ü˜QŸV™V ]Ó3ˆð
 �)‰)�E )ˆ)Ó
,€CÙÜÐ+¨H¨:Ð6¼S¿Z¹ZÕHØˆ	à€EØ�l‰l˜4Ó ò :ˆØ—+‘+˜dÓ#ò 	:ˆBØ—‘˜“ˆAØ—7‘7˜6“?ˆDÙ˜AŸE™E &œMØà�V‘9—?‘?Ó$ˆDÜ˜s DÓ)ˆHØ—E‘E˜' 2Ó&×,Ñ,Ó.ÒH°!·*±*À4°*Ó2HˆEÙ48�t—}‘}¨4�}Ô0¸bˆHâšØ—‘˜e X¨xÐ8Õ9ñ	:ð:ð €Løô3 ò ÜÐ! #  b¨¨Ð,´3·:±:Õ>Ø�	ûðús   �9E$ Å$	FÅ-"FÆFÆFc                 óÌ	  — 	 t        j                  | t        d¬«      }d|_        t        |j                  d«      }d}|j                  d	d
¬«      }|r|j                  d¬«      }|sE|j                  d«      }|r2|j                  d¬«      j                  d«      d   j                  «       }d}|j                  dddi¬«      }|r'|j                  d«      r|d   j                  «       d d }|sj|j                  d	d¬«      }	|	rU|	j                  d«      }
|
D ]?  }|j                  d¬«      }t        j                   d|«      }|sŒ.|j#                  d«      } n |j                  d	d¬«      }|s|j                  d	d¬«      }d}|�r†|j                  ddg«      D ]  }|j%                  «        Œ g }|j&                  D �];  }|j(                  sŒ|j(                  dk(  r|j+                  t-        |«      «       Œ;|j(                  d k(  rº|j                  d	dgd!¬"«      r}|j                  d dgd¬"«      D ]d  }|j(                  dk(  r|j+                  t-        |«      «       Œ-|j/                  d«      rŒ?|j                  d¬«      }|sŒT|j+                  |«       Œf ŒÜ|j                  d¬«      }|sŒñ|j+                  |«       �Œ|j(                  d	k(  s�Œ|j                  d¬«      }|s�Œ+|j+                  |«       �Œ> d#j1                  |«      }t        j2                  d$d#|«      j                  «       }g }t5        «       }|j                  d	d%¬«      }|rœ|j                  d&d¬'«      D ]†  }|d(   }t7        | |«      }|j                  d¬«      xs& |j                  d)«      d*   j                  d+«      d   }||vsŒS|j9                  |«       |j+                  ||d,œ«       |sŒ{|d-|› d.|› d/�z  }Œˆ |r|j                  d&d¬'«      ng D ]�  }|d(   }t        j                   d0|t        j:                  «      sŒ.t7        | |«      }|j                  d¬«      xs& |j                  d)«      d*   j                  d+«      d   }||vsŒy|j9                  |«       |j+                  ||d,œ«       ŒŸ ||||fS # t        $ r1}t        d| › d|› �t        j                  ¬«       d d d g fcY d }~S d }~ww xY w)1Nr   r   r   z  fetch_detail error r   r   r   r%   r   Úxl_titr   Tr&   r$   ú-r   ÚmetaÚnameÚPubDate)ÚattrsÚcontenté
   Ú	xl_tit1_lr"   z(\d{4}-\d{2}-\d{2})r	   Ú
TRS_EditorÚxl_con1ÚscriptÚstyleÚtableÚpF)Ú	recursivez

z\n{3,}Ú	szf_list2r!   )r#   r#   r
   éÿÿÿÿú?)rA   r5   u   

é™„ä»¶ï¼š<p><a href="z">z</a></p>z&\.(pdf|doc|docx|xls|xlsx|rar|zip|txt)$)r(   r)   r*   r+   r-   r.   r/   r0   r   r,   r1   r3   Úsplitr'   r2   ÚreÚsearchÚgroupÚ	decomposeÚchildrenrA   r4   ÚstrÚfind_parentÚjoinÚsubÚsetr   ÚaddÚI)r5   r6   r8   r7   r$   Útit_divÚtr;   r@   Útit1ÚspansÚspÚtxtÚmÚeditorrD   ÚsÚpartsÚchildÚinnerÚattachmentsÚseenÚatt_divÚa_tagr#   Úfull_urlrA   s                              r   Úfetch_detailro   P   s©  € ð$Ü�L‰L˜¤g°rÔ:ˆØˆŒ
ô
 ˜Ÿ™ Ó/€Dð €EØ�i‰i˜ hˆiÓ/€GÙØ× Ñ  tÐ Ó,ˆÙØ�I‰I�gÓˆÙØ—J‘J T�JÓ*×0Ñ0°Ó5°aÑ8×>Ñ>Ó@ˆEð €Hà�9‰9�V F¨IÐ#6ˆ9Ó7€DÙ�—‘˜Ô#Ø˜	‘?×(Ñ(Ó*¨3¨BÐ/ˆÙà�y‰y˜ {ˆyÓ3ˆÙØ—M‘M &Ó)ˆEØò �Ø—k‘k¨�kÓ-�Ü—I‘IÐ4°cÓ:�ÚØ Ÿw™w q›z�HÙðð �Y‰Y�u \ˆYÓ2€FÙà—‘˜5¨�Ó3ˆØ€GÚØ—‘ (¨GÐ!4Ó5ò 	ˆAØ�K‰K�Mð	àˆà—_‘_ó 	&ˆEØ—:’:ØØ�z‰z˜WÒ$Ø—‘œS ›ZÕ(Ø—‘˜sÒ"à—:‘:˜u gÐ.¸%�:Ô@Ø!&§¡°°g°È$ Ó!Oò 0˜Ø Ÿ:™:¨Ò0Ø!ŸL™L¬¨U«Õ4Ø!&×!2Ñ!2°7Õ!;Ø %§¡°T Ó :˜AÚ Ø %§¡¨Q¥ñ0ð Ÿ™¨T˜Ó2�AÚØŸ™ QžØ—‘˜uÔ$Ø—n‘n¨4�nÓ0�ÛØ—L‘L Ö%ð-	&ð. —+‘+˜eÓ$ˆô �f‰f�Y ¨Ó0×6Ñ6Ó8€Gð €KÜ‹5€Dà�i‰i˜ kˆiÓ2€GÙØ×%Ñ% c°Ð%Ó5ò 	VˆEØ˜‘=ˆDÜ˜s DÓ)ˆHØ—>‘>¨�>Ó-ÒR°·±¸C³ÀÑ1D×1JÑ1JÈ3Ó1OÐPQÑ1RˆDØ˜tÒ#Ø—‘˜Ô"Ø×"Ñ"¨D¸Ñ#BÔCÚØÐ!:¸8¸*ÀBÀtÀfÈHÐUÑU‘Gð	Vñ 5;�—‘ ¨4�Ô0Àò DˆØ�V‰}ˆÜ�9‰9Ð>ÀÄbÇdÁdÕKÜ˜s DÓ)ˆHØ—>‘>¨�>Ó-ÒR°·±¸C³ÀÑ1D×1JÑ1JÈ3Ó1OÐPQÑ1RˆDØ˜tÒ#Ø—‘˜Ô"Ø×"Ñ"¨D¸Ñ#BÕCðDð �(˜G [Ð0Ð0øôG ò $ÜÐ% c U¨"¨Q¨CÐ0´s·z±zÕBØ�T˜4 Ð#Õ#ûð$ús   ‚#R) Ò)	S#Ò2&SÓS#ÓS#c                 ól  — t        d|dz   «      D ]  }	  | «       c S  y
# t        j                  $ r�}dt        |«      v rC||k  r>t	        d|› d|› d|› d|› d�	t
        j                  ¬«       t        j                  |«       n't	        d|› d	|› �t
        j                  ¬«       Y d }~ y
Y d }~Œžd }~ww xY w)Nr	   Úlockedz  z: locked (attempt r
   z), retry in zs...r   z	 failed: F)	ÚrangeÚsqlite3ÚOperationalErrorrW   r.   r/   r0   ÚtimeÚsleep)ÚfnÚdescÚmax_attemptsÚdelayÚattemptr8   s         r   Ú
with_retryr|   ¼   s¸   € Ü˜˜L¨1Ñ,Ó-ò 	ˆð	Ù“4ŠKð	ð øô ×'Ñ'ò 	Øœ3˜q›6Ñ! g°Ò&<Ü˜˜4˜&Ð 2°7°)¸1¸\¸NÈ,ÐW\ÐV]Ð]aÐbÔil×isÑisÕtÜ—
‘
˜5Õ!ä˜˜4˜& 	¨!¨Ð-´C·J±JÕ?Ýô "ûð	ús   ”ŸB3²A1B.Â.B3c                  ó€   — t        j                  t        d¬«      } | j                  d«       | j                  d«       | S )Nr   )r   zPRAGMA journal_mode=WALzPRAGMA busy_timeout=30000)rs   ÚconnectÚDB_PATHÚexecute©Úconns    r   Úinit_dbrƒ   Ê   s1   € Ü�?‰?œ7¨BÔ/€DØ‡L�LÐ*Ô+Ø‡L�LÐ,Ô-Ø€Kr   c                 óˆ  — |r|d d n|}t        j                  dd|«      j                  «       }|rt        j                  |d¬«      nd}	 | j                  dt        |||j                  «       |||t        |t        f
«      }|j                  dkD  S # t        $ r(}	t        d	|	› �t        j                  ¬
«       Y d }	~	yd }	~	ww xY w)NéÈ   z\s+ú F)Úensure_asciiz[]zÍINSERT OR IGNORE INTO gov_raw
               (site_name, source_url, page_url, title, publish_date, summary, content, category, attachments, group_name)
               VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)r   z  DB error: r   )rR   rZ   r'   ÚjsonÚdumpsr€   Ú	SITE_NAMEÚCATEGORYÚGROUPÚrowcountr-   r.   r/   r0   )
r‚   r$   r:   Úpublish_daterD   rj   ÚsummaryÚatt_jsonÚcurr8   s
             r   Úsave_articler’   Ñ   s´   € Ù&ˆg�d�s‰m¨E€GÜ�f‰f�V˜S 'Ó*×0Ñ0Ó2€GÙ>IŒt�z‰z˜+°EÕ:Èt€HðØ�l‰lð8ô ˜ (¨E¯K©K«M¸<Ø�gœx¨´5ð:ó	
ˆð �|‰|˜aÑÐøÜò Ü�˜Q˜CÐ ¤s§z¡zÕ2Üûðús   ÁAB Â	CÂB<Â<Cc                  óÜ  ‡— t         } t        t        j                  «      dkD  r	 t	        t        j                  d   «      } t        dt        › d| › �t        j                  ¬«       t        «       Šd}d}t        j                  «       }ˆfd„}t        dt        j                  ¬«       t        |dt        › �¬	«       t        d
t        › �t        j                  ¬«       t        d| dz   «      D �]…  }t        |«      }|s"t        d|› d�t        j                  ¬«        �nV|t        |«      z  }d}|D ]�  \  }}	}
|
r|
dk  rŒ‰j                  d|	f«      }|j                  «       rŒ3t        |	«      \  }}}}|xs |}|xs |
}|xs	 d|› d|	› d�}|xs g }t!        ‰||	|||«      r
|dz  }|dz  }t        j"                  d«       Œ’ t	        t        j                  «       |z
  «      }| |z
  }|dkD  r-|dkD  r(t	        |t%        d|t%        d|«      z  «      z  dz  «      nd}t        d|› d| › d|› d|› d|› d|dz  › d|dz  d›d|› d�t        j                  ¬«       |dz  dk(  s�Œv‰j'                  «        �Œˆ ‰j'                  «        t	        t        j                  «       |z
  «      }‰j)                  «        t        d|› d|› d|dz  › d |dz  d›d!�	t        j                  ¬«       y #  Y �ŒªxY w)"Nr	   z	Scraping z, max pages: r   r   c                  ó&   •— ‰ j                  «        y )N)Úcommitr�   s   €r   Údo_cleanzmain.<locals>.do_cleanó   s   ø€ à�‰�r   z  Cleaning old data...zClean )rx   z  Cleaned old data for z  Page z: 0 items (end)z
2005-01-01z)SELECT id FROM gov_raw WHERE page_url = ?ú[z](ú)g333333Ó?é<   r
   z: +z new, z total, ú:Ú02dz elapsed, ETA Úminé   z
Done! Found: z, New: z, Time: rd   rf   )ÚTOTAL_PAGESÚlenr/   ÚargvÚintr.   rŠ   r0   rƒ   ru   r|   rr   r<   r€   Úfetchonero   r’   rv   Úmaxr•   Úclose)Ú	max_pagesÚ	total_newÚtotal_foundÚ
start_timer–   ÚpnÚarticlesÚ	batch_newr$   r:   Údater‘   Ú	det_titleÚdet_dateÚdet_contentÚdet_attsÚfinal_titleÚ
final_dateÚfinal_contentÚ
final_attsÚelapsedÚ
pages_leftÚetar‚   s                          @r   Úmainr¸   å   sí  ø€ Ü€IÜ
Œ3�8‰8ƒ}�qÒð	ÜœCŸH™H Q™KÓ(ˆIô 
ˆI”i�[ ¨i¨[Ð
9ÄÇ
Á
ÕKÜ‹9€DØ€IØ€KÜ—‘“€Jôô 
Ð
"¬¯©Õ4Üˆx ¤y kÐ2Õ3Ü	Ð#¤I ;Ð
/´c·j±jÕAä�A�y 1‘}Ó%ó 'ˆÜ$ RÓ(ˆÙÜ�G˜B˜4˜Ð/´c·j±jÕAÚà”s˜8“}Ñ$ˆØˆ	à%-ò 	Ñ!ˆE�8˜TÙ˜˜|Ò+Øà—,‘,ÐJÈXÈKÓXˆCØ�|‰|Œ~Øä9EÀhÓ9OÑ6ˆI�x ¨hØ#Ò, uˆKØ!Ò) TˆJØ'ÒI¨Q¨{¨m¸2¸h¸ZÀqÐ+IˆMØ!š RˆJä˜D +¨x¸À]ÐT^Ô_Ø˜Q‘�	Ø˜Q‘�	ä�J‰J�s�Oð%	ô( ”d—i‘i“k JÑ.Ó/ˆØ ‘^ˆ
ØELÈqÂ[ÐUWÐZ[ÒU[Œc�*œs 1 b¬3¨q°'«?Ñ&:Ó;Ñ;¸bÑ@ÔAÐabˆä�˜�t˜1˜Y˜K s¨9¨+°VØ�˜1˜[˜M¨Ø˜"‘�˜Q˜w r™z¨#Ð.ð /Ø�E˜ðô %(§J¡Jõ	0ð
 �‰6�QŒ;Ø�K‰KŽMðO'ðR 	‡K�K„MÜ”$—)‘)“+ 
Ñ*Ó+€GØ‡J�J„LÜ	ˆO˜K˜=¨°	¨{¸(À7ÈBÁ;À-ÈqÐQXÐY[ÑQ[Ð\_ÐP`Ð`aÐ
bÔil×isÑisÖtøðy	Úús   ¥K& Ë&K+Ú__main__)zDB oprE   r�   )Ú__doc__r(   rR   rˆ   rs   ru   Úosr/   r   Úbs4r   Úurllib.parser   r   rŠ   r‹   rŒ   r   r   rž   r*   r   r<   ro   r|   rƒ   r’   r¸   Ú__name__© r   r   ú<module>rÀ      s”   ðñ
÷ 2× 1× 1Ó 1Ý Ý Ý  à
€Ø$€	Ø€Ø€Ø!€Ø#€Ø€ð DØOØ0ñ€ò:òòHg1óXòòò(AuðH ˆzÒÙ…Fð r   