Ë
    m }jÀ  ã                   ó6  — 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dl	m	Z	m
Z
 ddlmZmZ ej                  j                  dej                  j                  dd	«      «      Zd
Zedz   ZdZdZddiZdZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zedk(  r e«        yy)u  
crawl_guanxian.py â€” å† åŽ¿äººæ°‘æ”¿åºœÂ·é€šçŸ¥å…¬å‘Š
==========================================
è�šå�ˆå¹³å�°ï¼Œæ±‡é›†å�„éƒ¨é—¨é€šçŸ¥å…¬å‘Š
?page=N åˆ†é¡µï¼Œ13æ�¡/é¡µï¼Œ~450é¡µ / ~5900æ�¡ï¼ˆ3å¹´ï¼‰

åˆ—è¡¨ï¼š<a href="/site_xxx/channel_x_xxx_6351/doc_xxx.html">
        <div>...<em>YYYY-MM-DD</em>...Title</div></a>
è¯¦æƒ…ï¼š<div class="main ovh"> æ­£æ–‡ | <meta name="PubDate"> æ—¥æœŸ

ç”¨æ³•:
    python3 crawl_guanxian.py             # å…¨é‡�
    python3 crawl_guanxian.py 1           # å¢žé‡�ï¼ˆå�ªçˆ¬é¦–é¡µï¼‰
é    N)ÚBeautifulSoup)Úurljoin)ÚdatetimeÚ	timedelta)ÚThreadPoolExecutorÚas_completedÚ	SEARCH_DBÚGOV_DB_PATHz/root/search.dbzhttp://www.guanxian.gov.cnz/channel_x_0.0_6351/u   å† åŽ¿äººæ°‘æ”¿åºœu   å† åŽ¿é€šçŸ¥å…¬å‘Šz
User-AgentzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36é   iô  c                 ó    — t        d| › �«       y )Nz[guanxian] )Úprint)Úmsgs    ú#/root/gov_crawler/crawl_guanxian.pyÚlogr   .   s   € Ü	ˆK˜�uÐ
Õó    c                 ó"   — | j                  «       S )N)Ústrip)Útitles    r   Úclean_titler   1   s   € Ø�;‰;‹=Ðr   c                 ó^  — | dkD  rt         › d| › �nt         }	 t        j                  |t        d¬«      }d|_        |j
                  }g }t        j                  d
