Ë
    ¸¬ujÛ$  ã                   óF  — 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	m
Z
mZ ddlZddlmZ dZe› d�ZdZ ej$                  dd	«      Zd
diZddlmZmZ  ej.                  «        ed¬«      z
  j1                  d«      Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Ze dk(  r e«        yy)u±   
crawl_hualunchem.py â€” å�Žä¼¦æ–°æ��æ–™ - å…¬ç¤ºå…¬å‘Š (ä¸‡ç½‘æ—º CMS)
List: static HTML (page 1) + AJAX API for remaining pages
Detail: Body.js JS-rendered content extraction
é    N)ÚThreadPoolExecutorÚas_completed)ÚBeautifulSoupzhttps://www.hualunchem.comz/Designer/Common/GetDatau   å�Žä¼¦æ–°æ��æ–™-å…¬ç¤ºå…¬å‘ŠÚ	SEARCH_DBz/root/search.dbz
User-AgentzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36)ÚdatetimeÚ	timedeltaiG  )Údaysz%Y-%m-%dc                 óä  — g }d}|t        | «      k  �r/| |   dk(  rþ|dz   t        | «      k  rí| |dz      }|dk(  r|j                  d«       |dz  }nâ|dk(  r|j                  d«       |dz  }nÆ|d	k(  r|j                  d
«       |dz  }nª|dk(  s|dk(  s
|dk(  s|dk(  r|j                  |«       |dz  }n|dk(  rG|dz   t        | «      k  r6| |dz   |dz    }	 |j                  t        t        |d«      «      «       |dz  }n3|j                  | |   «       |dz  }n|j                  | |   «       |dz  }|t        | «      k  r�Œ/dj	                  |«      S #  |j                  d|z   |z   «       Y ŒuxY w)z+Unescape JavaScript string escape sequencesr   ú\é   Únú
é   ÚrúÚtú	ú"ú'ú/Úué   é   é   Ú )ÚlenÚappendÚchrÚintÚjoin)ÚsÚresultÚiÚcÚhex_strs        ú%/root/gov_crawler/crawl_hualunchem.pyÚunescape_js_strr'      sz  € à€FØ	€AØ
Œc�!‹f‹*ØˆQ‰4�4Š<˜A ™E¤C¨£FšNØ�!�A‘#‘ˆAØ�CŠxØ—‘˜dÔ#Ø�Q‘‘Ø�c’Ø—‘˜dÔ#Ø�Q‘‘Ø�c’Ø—‘˜dÔ#Ø�Q‘‘Ø�c’˜Q #šX¨¨dª°a¸3²hØ—‘˜aÔ Ø�Q‘‘Ø�c’˜a !™e¤c¨!£fšnØ˜A˜a™C  !¡˜*�ð6Ø—M‘M¤#¤c¨'°2Ó&6Ó"7Ô8ð �Q‘‘à—‘˜a ™dÔ#Ø�Q‘‘à�M‰M˜!˜A™$ÔØ�‰FˆAð7 Œc�!‹fŒ*ð8 �7‰7�6‹?Ðøð6Ø—M‘M $¨¡(¨WÑ"4Ö5ús   Ã$E ÅE/c                  óÒ   — 	 t        j                  t        › d�t        dd¬«      } d| _        t        j                  d| j                  «      }|r|j                  d«      S dS #  Y yxY w)	z1Get __RequestVerificationToken from the list pageú#/NewsInfoCategory?categoryId=398052é   F©ÚheadersÚtimeoutÚverifyúutf-8z5name='__RequestVerificationToken'[^>]*value='([^']+)'r   r   )	ÚrequestsÚgetÚBASE_URLÚHEADERSÚencodingÚreÚsearchÚtextÚgroup)r   Úms     r&   Úget_verification_tokenr:   :   se   € ðÜ�L‰LœH˜:Ð%HÐIÜ '°¸EôCˆàˆŒ
Ü�I‰IÐNÐPQ×PVÑPVÓWˆÙˆq�w‰w�q‹zÐ& BÐ&øðÙús   ‚AA" Á A" Á"A&c                  óŠ  — g } t        «       }	 t        j                  t        › d�t        dd¬«      }d|_        t        |j                  d«      }|j                  dd¬	«      D ]¹  }|j                  d
dd¬«      }|sŒ|d   }|j                  d«      sŒ1t        j                  j                  t        |«      }|j                  d¬«      }|j                  dd¬	«      }	|	r|	j                  d¬«      nd}
||vsŒ•|j                  |«       | j!                  |||
f«       Œ» 	 t'        «       }d}	 	 ddt)        |«      dddddddddd |d!œ}t        j*                  t,        |t        dd¬"«      }|j/                  «       }|j                  d#«      sn»|j                  d$g «      }|sn¦|D ]š  }|j                  d%d«      }|r|j                  d«      sŒ)t        j                  j                  t        |«      }||vsŒR|j                  |«       |j                  d&d«      }|j                  d'd«      }
| j!                  |||
f«       Œœ |dz  }�Œ| D ���cg c]  \  }}}|sŒ
|t0        k\  sŒ|||f‘Œ }}}}|S # t"        $ r}t%        d|› �«       Y d}~�Œmd}~ww xY w# t"        $ r}t%        d(|dz   › d)|› �«       Y d}~Œpd}~ww xY wc c}}}w )*z7Fetch all list items from page 1 (HTML) + page 2 (AJAX)r)   r*   Fr+   r/   úhtml.parserÚlizw-list-item©Úclass_Úazw-list-titlelinkT)r?   ÚhrefrA   z
/newsinfo/©ÚstripÚspanzw-list-dater   z  [ERROR] fetch page 1: Nr   ÚnewsÚ5Ú398052z
yyyy-MM-ddÚ
createtimeÚdescÚ0z{}ÚfalseÚtrue)ÚdataTypeÚkeyÚ	pageIndexÚpageSizeÚselectCategoryÚselectIdÚdateFormaterÚorderByFieldÚorderByTypeÚ
templateIdÚpostDataÚesÚsetTopÚ__RequestVerificationToken)Údatar,   r-   r.   Ú	IsSuccessÚDataÚLinkUrlÚNameÚQTimez  [ERROR] AJAX page ú: )Úsetr0   r1   r2   r3   r4   r   r7   Úfind_allÚfindÚ
startswithÚurllibÚparseÚurljoinÚget_textÚaddr   Ú	ExceptionÚprintr:   ÚstrÚpostÚAPI_URLÚjsonÚCUTOFF)Ú	all_itemsÚ	seen_urlsr   Úsoupr=   Úa_tagÚurlÚfull_urlÚtitleÚ	date_spanÚdate_strÚeÚtokenÚpage_idxr[   ÚrespÚ
data_itemsÚitemr   r   ÚdÚfiltereds                         r&   Úfetch_list_itemsrƒ   E   sÖ  € à€IÜ“€Ið.Ü�L‰LœH˜:Ð%HÐIÜ '°¸EôCˆàˆŒ
Ü˜QŸV™V ]Ó3ˆØ—-‘- ¨]�-Ó;ò 	>ˆBØ—G‘G˜CÐ(:À�GÓFˆEÙØØ˜‘-ˆCØ—>‘> ,Ô/ØÜ—|‘|×+Ñ+¬H°cÓ:ˆHØ—N‘N¨�NÓ.ˆEØŸ™ ¨}˜Ó=ˆIÙ9B�y×)Ñ)°Ð)Ô5ÈˆHØ˜yÒ(Ø—‘˜hÔ'Ø× Ñ  %¨°8Ð!<Õ=ñ	>ô$ #Ó$€EØ€HØ
ð&	à"ØÜ  ›]ØØ"*ØØ ,Ø ,Ø%Ø!Ø ØØ Ø.3ñˆDô  —‘œg¨D¼'Ø$&¨uô6ˆAà—6‘6“8ˆDØ—8‘8˜KÔ(ØØŸ™ &¨"Ó-ˆJÙØØ"ò 	B�Ø—h‘h˜y¨"Ó-�Ù #§.¡.°Ô">ØÜ!Ÿ<™<×/Ñ/´¸#Ó>�Ø 9Ò,Ø—M‘M (Ô+Ø ŸH™H V¨RÓ0�EØ#Ÿx™x¨°Ó4�HØ×$Ñ$ e¨X°xÐ%@ÕAð	Bð ˜‰MˆHñI ðT *3×HÐH™g˜a  A²a¸AÄ»K��A�q’	ÐH€HÒHØ€Oøôc ò .ÜÐ(¨¨Ð,×-Ò-ûð.ûôV ò 	ÜÐ(¨°!©¨°B°q°cÐ:Ô;Üûð	üô
 Is]   ŽC(I/ Ã7'I/ Ä-AJ ÆJ Æ AJ Ç4AJ ÉJ>É	J>É"J>É/	JÉ8JÊJÊ	J;ÊJ6Ê6J;c                 ó6  — 	 t        j                  | t        dd¬«      }d|_        t	        j
                  d|j                  «      }|s t	        j
                  d|j                  «      }|sy|j                  d«      }|j                  d	«      rd
