Ë
    €Ûµ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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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 æ²³å�—æ¿®é˜³å·¥ä¸šå›­åŒº - å…¬å‘Šå…¬ç¤º (pygyyq.gov.cn)
CMS: è‡ªå®šä¹‰ASP CMS, charset=gb2312
List: ul.news-list > li > a[href][title] + span(date), 15/page
Pagination: ?class=23&page=N, 3 pages ~44 items
Detail: h1.content-title, div.show>p.text or a.pdf or img content
Attachments: a.ke-insertfile or a[href*=./upload/]

Usage:
    python3 /root/gov_crawler/crawl_pygyyq_gsgg.py
é    N)Údatetime)ÚBeautifulSoup)Úurljoinz/root/search.dbu%   æ²³å�—æ¿®é˜³å·¥ä¸šå›­åŒº-å…¬å‘Šå…¬ç¤ºu   é€šçŸ¥å…¬å‘Šu   æ²³å�—zhttp://www.pygyyq.gov.cnz0http://www.pygyyq.gov.cn/zwgk/zfxx_gknr_news.aspé   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 ]5  }	 t        j                  | t        d¬«      }d|_        |j
                  |fc S  y
# t        $ rO}||dz
  k  rt        j                  d«       n't        d| › d|› �t        j                  ¬«       Y d	}~ y
Y d	}~ŒŒd	}~ww xY w)z$Fetch URL with GBK encoding handlingé   )ÚheadersÚtimeoutÚgbké   é   z  [WARN] Failed to fetch z: ©ÚfileN)NN)ÚrangeÚrequestsÚgetÚHEADERSÚencodingÚtextÚ	ExceptionÚtimeÚsleepÚprintÚsysÚstderr)ÚurlÚretriesÚiÚrÚes        ú&/root/gov_crawler/crawl_pygyyq_gsgg.pyÚ	fetch_gbkr#   #   s’   € ä�7‹^ò 
"ˆð		"Ü—‘˜S¬'¸2Ô>ˆAØˆAŒJØ—6‘6˜1�9Òð	
"ð øô ò 	"Ø�7˜Q‘;ŠÜ—
‘
˜1•äÐ1°#°°b¸¸Ð<Ä3Ç:Á:ÕNÝ!ô ûð	"ús   �0AÁ	BÁ?BÂBc                 óD  — ddi}| dkD  r| |d<   t         dz   t        j                  j                  |«      z   }t	        |«      \  }}|sg S t        |d«      }g }|j                  dd¬	«      }|sg S |j                  d
d¬«      D ]›  }|j                  dd¬«      }	|	sŒ|	d   }
t        ||
«      }|	j                  dd«      j                  «       xs |	j                  d¬«      }|sŒa|j                  d«      }|r|j                  d¬«      nd}|j                  |||f«       Œ� |S )NÚclassé   r   Úpageú?úhtml.parserÚulz	news-list©Úclass_ÚliF)Ú	recursiveÚaT©Úhrefr1   ÚtitleÚ ©ÚstripÚspan)ÚLIST_URLÚurllibÚparseÚ	urlencoder#   r   ÚfindÚfind_allr   r   r5   Úget_textÚappend)Úpage_numÚparamsr   ÚhtmlÚ_ÚsoupÚitemsr*   r-   r/   r1   Úpage_urlr2   r6   Údate_strs                  r"   Úextract_list_pagerG   5   s+  € Ø�rˆ]€FØ�!‚|Ø!ˆˆv‰Ü
�S‰.œ6Ÿ<™<×1Ñ1°&Ó9Ñ
9€CÜ˜‹n�G€Dˆ!ÙØˆ	ä˜˜}Ó-€DØ€Eà	�‰�4 ˆÓ	,€BÙØˆ	à�k‰k˜$¨%ˆkÓ0ò 2ˆØ�G‰G�C˜dˆGÓ#ˆÙØØ�‰yˆÜ˜3 Ó%ˆØ—‘�g˜rÓ"×(Ñ(Ó*ÒD¨a¯j©j¸t¨jÓ.DˆÙØØ�w‰w�v‹ˆÙ04�4—=‘= t�=Ô,¸"ˆØ�‰�e˜X xÐ0Õ1ð2ð €Ló    c                 óÜ   — | sy	 | j                  «       j                  d«      }t        |«      dk(  r1t        |d   «      d›dt        |d   «      d›dt        |d   «      d›�S 	 | S #  Y | S xY w)	z Normalize YYYY-M-D to YYYY-MM-DDr3   ú-r   r   Ú04dr   Ú02dr   )r5   ÚsplitÚlenÚint)rF   Úpartss     r"   Únormalize_daterQ   W   s‚   € áØðØ—‘Ó ×&Ñ& sÓ+ˆÜˆu‹:˜Š?Ü˜% ™(“m CÐ(¨¬#¨e°A©h«-¸Ð)<¸A¼cÀ%ÈÁ(»mÈCÐ=PÐQÐQð ð €OøðØØ€Oús   …AA& Á&A+c                 óè  — t        | «      \  }}|sd d d g fS t        |d«      }d}|j                  dd¬«      }|r|j                  d¬«      }|sK|j                  d«      }|r8|j                  d¬«      }d	|v r"|j	                  d	«      d
   j                  «       }d}|j                  dd¬«      }	|	rR|	j                  d«      }
