Ë
    m }j½  ã                   ó*  — 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d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edk(  r e«        yy)uf  
crawl_chuanshan.py â€” èˆ¹å±±åŒºäººæ°‘æ”¿åºœÂ·é«˜æ–°åŒºåŠ¨æ€�
==============================================
CMS: é�‚å®�é«˜æ–°æŠ€æœ¯äº§ä¸šå›­åŒºå­�ç«™ï¼Œ?page=N åˆ†é¡µï¼Œ20æ�¡/é¡µï¼Œ30é¡µ/~600æ�¡

åˆ—è¡¨ï¼š<ul class="news-list"><li><a title="TITLE" href="/gxq/zwgk/show/xxx.html">TITLE</a><span>YYYY-MM-DD</span></li></ul>
è¯¦æƒ…ï¼š<div class="article-content pt-2 xqing-web-box"> æ­£æ–‡
      <meta name="ArticleTitle"> / <meta name="PubDate"> / <meta name="ContentSource">

ç”¨æ³•:
    python3 crawl_chuanshan.py               # å…¨é‡�
    python3 crawl_chuanshan.py 1             # å¢žé‡�ï¼ˆä»…çˆ¬ç¬¬ä¸€é¡µï¼‰
é    N)ÚBeautifulSoup)Úurljoin)ÚdatetimeÚ	timedelta)ÚThreadPoolExecutorÚas_completedÚ	SEARCH_DBÚGOV_DB_PATHz/root/search.dbzhttps://www.chuanshan.gov.cnz4/gxq/zwgk/list/db49e9ea4397a019d43a5057ef8cbe9e.htmlu   èˆ¹å±±åŒºäººæ°‘æ”¿åºœ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é   éd   c                 ó    — t        d| › �«       y )Nz[chuanshan] )Úprint)Úmsgs    ú$/root/gov_crawler/crawl_chuanshan.pyÚlogr   *   s   € Ü	ˆL˜˜Ð
Õó    c                 óX  — | dkD  rt         › t        › d| › �nt         › t        › �}	 t        j                  |t        d¬«      }d|_        |j                  }g }t        j                  d
|t        j                  «      D ]æ  }|j                  d«      j                  «       }|j                  d«      }|j                  d«      sŒEt        t         |«      }	d}
t        j                   dt        j"                  |«      › d�|«      }t        j                   dt        j"                  |«      › d�|t        j                  «      }|r|j                  d«      }
|j%                  |	||
f«       Œè t        j                   d|«      d	u}||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 ú: FNz=<a\s+target="_blank"\s+title="([^"]*)"\s+href="([^"]+)"[^>]*>é   z/gxq/zwgk/show/Ú zre:\s*z'["\']?>\s*</a><span>(\d{4}-\d{2}-\d{2})z<li[^>]*>.*?href="z1"[^>]*>.*?</a>\s*<span>(\d{4}-\d{2}-\d{2})</span>u   page=(\d+)">ä¸‹ä¸€é¡µ</a>)ÚBASE_URLÚLIST_URLÚrequestsÚgetÚHEADERSÚencodingÚtextÚ	Exceptionr   ÚreÚfinditerÚDOTALLÚgroupÚstripÚ
startswithr   ÚsearchÚescapeÚappend)ÚpageÚurlÚrespÚhtmlÚeÚitemsÚmÚtitleÚhrefÚfull_urlÚdate_strÚdÚli_matchÚhas_nexts                 r   Úfetch_list_pager<   .   s�  € à15¸²ŒXˆJ”x�j  t fÑ
-Ä(ÀÌHÈ:Ð?V€CðÜ�|‰|˜C¬¸"Ô=ˆØˆŒØ�y‰yˆð
 €EÜ�[‰[ØHØŒb�i‰ióò 2ˆð —‘˜“
× Ñ Ó"ˆØ�w‰w�q‹zˆØ�‰Ð0Ô1ØÜœ8 TÓ*ˆð ˆÜ�I‰I˜¤§	¡	¨$£Ð0Ð0]Ð^Ð`dÓeˆô —9‘9Ø!¤"§)¡)¨D£/Ð!2Ð2iÐjØ”"—)‘)ó
ˆñ Ø—~‘~ aÓ(ˆHà�‰�h  xÐ0Õ1ð/2ô2 �y‰yÐ5°tÓ<ÀDÐH€HØ�(ˆ?Ðøô? ò Üˆm˜D˜6  A 3Ð'Ô(Ø�5ˆyÕûðús   ¦/F Æ	F)Æ
F$ÆF)Æ$F)c                 ó‚  — 	 t        j                  | t        d¬«      }d|_        |j                  }t        |d«      }|j                  d	d
di¬«      }|r$|j                  d«      r|d   j                  «       nd}d}|j                  d	d
di¬«      }|rK|j                  d«      r:t        j                  d|d   j                  «       «      }	|	r|	j                  d«      }|j                  d„ ¬«      }
|
rt        |
«      n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, title) or (None, None, None).r   r   r   z  ERROR r   N©NNNzhtml.parserÚmetaÚnameÚArticleTitle)ÚattrsÚcontentr   ÚPubDatez(\d{4}-\d{2}-\d{2})r   c                 óT   — | xr% dt        | t        «      r| ndj                  | «      v S )Nzarticle-contentú )Ú
isinstanceÚstrÚjoin)Úcs    r   ú<lambda>zfetch_detail.<locals>.<lambda>p   s+   € ¨AÒ,qÐ2CÌZÐXYÔ[^ÔM_ÉÐeh×emÑemÐnoÓepÐ2q€ r   )Úclass_z  WARNING: no content for )r   r    r!   r"   r#   r$   r   r   Úfindr)   r%   Úmatchr(   rH   )r/   r0   r1   r2   ÚsoupÚ
meta_titler5   r8   Ú	meta_dater4   Ú
content_elÚcontent_htmls               r   Úfetch_detailrT   W   sE  € ð Ü�|‰|˜C¬¸"Ô=ˆØˆŒØ�y‰yˆô
 ˜˜}Ó-€Dð —‘˜6¨&°.Ð)A�ÓB€JÙ-7¸J¿N¹NÈ9Ô<UˆJ�yÑ!×'Ñ'Ô)Ð[]€Eð €HØ—	‘	˜&¨°Ð(;�	Ó<€IÙ�Y—]‘] 9Ô-Ü�H‰HÐ+¨Y°yÑ-A×-GÑ-GÓ-IÓJˆÙØ—w‘w˜q“zˆHð —‘Ñ"q�Ór€JÙ&0”3�z”?°b€LáÜÐ(¨¨Ð.Ô/Ø�X˜uÐ$Ð$à˜ 5Ð(Ð(øô5 ò  Üˆh�s�e˜2˜a˜SÐ!Ô"Üûð ús   ‚/D Ä	D>Ä#D9Ä9D>c                 ó2  — i }t        t        ¬«      5 }| D �ci c]  }|j                  t        |«      |“Œ }}t	        |«      D ]  }||   }	 |j                  «       ||<   Œ 	 d d d «       |S c c}w # t        $ r}d||<   Y d }~ŒAd }~ww xY w# 1 sw Y   |S xY w)N)Úmax_workersr>   )r   ÚMAX_WORKERSÚsubmitrT   r   Úresultr$   )ÚurlsÚresultsÚexr/   Úfut_mapÚfutr2   s          r   Úfetch_detail_batchr_   z   s¤   € Ø€GÜ	¬Ô	4ð 2¸Ø@DÖE¸�2—9‘9œ\¨3Ó/°Ñ4ÐEˆÐEÜ Ó(ò 	2ˆCØ˜#‘,ˆCð2Ø"Ÿz™z›|�˜’ñ	2÷2ð €Nùò Føô
 ò 2Ø1�˜–ûð2ú÷2ð €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)z3items: list of (url, title, date_str, content_html)r   Nzœ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)