|z   }t        j                  «       }| |d<   t        j                  ||dd¬«      }d|_        t	        j
                  d|j                  t        j                  «      }|syt        |j                  d«      «      }t        |d«      }d}	|j                  dd¬«      }
|
r|
j                  d¬«      }	d}|j                  dd¬«      }|rt        |«      }||	ddfS # t         $ r}t#        d| › d|› �«       Y d}~yd}~ww xY w)z(Fetch detail page via Body.js extractionr*   Fr+   r/   z*src='([^']+nocookie\.html\.Body\.js[^']*)'z*src="([^"]+nocookie\.html\.Body\.js[^"]*)")r   r   r   r   r   z//zhttps:ÚRefererz&document\.write\('((?:[^'\\]|\\.)*)'\)r<   r   Úh1zw-titler>   TrB   Údivzw-detailz  [ERROR] detail ra   N)r0   r1   r3   r4   r5   r6   r7   r8   re   ÚcopyÚSr'   r   rd   ri   rm   rk   rl   )rv   r   r9   Úbody_js_urlr,   Úr2Úm2Úhtmlrt   rx   r†   ÚcontentÚdetailr{   s                 r&   Úfetch_detailr�   ‘   sz  € ð1 ä�L‰L˜¤g°rÀ%ÔHˆØˆŒ
ô �I‰IÐCÀQÇVÁVÓLˆÙÜ—	‘	ÐGÈÏÉÓPˆAÙØ#à—g‘g˜a“jˆØ×!Ñ! $Ô'Ø" [Ñ0ˆKô —,‘,“.ˆØ ˆ�	ÑÜ�\‰\˜+¨wÀÈ5ÔQˆØˆŒô �Y‰YÐ@À"Ç'Á'Ì2Ï4É4ÓPˆÙØ#ô ˜rŸx™x¨›{Ó+ˆô ˜T =Ó1ˆàˆØ�Y‰Y�t IˆYÓ.ˆÙØ—K‘K d�KÓ+ˆEàˆØ—‘˜5¨�Ó4ˆÙÜ˜&“kˆGð ˜  BÐ'Ð'øäò  ÜÐ! #  b¨¨Ð,Ô-Üûð ús&   ‚A(E4 Á+BE4 Ã=A6E4 Å4	FÅ=FÆFc                 ó°  — dd l }|j                  t        d¬«      }|j                  d«       |j                  d«       |j	                  «       }d}| D ]:  \  }}}}}		 |j                  dt
        |||||	df«       |j                  dkD  r|dz  }Œ< |j                  «        |j                  «        |S # t        $ r}
