Ë
    ¸¬ujl"  ã                   ó¶   — 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mZ ddl	m
Z
 dZdZdZdZd	Zd
ZdddœZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zedk(  r e«        yy)u  
Crawler for é»„å¹³åŽ¿äººæ°‘æ”¿åºœ - é€šçŸ¥å…¬å‘Š
Site: www.qdnhp.gov.cn (è´µå·žé»”ä¸œå�—å·žé»„å¹³åŽ¿)
CMS: TRS WCM, JS document.write() list + right_list anchors
Pattern: 10 str_1 JS items (same on every page) + 20 right_list anchors per page
Total: 6 pages, ~104 records
é    N)ÚBeautifulSoup)Úurljoinz/root/search.dbu"   é»„å¹³åŽ¿äººæ°‘æ”¿åºœ-é€šçŸ¥å…¬å‘ŠÚ07zhttps://www.qdnhp.gov.cnz#https://www.qdnhp.gov.cn/xwzx/tzgg/é   z<Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36z?text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8)z
User-AgentÚAcceptc                 ó.   — | xs dj                  dd«      S )NÚ ú'z'')Úreplace)Úss    ú /root/gov_crawler/crawl_qdnhp.pyÚescr      s   € ØŠG�×Ñ˜S $Ó'Ð'ó    c                 óŒ  — g }t        «       }t        j                  d| «      D ]u  }|j                  d«      j	                  «       }|j                  d«      j	                  «       }||vsŒF|j                  |«       t        |«      }|j                  |||f«       Œw | j                  d«      }|dk\  r“| |d }	t        j                  d|	«      D ]u  }|j                  d«      j	                  «       }|j                  d«      j	                  «       }||vsŒF|j                  |«       t        |«      }|j                  |||f«       Œw |S )zCExtract list items from both str_1 JS blocks and right_list anchorsz/var str_1 = "([^"]+)";\s*var str_2 = "([^"]+)";é   é   zclass="right_listr   NzShref="(https://www\.qdnhp\.gov\.cn/xwzx/tzgg/\d+/t\d+_\d+\.html)"\s*title="([^"]+)")	ÚsetÚreÚfinditerÚgroupÚstripÚaddÚextract_date_from_urlÚappendÚfind)
ÚhtmlÚpage_urlÚitemsÚ	seen_urlsÚmÚurlÚtitleÚdate_strÚ	right_idxÚright_sections
             r   Úextract_items_from_pager&      s3  € à€EÜ“€Iô �[‰[ÐKÈTÓRò 1ˆØ�g‰g�a‹j×ÑÓ ˆØ—‘˜“
× Ñ Ó"ˆØ�iÒØ�M‰M˜#ÔÜ,¨SÓ1ˆHØ�L‰L˜%  hÐ/Õ0ð1ð —	‘	Ð-Ó.€IØ�A‚~Ø˜Y˜ZÐ(ˆÜ—‘Ðsð  vCó  Dò 	5ˆAØ—'‘'˜!“*×"Ñ"Ó$ˆCØ—G‘G˜A“J×$Ñ$Ó&ˆEØ˜)Ò#Ø—‘˜cÔ"Ü0°Ó5�Ø—‘˜e S¨(Ð3Õ4ð	5ð €Lr   c                 ó  — t        j                  d| «      }|r7|j                  d«      › d|j                  d«      › d|j                  d«      › �S t        j                  d| «      }|r&|j                  d«      › d|j                  d«      › d�S y)	zEExtract YYYY-MM-DD date from URL like /202607/t20260710_90606664.htmlz!/t(\d{4})(\d{2})(\d{2})_\d+\.htmlr   ú-r   é   z/(\d{4})(\d{2})/z-01r	   )r   Úsearchr   )r!   r    s     r   r   r   <   s   € ä
�	‰	Ð6¸Ó<€AÙØ—'‘'˜!“*�˜Q˜qŸw™w q›z˜l¨!¨A¯G©G°A«J¨<Ð8Ð8Ü
�	‰	Ð% sÓ+€AÙØ—'‘'˜!“*�˜Q˜qŸw™w q›z˜l¨#Ð.Ð.Ør   c                 óô  — 	 t        j                  | t        d¬«      }d|_        |j                  dk7  ry	 t        |j                  d
«      }d}|j                  d«      }|r^|j                  d¬«      }dD ]C  }||v sŒ|j                  |«      }|j                  t        d¬«       |d   j                  «       } n |s|}d}	|j                  d¬«      }
|
rGt        j                   d|
j                  «       «      }|r!|j#                  d«      j%                  dd«      }	|	sCt        j                   d|j                  «      }|r!|j#                  d«      j%                  dd«      }	d}|j                  dd¬«      }|s|j                  dd¬«      }|rÂ|j'                  d«      }|rQg }|D ]8  }|j                  dd¬«      }|sŒt        |«      dkD  sŒ(|j)                  |«       Œ: dj+                  |«      }n^|j'                  g d¢«      D ]5  }|j,                  d k(  sŒd!|j                  «       v sŒ&|j/                  «        Œ7 |j                  d"d¬«      }||	|fS # t
        $ r}t        d|z  d¬«       Y d	}~yd	}~ww xY w)#zParse detail pageé   ©ÚheadersÚtimeoutúutf-8éÈ   )NNNz
  [ERR] %sT©ÚflushNzhtml.parserr	   r"   )r   )ú - r(   u   â€”â€”u   â€”)ÚkeyÚreverser   ÚNewsArticlePubDay)Úidz(\d{4}[-/]\d{1,2}[-/]\d{1,2})r   ú/r(   ÚdivÚ