r3   ra   ÚconnrJ   Úinsertedr/   r5   r8   rS   r2   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                  óF  — 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
�«        nM|r|	st        d|› d�«        n8|dz  dk(  rt        d|› dt        |«      › d�«       |rŒ¯t        d|› d�«        n 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 ]A  \  }}}|j                  |d«      \  }}}|xs |}|xs |}|
j                  ||||xs df«       ŒC ŒŸ 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«       |j/                  «        |j1                  «        t        d$«       y c c}}}w c c}}w c c}w # t2        $ 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	 articlesz: all before cutoff, stoppingé
   r   z  Page r   z articles so farz: no next page, stoppingzTotal articles: é   z  Details [ú-ú/z]...r>   r   ú
z2==================================================zDone. Total: z articles (saved: ú)r   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: )ÚlenÚsysÚargvr   Únowr   Ústrftimer   ÚrangeÚ	MAX_PAGESr<   ÚextendrW   r_   r    r-   rl   Úsortedra   rb   rc   re   rg   rh   ri   r$   )ÚincrementalÚthree_years_agoÚall_articlesr.   Úarticlesr;   ÚuÚtr9   Úfilteredr[   Ú
batch_sizeÚbatch_startÚbatchÚ_Ú
batch_urlsÚ
detail_mapr/   r5   r8   rS   Údetail_dateÚdetail_titleÚfinal_titleÚ
final_dateÚsavedÚrÚdatesra   rj   r2   s                                  r   Úmainr”   Ÿ   sO  € Ü”c—h‘h“- !Ñ#Ò:¬¯©°©°sÑ(:€KÜ—|‘|“~¬	°wÔ(?Ñ?×IÑIÈ*ÓU€OÜˆ/˜/Ð*Ð+Ô,ð €LÜ�aœ Q™Ó'ò ˆÜ,¨TÓ2Ñˆ�(ÙÜ�%˜�vÐ0Ð1Ô2Ùà-5×TÐT¡' ! Q¨º¸qÀOÓ?S�Q˜˜1’IÐTˆÒTØ×Ñ˜HÔ%áÜÐ'¬¨H« °iÐ@ÔAÙá™HÜ�%˜�vÐ:Ð;Ô<Ùà�"‰9˜Š>Ü�'˜$˜˜r¤# lÓ"3Ð!4Ð4DÐEÔFâÜ�%˜�vÐ5Ð6Ô7Ùð-ô0 Ð
œ3˜|Ó,Ð-Ð.Ô/ð €GÜ˜q‘€JÜ˜Q¤ LÓ 1°:Ó>ò 	OˆØ˜[¨°zÑ)AÐBˆØ',×-™G˜A˜q !’aÐ-ˆ
Ñ-Üˆk˜+ a™-˜¨¨+´c¸%³jÑ*@Ð)AÀÄ3À|ÓCTÐBUÐUYÐZÔ[Ü'¨
Ó3ˆ
Ø$)ò 	OÑ ˆC�˜Ø6@·n±nÀSÐJ\Ó6]Ñ3ˆL˜+ |Ø&Ò/¨%ˆKØ$Ò0¨ˆJØ�N‰N˜C ¨j¸,Ò:LÈ"ÐMÕNñ		Oð	Oô �wÓ€Eäˆ"ˆXˆJˆÔÜˆ-œ˜G›�~Ð%7¸°w¸aÐ@ÔAÙÜ gÖ6 °°1³˜˜!›Ò6Ó7ˆÜˆl˜5 ™8˜* C¨¨b©	 {Ð3Ô4ð&ÛØ�‰œwÓ'ˆØ�‰ð ô
 ˆYô	ð 	�‰ŒØ�
‰
ŒÜÐÕ ùôo Uùó2 .ùò 7øô  ò &ÜÐ   Ð$×%Ñ%ûð&ús=   Â2K-
Â>K-
ÃK-
ÆK4É 
K:É+K:ÊAK? Ë?	L ÌLÌL Ú__main__)Ú__doc__Úosr%   rx   r   Úbs4r   Úurllib.parser   r   r   Úconcurrent.futuresr   r   Úenvironr    rc   r   r   rf   rg   r!   rW   r}   r   r<   rT   r_   rl   r”   Ú__name__© r   r   ú<module>rž      s¯   ðñó 
Û 	Û 
Û Ý Ý  ß (ß ?à
�*‰*�.‰.˜ b§j¡j§n¡n°]ÐDUÓ&VÓ
W€à)€ØA€Ø#€	Ø	€ð ð 3ð€ð €Ø€	ò ò&òR )òF
òò0F&ðR ˆzÒÙ…Fð r   