|t        j                  «      D �]  }|j                  d«      }|j                  d«      }t        j                  dd|«      j                  «       }	t        j                  dd|	«      j                  «       }	d}
t        j                  d|	«      }|r|j                  d«      }
t        j                  dd|	«      j                  «       }t        |«      }|j!                  d«      r|}nt#        t$        |«      }|j'                  |||
f«       �Œ |t)        |«      dkD  fS # t        $ r}t        d| › d|› �«       g dfcY d	}~S d	}~ww xY w)z$Return [(url, title, date_str), ...]é   z?page=é   ©ÚheadersÚtimeoutúutf-8z  ERROR page ú: FNz3<a\s+href=\"([^\"]*doc_[^\"]+\.html)\"[^>]*>.*?</a>r   z<[^>]+>Ú z\s+ú ú(\d{4}-\d{2}-\d{2})z\d{4}-\d{2}-\d{2}Úhttp)ÚLIST_URLÚrequestsÚgetÚHEADERSÚencodingÚtextÚ	Exceptionr   ÚreÚfinditerÚDOTALLÚgroupÚsubr   Úsearchr   Ú
startswithr   ÚBASE_URLÚappendÚlen)ÚpageÚurlÚrespÚhtmlÚeÚitemsÚmÚhrefÚa_htmlr'   Údate_strÚdr   Úfull_urls                 r   Úfetch_list_pager?   4   s‡  € à'+¨a¢xŒXˆJ�f˜T˜FÑ
#´X€CðÜ�|‰|˜C¬¸"Ô=ˆØˆŒØ�y‰yˆð
 €Eä�[‰[Ø>ØŒb�i‰ióó 2ˆð �w‰w�q‹zˆØ—‘˜“ˆÜ�v‰v�j " fÓ-×3Ñ3Ó5ˆÜ�v‰v�f˜c 4Ó(×.Ñ.Ó0ˆð ˆÜ�I‰IÐ,¨dÓ3ˆÙØ—w‘w˜q“zˆHô —‘Ð+¨R°Ó6×<Ñ<Ó>ˆÜ˜EÓ"ˆð �?‰?˜6Ô"Ø‰Häœx¨Ó.ˆHà�‰�h  xÐ0Ö1ð32ð6 ”#�e“*˜q‘.Ð Ð øôC ò Üˆm˜D˜6  A 3Ð'Ô(Ø�5ˆyÕûðús   ˜/F Æ	F,ÆF'Æ!F,Æ'F,c                 ó0  — 	 t        j                  | t        d¬«      }d|_        |j                  }t        |d«      }d	}|j                  d
d„ ¬«      }|s|j                  d
d¬«      }|rt        |«      }d	}|j                  dddi¬«      }|rK|j                  d«      r:t        j                  d|d   j                  «       «      }	|	r|	j                  d«      }|st        d| › �«       d|fS ||fS # t
        $ r}t        d| › d|› �«       Y d}~yd}~ww xY w)z/Return (content_html, date_str) or (None, None)r   r   r   z  ERROR r   N©NNzhtml.parserr   Údivc                 ó   — | xr
 d| v xr d| v S )NÚmainÚovh© )Úcs    r   ú<lambda>zfetch_detail.<locals>.<lambda>l   s   € ¨AÒ,L°&¸A°+Ò,LÀ%È1À*€ r   )Úclass_rD   ÚmetaÚnameÚPubDate)ÚattrsÚcontentr    r   z  WARNING: no content for )r#   r$   r%   r&   r'   r(   r   r   ÚfindÚstrr)   Úmatchr   r,   )
r4   r5   r6   r7   ÚsoupÚcontent_htmlrB   r<   rJ   r9   s
             r   Úfetch_detailrT   ^   s  € ðÜ�|‰|˜C¬¸"Ô=ˆØˆŒØ�y‰yˆô
 ˜˜}Ó-€Dð €LØ
�)‰)�EÑ"Lˆ)Ó
M€CÙØ�i‰i˜ fˆiÓ-ˆÙ
Ü˜3“xˆð €HØ�9‰9�V F¨IÐ#6ˆ9Ó7€DÙ�—‘˜Ô#Ü�H‰HÐ+¨T°)©_×-BÑ-BÓ-DÓEˆÙØ—w‘w˜q“zˆHáÜÐ(¨¨Ð.Ô/Ø�Xˆ~Ðà˜Ð!Ð!øô5 ò Üˆh�s�e˜2˜a˜SÐ!Ô"Üûðús   ‚/C1 Ã1	DÃ:DÄDc           	      óT  — i }t        t        ¬«      5 }| D �ci c]  }|j                  t        |«      |“Œ }}t	        |«      D ]  }||   }	 |j                  «       ||<   Œ 	 ddd«       |S c c}w # t        $ r }t        d|› d|› �«       d||<   Y d}~ŒRd}~ww xY w# 1 sw Y   |S xY w)z'Fetch multiple detail pages in parallel)Úmax_workersz  ERROR in thread for r   rA   N)r   ÚMAX_WORKERSÚsubmitrT   r   Úresultr(   r   )ÚurlsÚresultsÚexr4   Úfut_mapÚfutr7   s          r   Úfetch_detail_batchr_   €   sº   € à€GÜ	¬Ô	4ð ,¸Ø@DÖE¸�2—9‘9œ\¨3Ó/°Ñ4ÐEˆÐEÜ Ó(ò 	,ˆCØ˜#‘,ˆCð,Ø"Ÿz™z›|�˜’ñ	,÷,ð €Nùò Føô
 ò ,ÜÐ,¨S¨E°°A°3Ð7Ô8Ø+�˜–ûð,ú÷,ð €NúsE   “B˜A,¶BÁA1ÁBÁ,BÁ1	BÁ:BÂBÂBÂBÂB'c           
      óT  — dd l }| sy|j                  t        «      }|j                  «       }d}| D ]-  \  }}}}	 |j	                  dt
        ||||t        f«       |dz  }Œ/ |j                  «        |j                  «        |S # t        $ r}	t        d|› d|	› �«       Y d }	~	Œqd }	~	ww xY w)Nr   zœINSERT OR REPLACE INTO gov_raw
                   (site_name, page_url, title, publish_date, content, category)
                   VALUES (?, ?, ?, ?, ?, ?)r   z  DB error for r   )Úsqlite3ÚconnectÚDB_PATHÚcursorÚexecuteÚ	SITE_NAMEÚSOURCEr(   r   ÚcommitÚclose)
