Ë
    )à±jþ(  ã                   óB  — 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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ZddiZd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)uU  
crawl_zibo_epb.py â€” æ·„å�šå¸‚ç”Ÿæ€�çŽ¯å¢ƒå±€Â·å�—ç�†
=========================================
CMS: æ·„å�šæ”¿åŠ¡å…¬å¼€å¹³å�°ï¼ˆå�Œé«˜æ–°åŒºå�Œä¸€CMSï¼‰
?open=fdzdgknr&nr_page=N&nr_per_page=10 åˆ†é¡µ
fdzdgknr_total å�˜é‡�èŽ·å�–æ€»æ•°

åˆ—è¡¨ï¼š<td class="zfxxgk-list-title"><a> â†’ title + <td class="zfxxgk-list-time"> date
è¯¦æƒ…ï¼š<div class="details-content" id="details-content"> æ­£æ–‡
      <meta name="ArticleTitle"> / <meta name="PubDate">

ç”¨æ³•:
    python3 crawl_zibo_epb.py               # å…¨é‡�ï¼ˆè¿‘3å¹´ï¼‰
    python3 crawl_zibo_epb.py 1             # å¢žé‡�ï¼ˆä»…æœ€æ–°é¡µï¼‰
é    N)ÚBeautifulSoup)Úurljoin)ÚdatetimeÚ	timedelta)ÚThreadPoolExecutorÚas_completedÚ	SEARCH_DBÚGOV_DB_PATHz/root/search.dbzhttps://epb.zibo.gov.cnz>/gongkai/channel_c_5f9fa491ab327f36e4c13066_n_1605682663.2363/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é   éÈ   c                 ó    — t        d| › �«       y )Nz[zibo_epb] )Úprint)Úmsgs    ú#/root/gov_crawler/crawl_zibo_epb.pyÚlogr   .   s   € Ü	ˆK˜�uÐ
Õó    c            	      ó6  — t         › t        › dt        › dt        t	        j                  «       «      › �} t        d«      D ]“  }	 t        j                  | t        d¬«      }d|_	        |j                  }t        j                  d|«      }|rt        |j!                  d«      «      c S t        d|dz   › d�«       t	        j                  d
|d
z  z   «       Œ• y# t        $ r9}t        d|dz   › d	|› �«       t	        j                  d
|d
z  z   «       Y d }~ŒÔd }~ww xY w)Nz%?open=fdzdgknr&nr_page=1&nr_per_page=ú&_t=é   é   ©ÚheadersÚtimeoutúutf-8zERROR fetching first page (try é   ú): é   z(fdzdgknr_total\s*=\s*parseInt\("(\d+)"\)z  total not found (try ú), retryingr   )ÚBASE_URLÚ	LIST_PATHÚPER_PAGEÚintÚtimeÚrangeÚrequestsÚgetÚHEADERSÚencodingÚtextÚ	Exceptionr   ÚsleepÚreÚsearchÚgroup)ÚurlÚattemptÚrespÚhtmlÚeÚms         r   Úfetch_total_countr6   2   s  € ÜˆJ”y�kÐ!FÄxÀjÐPTÔUXÔY]×YbÑYbÓYdÓUeÐTfÐ
g€CÜ˜“8ò $ˆð	Ü—<‘< ¬W¸bÔAˆDØ#ˆDŒMØ—9‘9ˆDô
 �I‰IÐAÀ4ÓHˆÙÜ�q—w‘w˜q“z“?Ò"ÜÐ% g¨a¡i [°Ð<Ô=Ü�
‰
�1�w ‘{‘?Õ#ð$ð øô ò 	ÜÐ1°'¸!±)°¸CÀ¸sÐCÔDÜ�J‰J�q˜7 Q™;‘Ô'Üûð	ús   Á/CÃ	DÃ/DÄDc                 óÎ  — t         › t        › d| › dt        › dt        t	        j                  «       «      › �}t        d«      D ]ƒ  }	 t        j                  |t        d¬«      }d|_	        |j                  }t        |d«      }|j                  d«      }|r n4t        d| › d|d
z   › d�«       t	        j                  d|dz  z   «       Œ… g S |j                  d«      }g }	t!        |«      D ]±  \  }
}|j#                  d«      }|r|j                  d«      sŒ+|d   }|j                  d«      xs |j%                  d¬«      xs d}|j'                  «       }|
t)        |«      k  r||
   j%                  d¬«      nd}t+        t         |«      }|	j-                  |||f«       Œ³ |	S # t        $ r=}t        d| › d	|d