zx_content)Úclass_Únry_contentÚp)Ú	separatorr   r   z

)ÚscriptÚstyleÚarB   u   å­—ä½“ú
)ÚrequestsÚgetÚHEADERSÚencodingÚstatus_codeÚ	ExceptionÚprintr   Útextr   Úget_textÚsplitÚsortÚlenr   r   r*   r   r   Úfind_allr   ÚjoinÚnameÚ	decompose)r!   ÚrÚeÚsoupr"   Ú	title_tagÚrawÚsepÚpartsr#   Úpubdayr    Úcontentr;   ÚpsÚparasr>   ÚtxtÚunwanteds                      r   Úparse_detailra   G   se  € ð Ü�L‰L˜¤g°rÔ:ˆØˆŒ
Ø�=‰=˜CÒØ#ð  ô ˜Ÿ™ Ó/€Dð €EØ—	‘	˜'Ó"€IÙØ× Ñ  tÐ Ó,ˆØ0ò 	ˆCØ�cŠzØŸ	™	 #›�Ø—
‘
œs¨D�
Ô1Ø˜a™Ÿ™Ó(�Ùð	ñ ØˆEð €HØ�Y‰YÐ-ˆYÓ.€FÙÜ�I‰IÐ6¸¿¹Ó8IÓJˆÙØ—w‘w˜q“z×)Ñ)¨#¨sÓ3ˆHÙÜ�I‰IÐ6¸¿¹Ó?ˆÙØ—w‘w˜q“z×)Ñ)¨#¨sÓ3ˆHð €GØ—‘˜5¨�Ó6€JÙØ—Y‘Y˜u¨]�YÓ;ˆ
áØ× Ñ  Ó%ˆÙØˆEØò &�Ø—j‘j¨2°T�jÓ:�Úœ3˜s›8 a›<Ø—L‘L Õ%ð&ð —k‘k %Ó(‰Gà&×/Ñ/Ò0HÓIò )�Ø—=‘= CÓ'¨H¸×8IÑ8IÓ8KÒ,KØ×&Ñ&Õ(ð)ð !×)Ñ)°DÀÐ)ÓEˆGà�(˜GÐ#Ð#øôk ò  Üˆl˜QÑ dÕ+Üûð ús   ‚2I É	I7ÉI2É2I7c                 ó  — | st        dd¬«       yd}| D �]Q  \  }}}}d}t        j                  |t        t	        |«      fz  dddd¬«      }	 t        |j                  j                  «       «      }|dkD  rŒad	}	d
}
|
t	        |«      t	        |«      t	        |«      t	        |«      t	        |dd «      t	        |«      t	        t        «      t	        t        «      fz  }t        j                  dt        g|ddd¬«      }|j                  dk7  r5|j                  j                  «       }d|v r�Œt        d|›d|›�d¬«       �Œ)|dz  }|dk  s
|dz  dk(  s�Œ=t        d||dd fz  d¬«       �ŒT t        d|z  d¬«       y# t        $ r d}Y �Œw xY w)z)Save items to search.db using sqlite3 CLIzNo items to save.Tr2   Nr   z>sqlite3 %s "SELECT COUNT(*) FROM gov_raw WHERE page_url='%s';"é
   )ÚshellÚcapture_outputrK   r/   u   é»„å¹³åŽ¿äººæ°‘æ”¿åºœz�INSERT INTO gov_raw(page_url, title, content, publish_date, summary, source_url, site_name, industry) VALUES('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');r1   Úsqlite3©Úinputre   rK   r/   ÚUNIQUEz  [ERR] insert failed: r4   r   r   z  [OK] #%d %sé(   zInserted %d new records.)rJ   Ú