t        d	|› d
|
› �«       Y d }
~
Œ~d }
~
ww xY w)Nr   é   )r-   zPRAGMA journal_mode=WALzPRAGMA busy_timeout=5000zÇ
                INSERT OR IGNORE INTO gov_raw 
                    (site_name, title, page_url, publish_date, source_url, content, category)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            u   å…¬ç¤ºå…¬å‘Šr   z  [DB ERROR] ra   )Úsqlite3ÚconnectÚDB_PATHÚexecuteÚcursorÚ	SITE_NAMEÚrowcountrk   rl   ÚcommitÚclose)Úitemsr“   ÚconnÚcurÚ	new_countrx   rv   Úpub_dateÚsourcerŽ   r{   s              r&   Úpush_to_searchdbr¢   Æ   sâ   € ÛØ�?‰?œ7¨Bˆ?Ó/€DØ‡L�LÐ*Ô+Ø‡L�LÐ+Ô,Ø
�+‰+‹-€CØ€IØ16ò 
.Ñ-ˆˆs�H˜f gð		.Ø�K‰Kð ô ˜U C¨°6¸7ÀNÐSô	Uð
 �|‰|˜aÒØ˜Q‘�	øð
.ð 	‡K�K„MØ‡J�J„LØÐøô	 ò 	.Ü�M #  b¨¨Ð,×-Ñ-ûð	.ús   Á1B1Â1	CÂ:CÃCc                  ó8  — t        j                  dd¬«       t        dt        j                  «       j                  d«      › dt        › �«       t        «       } t        dt        | «      › �«       | D ]  \  }}}t        d|› d|d d	 › �«       Œ | st        d
«       yg }t        d¬«      5 }| D ���ci c]   \  }}}|j                  t        |«      |||f“Œ" }	}}}t        t        |	«      d«      D ]—  \  }
}|	|   \  }}}	 |j                  «       \  }}}}|xs |}|xs |}|rD|j                  |||||f«       t        d|
› dt        | «      › d|d d	 › dt        |«      › d�	«       n!t        d|
› dt        | «      › d|d d	 › d�«       Œ™ 	 d d d «       |r%t#        |«      }t        d|› d�«       t        |«      S t        d«       t        |«      S c c}}}w # t         $ r.}t        d|
› dt        | «      › d|d d › d|› �«       Y d }~�Œd }~ww xY w# 1 sw Y   Œ‡xY w)NÚignorezUnverified HTTPS request)Úmessageú[z%H:%M:%Sz] z  Items within 3 years: z    [é2   z  No items found!r   r   )Úmax_workersr   z  [r   z... OK (zB)z... no contenté(   z... ERROR: z
  === Done === New: z, Errors: 0z
  === Done === No items)ÚwarningsÚfilterwarningsrl   r   ÚnowÚstrftimer˜   rƒ   r   r   Úsubmitr�   Ú	enumerater   r"   r   rk   r¢   )rœ   r   r   r�   ÚdetailsÚexecutorrx   rv   rz   Ú