z   › d|› �«       t	        j                  d|dz  z   «       Y d }~�Œ�d }~ww xY w)Nz?open=fdzdgknr&nr_page=z&nr_per_page=r   r   r   r   r   z  ERROR page z (try r   r   r   úhtml.parserztd.zfxxgk-list-titleú  Page z empty rows (try r   ztd.zfxxgk-list-timeÚaÚhrefÚtitleT)ÚstripÚ )r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r   r,   r   ÚselectÚ	enumerateÚfindÚget_textr=   Úlenr   Úappend)Úpager0   r1   r2   r3   r4   ÚsoupÚrowsÚdatesÚitemsÚiÚtdr:   r;   r<   Údate_strÚfull_urls                    r   Úfetch_list_pagerN   E   sØ  € ÜˆJ”y�kÐ!8¸¸¸mÌHÈ:ÐUYÔZ]Ô^b×^gÑ^gÓ^iÓZjÐYkÐ
l€CÜ˜“8ò ˆð	Ü—<‘< ¬W¸bÔAˆDØ#ˆDŒMØ—9‘9ˆDô
 ˜T =Ó1ˆØ�{‰{Ð1Ó2ˆÙÙÜˆg�d�VÐ,¨W°Q©Y¨K°{ÐCÔDÜ�
‰
�1�w ‘{‘?Õ#ðð  ˆ	à�K‰KÐ-Ó.€EØ€EÜ˜4“ò 	2‰ˆˆ2Ø�G‰G�C‹LˆÙ˜Ÿ™˜fœØØ�‰yˆØ—‘�g“Ò> !§*¡*°4 *Ó"8Ò>¸BˆØ—‘“ˆØ45¼¸E»
²N�5˜‘8×$Ñ$¨4Ð$Ô0ÈˆÜœ8 TÓ*ˆØ�‰�h  xÐ0Õ1ð	2ð €Løô3 ò 	Ü�- ˜v V¨G°A©I¨;°c¸!¸Ð=Ô>Ü�J‰J�q˜7 Q™;‘Ô'Ýûð	ús   Á/FÆ	G$Æ'2GÇG$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d„ ¬«      }
|
s|j                  dd¬«      }
|
r¤dD ](  }|
j                  |«      D ]  }|j                  «        Œ Œ* |
j                  t        j                   d«      ¬«      D ](  }|j#                  g d¢«      }|sŒ|j                  «        Œ* |
j                  dd„ ¬«      }|r|d   }
t%        |
«      }nd}|s,dD ]'  Š|j                  dˆfd„¬«      }
|
sŒt%        |
«      } n |st        d| › �«       d ||fS |||fS # t
        $ r}t        d| › d|› �«       Y d }~yd }~ww xY w)Nr   r   r   z  ERROR ú: ©NNNr8   ÚmetaÚnameÚArticleTitle)ÚattrsÚcontentr>   ÚPubDatez(\d{4}-\d{2}-\d{2})r   Údivc                 óT   — | xr% dt        | t        «      r| ndj                  | «      v S ©Núdetails-contentÚ ©Ú
isinstanceÚstrÚjoin©Úcs    r   ú<lambda>zfetch_detail.<locals>.<lambda>y   s-   € °AÒ4yÐ:KÔU_Ð`aÔcfÔUgÑPQÐmp×muÑmuÐvwÓmxÐ:y€ r   )Úclass_r[   )Úid)	z.sk-breadcrumbztable.details-infozh1.details-titlez.share-details-rowz.sharez.details-erweimaz.related-itemzli.details-info-fontsizezli.details-change-fontsizeu   æ‰“å�°)Ústring)r:   ÚliÚspanÚbuttonc                 óT   — | xr% dt        | t        «      r| ndj                  | «      v S rZ   r]   ra   s    r   rc   zfetch_detail.<locals>.<lambda>‰   sE   € À!ò  CHÐHYÔcmÐnoÔqtÔcuÑ^_Ð{~÷  |Dñ  |Dð  EFó  |Gð  IH€ r   éÿÿÿÿ)zzfxxgk-textÚnr_rightrV   Úarticlec                 óV   •— | xr% ‰t        | t        «      r| ndj                  | «      v S )Nr\   r]   )rb   Úclss    €r   rc   zfetch_detail.<locals>.<lambda>‘   s+   ø€ ¸AÒ<sÀ#ÌzÐZ[Ô]`ÔOaÉ!Ðgj×goÑgoÐpqÓgrÐBs€ r   z  WARNING: no content for )r&   r'   r(   r)   r*   r+   r   r   rA   r=   r-   Úmatchr/   r?   Ú	decomposeÚfind_allÚcompileÚfind_parentr_   )r0   r2   r3   r4   rF   Ú
meta_titler<   rL   Ú	meta_dater5   Úcontent_divÚselÚelÚnodeÚ
inner_listÚcontent_htmlro   s                   @r   Úfetch_detailr}   h   s:  ø€ ð Ü�|‰|˜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Ø—)‘)˜EÑ*y�)Óz€KÙØ—i‘i Ð*;�iÓ<ˆÙðNò 	ˆCð "×(Ñ(¨Ó-ò �Ø—‘•ñð	ð ×&Ñ&¬b¯j©j¸Ó.CÐ&ÓDò 	!ˆBØ—>‘>Ò"?Ó@ˆDÚØ—‘Õ ð	!ð
 !×)Ñ)¨%ñ  9HÐ)ó  Iˆ