|
D ]<  }|j                  d¬«      }t        j                  d|«      sŒ,|j                  «       } n t        |«      }d}|j                  dd¬«      }|�rL|j                  ddg«      D ]  }|j                  «        Œ g }|j                  d«      D ]R  }d|j                  «       v rd|j                  «       v rŒ(|j                  d¬«      }|sŒ=|dvsŒB|j                  |«       ŒT |j                  d«      D ].  }|j                  d«      rŒ|j                  t        |«      «       Œ0 |sg|j                  d«      }|D ]Q  }|j                  dd«      }|sŒt        | |«      }|j                  dd«      xs d}|j                  d|› d|› d�«       ŒS dj!                  |«      }|s�|j                  dd¬«      }|rz|j                  ddg«      D ]  }|j                  «        Œ |j                  d«      D ]-  }|j                  d¬«      }|sŒd|vsŒj                  |«       Œ/ dj!                  «      }t        j"                  dd|«      j                  «       }g }t%        «       }|j                  d d¬!«      D ]¥  }|d"   }t        j&                  d#|t        j(                  «      xs d$|v }|sŒ6t        | |«      }|j                  d¬«      xs& |j	                  d%«      d&   j	                  d'«      d
   }||vsŒ�|j+                  |«       |j                  ||d(œ«       Œ§ ||||fS ))Nr)   r3   Úh1zcontent-titler+   Tr4   r2   rB   r   Údivz	wznr-messr6   z\d{4}[-\/]\d{1,2}[-\/]\d{1,2}ÚshowÚscriptÚstyleÚpu	   æ‰«ä¸€æ‰«u   æ‰‹æœº)ú õ   Â z&nbsp;ÚtableÚimgÚsrcÚaltz![ú](ú)ú

zshow-contentz\n{3,}r/   r0   r1   z&\.(pdf|doc|docx|xls|xlsx|rar|zip|txt)$z/upload/ú/éÿÿÿÿr(   )Únamer   )r#   r   r;   r=   rM   r5   r<   ÚreÚmatchrQ   Ú	decomposer>   Úfind_parentÚstrr   r   ÚjoinÚsubÚsetÚsearchÚIÚadd)r   rA   ÚresprC   r2   rS   ÚtÚrawrF   ÚmessÚspansr6   ÚcontentÚshow_divÚsrP   rX   ÚtblÚimgsr\   r]   Úfull_srcr^   ÚscÚattachmentsÚseenÚa_tagr1   Úis_attachmentÚfull_urlrd   s                                  r"   Úfetch_detailr�   d   sõ  € Ü˜3“�J€Dˆ$ÙØ�T˜4 Ð#Ð#ä˜˜}Ó-€Dð €EØ	�‰�4 ˆÓ	0€BÙ	Ø—‘ $�Ó'ˆÙØ�I‰I�gÓˆÙØ—*‘* 4�*Ó(ˆCØ�c‰zØŸ	™	 #› qÑ)×/Ñ/Ó1�ð €HØ�9‰9�U ;ˆ9Ó/€DÙØ—‘˜fÓ%ˆØò 	ˆDØ—‘ D�Ó)ˆAÜ�x‰xÐ8¸!Õ<ØŸ7™7›9�Ùð		ô
 ˜hÓ'€Hð €GØ�y‰y˜ vˆyÓ.€HÚØ×"Ñ" H¨gÐ#6Ó7ò 	ˆAØ�K‰K�Mð	àˆð ×"Ñ" 3Ó'ò 	 ˆAà˜aŸj™j›lÑ*¨x¸1¿:¹:»<Ñ/GØØ—
‘
 �
Ó&ˆAÚ�QÐ5Ò5Ø—‘˜Q•ð	 ð ×$Ñ$ WÓ-ò 	'ˆCØ—?‘? 7Õ+Ø—‘œS ›XÕ&ð	'ñ
 Ø×$Ñ$ UÓ+ˆDØò :�Ø—g‘g˜e RÓ(�ÚÜ& s¨CÓ0�HØŸ'™' %¨Ó,Ò2°�CØ—L‘L 2 c U¨"¨X¨J°aÐ!8Õ9ð:ð —+‘+˜eÓ$ˆñ Ø�Y‰Y�u ^ˆYÓ4ˆÙØ—[‘[ (¨GÐ!4Ó5ò �Ø—‘•ðà—[‘[ Ó%ò $�Ø—J‘J T�JÓ*�Ú˜¨AÒ-Ø—L‘L •Oð$ð —k‘k %Ó(ˆGä�f‰f�Y ¨Ó0×6Ñ6Ó8€Gð €KÜ‹5€DØ—‘˜s¨�Ó.ò DˆØ�V‰}ˆä�I‰IÐ?ÀÄrÇtÁtÓLò Ø˜$Ðð 	ò Ü˜s DÓ)ˆHØ—>‘>¨�>Ó-ÒR°·±¸C³ÀÑ1D×1JÑ1JÈ3Ó1OÐPQÑ1RˆDØ˜tÒ#Ø—‘˜Ô"Ø×"Ñ"¨D¸Ñ#BÕCðDð �(˜G [Ð0Ð0rH   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 rb   z), retry in zs...r   z	 failed: F)	r   Úsqlite3ÚOperationalErrorri   r   r   r   r   r   )ÚfnÚdescÚmax_attemptsÚdelayÚattemptr!   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)r„   ÚconnectÚDB_PATHÚexecute©Úconns    r"   Úinit_dbr’   Ö   s1   € Ü�?‰?œ7¨BÔ/€DØ‡L�LÐ*Ô+Ø‡L�LÐ,Ô-Ø€KrH   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+rY   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   )re   rk   r5   ÚjsonÚdumpsr�   Ú	SITE_NAMEÚCATEGORYÚGROUPÚrowcountr   r   r   r   )
r‘   r2   rE   Úpublish_dateru   r|   ÚsummaryÚatt_jsonÚcurr!   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                  ó8  ‡— 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                  ¬«        �n|t        |«      z  }d}|D ]¹  \  }}	}
‰j                  d|	f«      }|j                  «       rŒ+t        |	«      \  }}}}|xs |}|xs |
}|r|}n9|r.|D �cg c]  }d|d   › d|d   › d�‘Œ }}dj!                  |«      }n	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�ŒŸ‰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c c}w )'Nr   z	Scraping z, max pages: r   r   c                  ó&   •— ‰ j                  «        y )N)Úcommitr�   s   €r"   Údo_cleanzmain.<locals>.do_cleanÿ   s   ø€ à�‰�rH   z  Cleaning old data...zClean )r‡   z  Cleaned old data for z  Page z: 0 items (end)z)SELECT id FROM gov_raw WHERE page_url = ?ú[rd   r_   r   r`   ra   z<p><a href="z">z</a></p>g333333Ó?é<   rb   z: +z new, z total, ú:rL   z elapsed, ETA Úminé   z
Done! Found: z, New: z, Time: Úmrw   )Ú	MAX_PAGESrN   r   ÚargvrO   r   r˜   r   r’   r   r‹   r   rG   r�   Úfetchoner�   rj   r    r   Úmaxr£   Úclose)Ú	max_pagesÚ	total_newÚtotal_foundÚ
start_timer¤   ÚpnÚarticlesÚ	batch_newr2   rE   ÚdaterŸ   Ú	det_titleÚdet_dateÚdet_contentÚdet_attsÚfinal_titleÚ
final_dateÚfinal_contentr/   Ú	att_linesÚ
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áØ +‘ÙàCKÖL¸a˜q  6¡ ¨2¨a°©h¨Z°qÒ9ÐL�	ÐLØ &§¡¨IÓ 6‘à".¨x¨j¸¸;¸-ÀxÐ P�Ø!š RˆJä˜D +¨x¸À]ÐT^Ô_Ø˜Q‘�	Ø˜Q‘�	ä�J‰J�s�Oð/	ô2 ”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ðY,ð\ 	‡K�K„MÜ”$—)‘)“+ 
Ñ*Ó+€GØ‡J�J„LÜ	ˆO˜K˜=¨°	¨{¸(À7ÈBÁ;À-ÈqÐQXÐY[ÑQ[Ð\_ÐP`Ð`aÐ
bÔil×isÑisÖtøðC	ÚüòJ Ms   ¥L ÆLÌLÚ__main__)r   )zDB opé
   r©   )Ú__doc__r   re   r–   r„   r   Úosr   Úurllib.parser8   r   Úbs4r   r   rŽ   r˜   r™   rš   ÚBASE_URLr7   r«   r   r#   rG   rQ   r�   r‹   r’   r    rÄ   Ú__name__© rH   r"   ú<module>rÎ      sš   ðñ
÷ @× ?× ?× ?Ý Ý Ý  à
€Ø3€	Ø€Ø€Ø%€Ø=€Ø€	ð DØOØ0ñ€óò$òD
ò_1óHòòò(FuðR ˆzÒÙ…Fð rH   