subprocessÚrunÚDB_PATHr   ÚintÚstdoutr   Ú
ValueErrorÚ	SITE_NAMEÚINDUSTRYÚ
returncodeÚstderr)r   Ú	new_countr"   r!   r#   r\   Ú	check_cmdÚprocÚexistsÚsourceÚsqlÚ
insert_sqlÚerrs                r   Ú
save_to_dbr}   †   s•  € áÜÐ!¨Õ.Øà€IØ).ó  MÑ%ˆˆs�H˜gØVˆ	Ü�~‰~Øœ¤# c£(Ð+Ñ+Ø t°$Àô
ˆð	Ü˜Ÿ™×*Ñ*Ó,Ó-ˆFð �AŠ:Øà(ˆð nˆØÜ�‹H”c˜%“j¤# g£,´°H³Ü��d�s�Óœc #›h¬¬I«¼¼H»ð
ñ 
ˆ
ô �~‰~ØœÐ Ø¨T¸Àbô
ˆð �?‰?˜aÒØ—+‘+×#Ñ#Ó%ˆCØ˜3‰Ùåº#¹sÐCÈ4×Pà˜‰NˆIØ˜AŠ~ ¨R¡°1Ô!4Ü�o¨°E¸#¸2°JÐ(?Ñ?Àt×LðA MôD 
Ð
$ yÑ
0¸Ö=øô5 ò 	Ø‹Fð	ús   Á#E;Å;F
Æ	F
c                  óÈ   — d} t        j                  dt        gd| z   dz   ddd¬«      }|j                  dk(  rt	        d	d¬
«       y t	        d|j
                  d d z  d¬
«       y )Nz°INSERT OR IGNORE INTO gov_search(rowid, title, site_name) SELECT r.rowid, r.title, r.site_name FROM gov_raw r LEFT JOIN gov_search s ON r.rowid = s.rowid WHERE s.rowid IS NULL;rf   zBEGIN;zCOMMIT;Téx   rg   r   zFTS sync done.r2   zFTS sync ERR: %sr1   )rk   rl   rm   rs   rJ   rt   )rz   rw   s     r   Úsync_ftsr€   ²   sg   € ð }€CÜ�>‰>Ø	”GÐØ˜‰n˜yÑ(Ø $°ô€Dð
 ‡�˜!ÒÜÐ dÖ+äÐ  4§;¡;¨t°Ð#4Ñ4¸DÖAr   c            
      óà  — t        dd¬«       t        dt        z  d¬«       t        dt        t        fz  d¬«       t        dd¬«       t	        «       } g }t        dt        dz   «      D ]ð  }|dk(  rt        }nd|z  }	 t        j                  |t        d¬	«      }|j                  d