ÙØ$ R™.ˆKÜ˜;Ó'‰àˆÙØDò 	ˆCØŸ)™) EÓ2s˜)ÓtˆKÚÜ" ;Ó/�Ùð		ñ
 ÜÐ(¨¨Ð.Ô/Ø�X˜uÐ$Ð$Ø˜ 5Ð(Ð(øôW ò  Üˆh�s�e˜2˜a˜SÐ!Ô"Üûð ús   ƒ/G8 Ç8	HÈHÈH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_workersrQ   )r   ÚMAX_WORKERSÚsubmitr}   r   Úresultr+   )ÚurlsÚresultsÚexr0   Úfut_mapÚfutr4   s          r   Úfetch_detail_batchrˆ   ›   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           
      óX  — dd l }| sy|j                  t        d¬«      }|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   é<   ©r   zœINSERT OR REPLACE INTO gov_raw
                   (site_name, page_url, title, publish_date, content, category)
                   VALUES (?, ?, ?, ?, ?, ?)r   z  DB error for rP   )Úsqlite3ÚconnectÚDB_PATHÚcursorÚexecuteÚ	SITE_NAMEÚSOURCEr+   r   ÚcommitÚclose)
rI   rŒ   Úconnrb   Úinsertedr0   r<   rL   r|   r4   s
             r   Ú