r8   ra   ÚconnrG   Úinsertedr4   r   r<   rS   r7   s
             r   Ú
save_to_dbrl   Ž   s·   € ÛÙØØ�?‰?œ7Ó#€DØ�‰‹€AØ€HØ.3ò 
.Ñ*ˆˆU�H˜lð		.Ø�I‰Ið0ô ˜C ¨°,ÄÐGô	ð ˜‰M‰Hð
.ð 	‡K�K„MØ‡J�J„LØ€Oøô	 ò 	.Ü�/ #  b¨¨Ð,×-Ñ-ûð	.ús   º%BÂ	B'ÂB"Â"B'c                  ó|  — t        t        j                  «      dkD  xr t        j                  d   dk(  } t        j                  «       t        d¬«      z
  j                  d«      }t        d|› �«       g }t        dt        dz   «      D ]Ú  }t        |«      \  }}|st        d|› d�«        n¹|D ���cg c]  \  }}}|sŒ
||k\  sŒ|||f‘Œ }	}}}|j                  |	«       | rt        d	t        |	«      › d
�«        ni|rA|	s?t        |D �
�cg c]  \  }
}
}|sŒ
|‘Œ c}}
xs dg«      }|r||k  rt        d|› d�«        n&|dz  dk(  sŒÀt        d|› dt        |«      › d�«       ŒÜ t        dt        |«      › �«       g }t        dz  }t        dt        |«      |«      D ]–  }||||z    }|D ��
cg c]  \  }}
}
|‘Œ
 }}}