future_mapr#   ÚfuturerŽ   Ú	det_titler    r¡   Úfinal_titleÚ
final_dater{   rŸ   s                       r&   Úmainr·   Ü   sd  € Ü×Ñ˜HÐ.HÕIÜ	ˆAŒh�l‰l‹n×%Ñ% jÓ1Ð2°"´Y°KÐ
@ÔAô Ó€EÜ	Ð$¤S¨£Z LÐ
1Ô2Øò %‰ˆˆ1ˆaÜ��a�S˜˜1˜S˜b˜6˜(Ð#Õ$ð%ñ ÜÐ!Ô"Øð €GÜ	¨Ô	*ð J¨hà27÷9ð 9Ù.˜%  hð —o‘o¤l°CÓ8¸5À#ÀxÐ:PÑPð 9ˆ
ò 9ä"¤<°
Ó#;¸QÓ?ò 	J‰IˆAˆvØ#-¨fÑ#5Ñ ˆE�3˜ð
JØ7=·}±}³Ñ4�˜ H¨fØ'Ò0¨5�Ø%Ò1¨�
ÙØ—N‘N K°°jÀ&È'Ð#RÔSÜ˜C ˜s !¤C¨£J <¨r°+¸c¸rÐ2BÐ1CÀ8ÌCÐPWËLÈ>ÐY[Ð\Õ]ä˜C ˜s !¤C¨£J <¨r°+¸c¸rÐ2BÐ1CÀ>ÐRÔSøñ	J÷Jñ$ Ü$ WÓ-ˆ	ÜÐ& y k°Ð=Ô>ô ˆw‹<Ðô 	Ð)Ô+äˆw‹<Ðùô/9øô ò JÜ˜˜A˜3˜a¤ E£
˜|¨2¨e°C°R¨j¨\¸ÀQÀCÐH×IÒIûðJú÷Jð JúsI   Â*HÂ1%G
Ã(HÃ?BGÆHÇHÇ	HÇ#HÈHÈHÈHÈHÚ__main__)!Ú__doc__r5   Úsysrp   ÚtimeÚosÚurllib.parserf   rª   Úconcurrent.futuresr   r   r0   Úbs4r   r2   ro   r˜   Úgetenvr•   r3   r   r   r¬   r­   rq   r'   r:   rƒ   r�   r¢   r·   Ú__name__© ó    r&   ú<module>rÄ      s»   ðñ÷
 7× 6× 6Ó 6ß ?Û Ý à'€ØˆJÐ.Ð
/€Ø*€	Ø
ˆ"�)‰)�KÐ!2Ó
3€ð ð  Dð€÷ )Ø
ˆ(�,‰,‹.™9¨%Ô0Ñ
0×	:Ñ	:¸:Ó	F€ò òD	òJòX3 òjò,(ðT ˆzÒÙ…Fð rÃ   