k7  rt        d||j                  fz  d¬«        n•d|_
        t        |j                  |«      }d}|D ]5  \  }}}	|| vsŒ| j                  |«       |j                  |||	f«       |dz  }Œ7 t        d|t        |«      |t        |«      fz  d¬«       |dk(  rt        dd¬«        nŒò t        dt        |«      z  d¬«       |st        dd¬«       y g }t        |«      }t#        |d«      D ]]  \  }\  }}}	|dk  s|dz  dk(  s||k(  rt        d|||d d fz  d¬«       t%        |«      \  }}}|s|}|s|	}|j                  ||||f«       Œ_ t        dd¬«       t'        |«       t        dd¬«       t)        «        t        dt        |«      z  d¬«       y # t         $ r}
t        d||
fz  d¬«       Y d }
~
 �Œd }
~
ww xY w)Nz2==================================================Tr2   zStarting: %szTarget: %s, max pages: %dr   z0https://www.qdnhp.gov.cn/xwzx/tzgg/index_%d.htmlr,   r-   r1   zPage %d: HTTP %d (stop)r0   r   z+Page %d: %d items found, %d new (total: %d)z$  No new items, stopping pagination.zPage %d ERR: %sz
Total unique items found: %dzNo items to process.r)   rc   z
[%d/%d] %srj   z
--- Saving to DB ---z
--- FTS Sync ---z#
Done: %d unique items, saved to DB)rJ   rq   ÚLIST_URLÚ	MAX_PAGESr   ÚrangerD   rE   rF   rH   rG   r&   rK   r   r   rO   rI   Ú	enumeratera   r}   r€   )r   Ú	all_itemsÚpager   rT   r   Únew_on_pager"   r!   r#   rU   Ú	successesÚtotalÚiÚdetail_titleÚdetail_dater\   s                    r   ÚmainrŽ   ¿   sŽ  € Ü	ˆ(˜$ÕÜ	ˆ.œ9Ñ
$¨DÕ1Ü	Ð
%¬´9Ð(=Ñ
=ÀTÕJÜ	ˆ(˜$Õä“€IØ€Iä�aœ Q™Ó'ò ˆØ�1Š9Ü‰HàIÈDÑPˆHð	Ü—‘˜X¬wÀÔCˆAØ�}‰} Ò#ÜÐ/°4¸¿¹Ð2GÑGÈtÕTÙØ ˆAŒJä+¨A¯F©F°HÓ=ˆEØˆKØ(-ò %Ñ$��s˜HØ˜iÒ'Ø—M‘M #Ô&Ø×$Ñ$ e¨S°(Ð%;Ô<Ø 1Ñ$‘Kð	%ô Ð?Ø”c˜%“j +¬s°9«~ðC?ñ ?ØFJõLð ˜aÒÜÐ<ÀDÕIÙð  ð1ô> 
Ð
*¬S°«^Ñ
;À4ÕHÙÜÐ$¨DÕ1Øð €IÜ�	‹N€EÜ%.¨y¸!Ó%<ò DÑ!ˆÑ!ˆE�3˜Ø�Š6�Q˜‘V˜q’[ A¨¢JÜ�, ! U¨E°#°2¨JÐ!7Ñ7¸tÕDÜ-9¸#Ó->Ñ*ˆ�k 7ÙØ ˆLÙØ"ˆKØ×Ñ˜,¨¨[¸'ÐBÕCðDô 
Ð
"¨$Õ/ÜˆyÔô 
Ð
 dÕ+Ü„Jä	Ð
0´3°y³>Ñ
AÈÖNøô= ò 	ÜÐ# t¨Q iÑ/°tÕ<Þûð	ús&   Á=AIÃ,IÃ3A$IÉ	I-ÉI(É(I-Ú__main__)Ú__doc__rD   r   rk   ÚsysÚtimeÚosÚbs4r   Úurllib.parser   rm   rq   rr   ÚBASE_URLr‚   rƒ   rF   r   r&   r   ra   r}   r€   rŽ   Ú__name__© r   r   ú<module>r™      s†   ðñ÷ /× .× .Ý Ý  à
€Ø0€	Ø€Ø%€Ø0€Ø€	ð QØOñ€ò(òò:ò<$ò~)>òX
BòBOðJ ˆzÒÙ…Fð r   