t        d|dz   › d|t        |«      z   › dt        |«      › d�«       t        |«      }|D ]:  \  }}}|j                  |d«      \  }}|xs |}|j!                  ||||xs df«       Œ< Œ˜ t#        |«      }t        dd› �«       t        dt        |«      › d|› d�«       |r9t%        |D �cg c]  }|d   sŒ	|d   ‘Œ c}«      }t        d|d   › d |d!   › �«       	 dd l}|j)                  t*        «      }|j-                  d"t.        f«       |j1                  «        |j3                  «        t        d#«       y c c}}}w c c}}
w c c}
}w c c}w # t4        $ r}t        d$|› �«       Y d }~y d }~ww xY w)%Nr   Ú1iG  )Údaysz%Y-%m-%dz3-year cutoff: zPage z: no data, stoppingzIncremental: page 1, z	 articlesr   z: all before cutoff, stoppingé2   r   z  Page r   z articles so farzTotal articles: é   z  Fetching details [ú-ú/z]...rA   ú
z2==================================================zDone. Total: z articles (saved: ú)é   zDate range: z ~ éÿÿÿÿa  
            INSERT OR REPLACE INTO gov_search(rowid, title, site_name, summary)
            SELECT rowid, title, site_name, 
                   CASE WHEN length(content) > 200 THEN substr(content, 1, 200) ELSE content END
            FROM gov_raw WHERE category = ?
        zFTS index rebuiltzFTS rebuild note: )r2   ÚsysÚargvr   Únowr   Ústrftimer   ÚrangeÚ	MAX_PAGESr?   ÚextendÚmaxrW   r_   r$   r1   rl   Úsortedra   rb   rc   re   rg   rh   ri   r(   )ÚincrementalÚthree_years_agoÚall_articlesr3   ÚarticlesÚhas_dataÚuÚtr=   ÚfilteredÚ_Úoldest_on_pager[   Ú
batch_sizeÚbatch_startÚbatchÚ
batch_urlsÚ
detail_mapr4   r   r<   rS   Údetail_dateÚ
final_dateÚsavedÚrÚdatesra   rj   r7   s                                 r   rD   rD   ¤   sh  € Ü”c—h‘h“- !Ñ#Ò:¬¯©°©°sÑ(:€KÜ—|‘|“~¬	°wÔ(?Ñ?×IÑIÈ*ÓU€OÜˆ/˜/Ð*Ð+Ô,ð €LÜ�aœ Q™Ó'ò GˆÜ,¨TÓ2Ñˆ�(ÙÜ�%˜�vÐ0Ð1Ô2Ùð .6×TÐT¡' ! Q¨º¸qÀOÓ?S�Q˜˜1’IÐTˆÒTØ×Ñ˜HÔ%áÜÐ'¬¨H« °iÐ@ÔAÙñ ™HÜ °8×!A©¨¨1¨aºq¢!Ó!AÒ!IÀbÀTÓJˆNÙ .°?Ò"BÜ�e˜D˜6Ð!>Ð?Ô@Ùà�"‰9˜‹>Ü�'˜$˜˜r¤# lÓ"3Ð!4Ð4DÐEÕFð-Gô0 Ð
œ3˜|Ó,Ð-Ð.Ô/ð €GÜ˜q‘€JÜ˜Q¤ LÓ 1°:Ó>ò 
IˆØ˜[¨°zÑ)AÐBˆØ',×-™G˜A˜q !’aÐ-ˆ
Ñ-ÜÐ" ;¨q¡= /°°;¼sÀ5»zÑ3IÐ2JÈ!ÌCÐP\ÓL]ÐK^Ð^bÐcÔdä'¨
Ó3ˆ
à$)ò 	IÑ ˆC�˜Ø(2¯©°s¸LÓ(IÑ%ˆL˜+Ø$Ò0¨ˆJØ�N‰N˜C ¨
°LÒ4FÀBÐGÕHñ	Ið
Iô �wÓ€Eô ˆ"ˆVˆHˆÔÜˆ-œ˜G›�~Ð%7¸°w¸aÐ@ÔAÙÜ gÖ6 °°1³˜˜!›Ò6Ó7ˆÜˆl˜5 ™8˜* C¨¨b©	 {Ð3Ô4ð&ÛØ�‰œwÓ'ˆØ�‰ð ô
 ˆYô	ð 	�‰ŒØ�
‰
ŒÜÐÕ ùôq Uùó "Bùó .ùò" 7øô  ò &ÜÐ   Ð$×%Ñ%ûð&úsI   Â2L
Â>L
ÃL
Ä
L	ÄL	Æ-LÉ5
LÊ LÊ&AL Ì	L;Ì#L6Ì6L;Ú__main__) Ú__doc__Úosr)   rx   r#   Úbs4r   Úurllib.parser   r   r   Úconcurrent.futuresr   r   Úenvironr$   rc   r0   r"   rf   rg   r%   rW   r}   r   r   r?   rT   r_   rl   rD   Ú__name__rF   r   r   ú<module>r�      s¾   ðñó 
Û 	Û 
Û Ý Ý  ß (ß ?ð �*‰*�.‰.˜ b§j¡j§n¡n°]ÐDUÓ&VÓ
W€ð (€ØÐ,Ñ,€Ø €	Ø	€ð ð 3ð€ð €Ø€	òòò(!òT "òDòò,H&ðV ˆzÒÙ…Fð r   