save_to_dbr—   ¨   s»   € ÛÙØØ�?‰?œ7¨Bˆ?Ó/€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                 ó   — ddl }| s
t        «       S |j                  t        d¬«      }	 dj	                  dt        | «      z  «      }|j                  d|› d�| «      j                  «       }|D �ch c]  }|d   ’Œ	 c}|j                  «        S c c}w # t        $ r t        «       cY |j                  «        S w xY w# |j                  «        w xY w)	u2   è¿”å›žå·²å…¥åº“çš„ URL é›†å�ˆ (å¢žé‡�å�œæ­¢æ�¡ä»¶)r   NrŠ   r‹   Ú,ú?z0SELECT page_url FROM gov_raw WHERE page_url IN (ú))
rŒ   Úsetr�   rŽ   r`   rC   r�   Úfetchallr”   r+   )rƒ   rŒ   r•   ÚphrG   Úrs         r   Úcheck_existingr    ¿   s±   € ãÙÜ‹uˆØ�?‰?œ7¨Bˆ?Ó/€Dð	Ø�X‰X�cœC ›I‘oÓ&ˆØ�|‰|Ø>¸r¸dÀ!ÐDÀdó
ç
‰(‹*ð 	ð #Ö#˜��!“Ò#ð 	�
‰
�ùò	 $øÜò Ü‹u‰à�
‰
�ðûð 	�
‰
�ús6   ©AB Á.BÁ:B ÂB ÂB8Â%B; Â7B8Â8B; Â;Cc                  ó¨  — t        t        j                  «      dkD  xr t        j                  d   dk(  } t        j                  «       t        d¬«      z
  j                  d«      }t        d|› �«       t        «       }|dk(  rt        d«       y |t        z   dz
  t        z  }t        d	|› d
|› d�«       g }| r|}nt        |t        «      }t        d|dz   «      D �]  }t        |«      }|st        d|› d�«        ní|D ��	�
cg c]  \  }}	}
|
sŒ
|
|k\  sŒ||	|
f‘Œ }}	}}
|j                  |«       | rxt        |D ��cg c]  \  }}}|‘Œ
 c}}«      }|D ��	�
cg c]  \  }}	}
||vsŒ||	|
f‘Œ }}	}}
|st        d|› d�«        nft        d|› dt        |«      › dt        |«      › �«       ŒÐ|r|st        d|› d�«        n*|dz  dk(  sŒît        d|› d|› dt        |«      › d�«       �Œ t        dt        |«      › �«       |sy 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/                  t0        d&¬'«      }!|!j3                  d(t4        f«       |!j7                  «        |!j9                  «        t        d)«       y c c}
}	}w c c}}w c c}
}	}w c c}}w c c}w # t:        $ r}"t        d*|"› �«       Y d }"~"y d }"~"ww xY w)+Nr   Ú1iG  )Údaysz%Y-%m-%dz3-year cutoff: r   z+ERROR: could not detect total article countzTotal: z articles, z pageszPage z: no data, stoppingz: all already in DB, stoppingr9   rP   z new, cumulative z: all before cutoff, stoppingr   ú/z so farzTotal filtered: é   z  Details [Ú-z]...rQ   r>   Ú
z2==================================================zDone. Total: z	 (saved: r›   r   zDate range: z ~ rk   rŠ   r‹   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: )rC   ÚsysÚargvr   Únowr   Ústrftimer   r6   r"   ÚminÚ	MAX_PAGESr%   rN   Úextendr    r€   rˆ   r'   rD   r—   ÚsortedrŒ   r�   rŽ   r�   r’   r“   r”   r+   )#ÚincrementalÚthree_years_agoÚtotal_countÚtotal_pagesÚall_articlesÚ	max_pagesrE   rI   ÚuÚtÚdÚfilteredÚ_ÚexistingÚnew_onesr„   Ú
batch_sizeÚbatch_startÚbatchÚ
batch_urlsÚ
detail_mapr0   r<   rL   r|   Údetail_dateÚdetail_titleÚfinal_titleÚ
final_dateÚsavedrŸ   rH   rŒ   r•   r4   s#                                      r   ÚmainrÇ   Ñ   s  € Ü”c—h‘h“- !Ñ#Ò:¬¯©°©°sÑ(:€KÜ—|‘|“~¬	°wÔ(?Ñ?×IÑIÈ*ÓU€OÜˆ/˜/Ð*Ð+Ô,ä#Ó%€KØ�aÒÜÐ9Ô:ØØ¤Ñ)¨AÑ-´(Ñ:€KÜˆ'�+�˜k¨+¨°fÐ=Ô>à€LÙØ‰	ä˜¤YÓ/ˆ	ä�a˜ Q™Ó'ó JˆÜ Ó%ˆÙÜ�%˜�vÐ0Ð1Ô2ÙØ-2×QÐQ¡' ! Q¨²a¸AÀÓ<P�Q˜˜1’IÐQˆÒQØ×Ñ˜HÔ%ÙÜ%¸×&A©W¨Q°°1¢qÓ&AÓBˆHØ19×OÐO¡g a¨¨A¸QÀhÒ=N˜˜A˜qš	ÐOˆHÒOÙÜ�e˜D˜6Ð!>Ð?Ô@ÙÜ�'˜$˜˜r¤# h£- Ð0AÄ#ÀlÓBSÐATÐUÔVØÙ™Ü�%˜�vÐ:Ð;Ô<ÙØ�"‰9˜‹>Ü�'˜$˜˜q  ¨2¬c°,Ó.?Ð-@ÀÐHÖIð'Jô* Ð
œ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›�~ Y¨u¨g°QÐ7Ô8ÙÜ gÖ6 °°1³˜˜!›Ò6Ó7ˆÜˆl˜5 ™8˜* C¨¨b©	 {Ð3Ô4ð&ÛØ�‰œw°ˆÓ3ˆØ�‰ð ô
 ˆYô	ð 	�‰ŒØ�
‰
ŒÜÐÕ ùôg Rùó 'BùÜOùó( .ùò 7øô ò &ÜÐ   Ð$×%Ñ%ûð&úsO   ÄN
ÄN
ÄN
Ä;NÅN
Å$N
È3N%Ì
N+ÌN+Ì3AN0 Î0	OÎ9OÏOÚ__main__)#Ú__doc__Úosr-   r¨   r$   r&   Úbs4r   Úurllib.parser   r   r   Úconcurrent.futuresr   r   Úenvironr'   rŽ   r    r!   r‘   r’   r"   r(   r€   r­   r   r6   rN   r}   rˆ   r—   r    rÇ   Ú__name__© r   r   ú<module>rÑ      sÁ   ðñó  
Û 	Û 
Û Û Ý Ý  ß (ß ?à
�*‰*�.‰.˜ b§j¡j§n¡n°]ÐDUÓ&VÓ
W€à$€ØL€	Ø&€	Ø	*€Ø€ð ð 3ð€ð €Ø€	òòò& òF0)òf
òò.ò$L&ð^ ˆzÒÙ…Fð r   