Ë
    s…j&  ã                   óœ   — 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ZdZ	d
d„Z
d„ Zd„ Zd„ Zed	k(  r ej                   e«       «       yy)uû  yanshou100.com æ°´åœŸä¿�æŒ�å…¬ç¤ºç½‘ - å¢žé‡�æŠ“å�– v3 (ä¿®å¤�è¡¨æ ¼/æ®µè�½/é™„ä»¶æ ¼å¼�)

v3 ä¿®å¤� (2026-08-19 ç”¨æˆ·å��é¦ˆ):
1. æ­£æ–‡ä¿�ç•™ <p> æ®µè�½ + <table> è¡¨æ ¼ HTML (ä¸�å†�å‰¥å¹³)
   - clean_html ç”¨ bs4: åŽ» script/style/iframe/object, div/span/font/center unwrap,
     a è½¬ç»�å¯¹ URL, img è½¬æŸ¥çœ‹é“¾æŽ¥, è¡¨æ ¼ç»“æž„å®Œæ•´ä¿�ç•™
2. é™„ä»¶è½¬æ­£æ–‡å†…åµŒ <p><a href="ç»�å¯¹URL">é™„ä»¶å��</a></p> æ®µè�½ (å¤šé™„ä»¶ç‹¬ç«‹æˆ�æ®µ)
   - attachments å­—æ®µå�Œæ—¶ä¿�ç•™ [{fileName,fileUrl}] æ•°ç»„
3. å¯¼å…¥ä¸�èµ° import_jsonl_v2 çš„ strip_html å‰¥å¹³é€»è¾‘ â†’ ç›´æŽ¥å†™ gov_raw (ä¿�ç•™ HTML)
   - push_to_searchdb ä¿�ç•™ content åŽŸæ ·

ç”¨æ³•: python3 crawl_yanshou100_inc.py --pages 5 --type yanshou|qita --out /tmp/x.jsonl [--existing /tmp/ids.txt]
é    NzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36zhttps://www.yanshou100.comc              ƒ   ó  K  — d|rdnd› dt        j                  |«      › dt        j                  |«      › dt        › d|› d�}	 | j                  |«      ƒ d {  –—† S 7 Œ# t        $ r}d	t        |«      d d
 dœcY d }~S d }~ww xY w­w)NzÕ
    async () => {
        const opts = {
            method: 'POST',
            headers: {'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json, text/javascript, */*; q=0.01'}
        };
        if (ÚtrueÚfalsez€) {
            opts.headers['Content-Type'] = 'application/x-www-form-urlencoded';
            opts.body = new URLSearchParams(z…).toString();
        } else {
            opts.headers['Content-Type'] = 'application/json';
            opts.body = JSON.stringify(z,);
        }
        const r = await fetch('z' + 'zó', opts);
        const ct = r.headers.get('content-type') || '';
        if (ct.includes('application/json')) {
            return await r.json();
        }
        return {'code': 'notjson', 'msg': (await r.text()).slice(0, 120)};
    }
    Úerréd   )ÚcodeÚmsg)ÚjsonÚdumpsÚBASEÚevaluateÚ	ExceptionÚstr)ÚpageÚurlÚpayloadÚformÚjsÚes         ú%/root/gov_crawler/crawl_yanshou100.pyÚapi_postr      sœ   è ø€ ðñ ‰V Ð)ð *-ä-1¯Z©Z¸Ó-@Ð,Að B(ô )-¯
©
°7Ó(;Ð'<ð = ä $˜v U¨3¨%ð 0ð
€Bð*4Ø—]‘] 2Ó&×&Ð&Ð&ùÜò 4Ø¤c¨!£f¨T¨c lÑ3Õ3ûð4üsH   ‚ABÁA ÁAÁA ÁBÁA Á	BÁ(A>Á8BÁ9BÁ>BÂBc                 ó  — ddl m} ddlm}  || d«      } |g d¢«      D ]  }|j	                  «        Œ |j                  d«      D ]ˆ  }|j                  d«      xs |j                  d«      xs d	}|rL|j                  d
«      r|n |t        |«      }|j                  d|¬«      }d|_
        |j                  |«       Œy|j	                  «        ŒŠ |j                  ddi¬«      D ]  }|d= Œ |j                  g d¢«      D ]  }|j                  «        Œ |j                  d«      D ]p  }|j                  dd	«      }	|	r5|	j                  d«      s$|	j                  d
«      r|	n |t        |	«      |d<   ŒL|	sŒO|	j                  d«      sŒa|j	                  «        Œr |j                  d«      D ]I  }
|
j                  d¬«      rŒ|
j                  d«      rŒ(|
j                  d«      rŒ:|
j	                  «        ŒK t        |«      S )uS   ç™½å��å�•æ¸…æ´—: ä¿�ç•™ <p>/<table>/<a>/<img>, unwrap è£…é¥°æ ‡ç­¾, é“¾æŽ¥ç»�å¯¹åŒ–r   )ÚBeautifulSoup)Úurljoinzhtml.parser)ÚscriptÚstyleÚiframeÚobjectÚimgÚsrczdata-srcÚ ÚhttpÚa)Úhrefu   æŸ¥çœ‹å›¾ç‰‡ÚhiddenT)Úattrs)ÚdivÚspanÚfontÚcenterÚbÚstrongÚemÚiÚuÚsÚlabelr$   Ú
javascriptÚp)ÚstripÚtable)Úbs4r   Úurllib.parser   Ú	decomposeÚfind_allÚgetÚ
startswithr   Únew_tagÚstringÚreplace_withÚunwrapÚget_textÚfindr   )Úhtmlr   r   ÚsoupÚtr   r    Úabs_srcr#   r$   r3   s              r   Ú
clean_htmlrF   1   s¿  € å!Ý$Ù˜˜}Ó-€DÙÒ9Ó:ò ˆØ	�‰�ðð �}‰}˜UÓ#ò ˆØ�g‰g�e‹nÒ9 §¡¨
Ó 3Ò9°rˆÙØ Ÿ^™^¨FÔ3‘c¹ÄÀsÓ9KˆGØ—‘˜S w�Ó/ˆAØ%ˆAŒHØ×Ñ˜QÕà�M‰M�Oðð �]‰] (¨DÐ!1ˆ]Ó2ò ˆØˆh‰Kðà�]‰]ÒiÓjò ˆØ	�‰�
ðð �]‰]˜3Óò ˆØ�u‰u�V˜RÓ ˆÙ˜Ÿ™¨Ô5Ø $§¡°Ô 7™¹WÄTÈ4Ó=PˆAˆfŠIÚ�d—o‘o lÕ3à�K‰K�Mðð �]‰]˜3Óò ˆØ�z‰z ˆzÕ%¨a¯f©f°W­oÀaÇfÁfÈUÅmØ�K‰K�Mðô ˆt‹9Ðó    c           	   ƒ   óT  ‡K  — t         › d|› �}t        d«      D �]>  }	 | j                  |dd¬«      ƒ d {  –—†  | j	                  d«      ƒ d {  –—†  | j                  «       ƒ d {  –—† Št        j                  d‰«      }|r@|j                  d«      j                  «       r!|j                  d«      j                  «       d	v rt        j                  d
‰«      }|r4t        j                  dd|j                  d«      «      j                  «       nd}|j                  dd«      j                  «       }|r n&t        j                  d|dz   z  «      ƒ d {  –—†  �ŒA s|dxx   dz  cc<   y t        j                  d‰«      }|r"|j                  d«      j                  «       d d nd}	ˆfd„}
 |
d«      }d}	 | j                  d«      ƒ d {  –—† }|s+t        j                  d‰«      }|r|j                  d«      nd}|rt        |«      nd}g }t        j                   d‰«      D ]D  }|j                  d«      |j                  d«      }}|j#                  |t         › d|› d|› �dœ«       ŒF t%        «       }g }|D ]/  }|d   |vsŒ|j'                  |d   «       |j#                  |«       Œ1 d}|D ]  }|d|d   › d|d   › d �z  }Œ |r|d!z   |z   j                  «       }||||	||||d"œ}|d#xx   dz  cc<   |S 7 �ŒÃ# t        $ r Y �ŒÍw xY w7 �Œ½7 �Œ¨7 �Œ¾7 �ŒI# t        $ r Y �ŒSw xY w­w)$Nz/item_detail.html?id=é   Údomcontentloadedé0u  ©Ú
wait_untilÚtimeouti˜  z#id="itemName1"[^>]*>\s*([^<]+?)\s*<é   )ú&nbsp;z&nbsp;&nbsp;z#id="itemName2"[^>]*>\s*([^<]+?)\s*<ú\s+ú r!   rP   g       @Údetail_failu3   id="createDate"[^>]*>\s*æ—¶é—´[ï¼š:]\s*([^<]+?)\s*<é
   c                 ó¬   •— t        j                  d| z   dz   ‰«      }|r4t        j                  dd|j                  d«      «      j	                  «       S dS )Nzid="z"[^>]*>\s*([^<]+?)\s*<rQ   rR   rO   r!   )ÚreÚsearchÚsubÚgroupr4   )ÚfidÚmÚcs     €r   Úfieldz fetch_detail_page.<locals>.fieldm   sH   ø€ Ü�I‰I�g ‘mÐ&?Ñ?ÀÓCˆÙ:;Œr�v‰v�f˜c 1§7¡7¨1£:Ó.×4Ñ4Ó6ÐCÀÐCrG   ÚcompanyNamea_  
        (() => {
            const info = document.getElementById('itemInfo');
            if (!info) return '';
            let tbl = info.closest('table');
            if (!tbl) return '';
            const attTr = tbl.querySelector('tr#tr_attachment');
            if (attTr) attTr.remove();
            return tbl.outerHTML;
        })()
        z#id="itemInfo"[^>]*>([\s\S]*?)</div>z!jumpToFile\('([^']+)','([^']+)'\)é   z/item/showFile?fileId=z
&fileName=)ÚfileNameÚfileUrlra   z<p><a href="z">r`   z</a></p>ú
)Útitler   Úpage_urlÚpublish_dateÚcontentÚauthorÚ	site_nameÚattachmentsÚok)r   ÚrangeÚgotor   Úwait_for_timeoutrf   rV   rW   rY   r4   rX   ÚreplaceÚasyncioÚsleepr   rF   ÚfinditerÚappendÚsetÚadd)r   Úitem_idÚstatsrh   r   ÚattemptrD   rc   ÚdmÚpubr]   ÚcompanyÚbodyÚimÚattsr[   ÚfaÚfnÚseenÚatts2r#   Úatt_pÚitemr\   s                          @r   Úfetch_detail_pager„   W   sC  øè ø€ ÜˆFÐ'¨ yÐ
1€CÜ˜“8ó 1ˆð	Ø—)‘)˜CÐ,>È�)ÓN×NÐNð ×#Ñ# DÓ)×)Ð)Ø—,‘,“.× ˆÜ�I‰IÐ<¸aÓ@ˆÙ˜Ÿ™ ›
×(Ñ(Ô*¨a¯g©g°a«j×.>Ñ.>Ó.@ÐD^Ñ.^Ü—	‘	Ð@À!ÓDˆAÙ;<”—‘�v˜s A§G¡G¨A£JÓ/×5Ñ5Ô7À"ˆØ—‘˜h¨Ó+×1Ñ1Ó3ˆÙÙÜ�m‰m˜C 7¨Q¡;Ñ/Ó0×0Ò0ð1ñ ØˆmÓ Ñ!ÓØÜ	�‰ÐIÈ1Ó	M€BÙ&(ˆ"�(‰(�1‹+×
Ñ
Ó
˜c˜rÑ
"¨b€CôDñ �MÓ"€Gð €DðØ—]‘]ð 
$ó 
÷ 
ˆñ Ü�Y‰YÐ=¸qÓAˆÙ ˆr�x‰x˜Œ{ bˆÙ#Œ:�dÔ¨€Dð €DÜ�[‰[Ð=¸qÓAò dˆØ—‘˜“˜QŸW™W Q›ZˆBˆØ�‰ ´4°&Ð8NÈrÈdÐR\Ð]_Ð\`Ð0aÑbÕcðdô ‹5€DØ€EØò ˆØˆY‰<˜tÒ#Ø�H‰H�Q�y‘\Ô"Ø�L‰L˜�Oðð €EØò HˆØ�<  )¡˜~¨R°°*±¨¸hÐGÑG‰ðHáØ�t‘˜eÑ#×*Ñ*Ó,ˆð ØØØØØØØñ	€Dð 
ˆ$ƒK�1ÑƒKØ€KðW OúÜò 	Úð	úà)ùØ ùð 	1ùð
úô ò Úðüs§   ƒL(ŸK<¶K9·K<»L(ÁLÁL(Á'LÁ(C,L(ÅLÅA"L(Æ8L ÇLÇL ÇB3L(ÊA4L(Ë9K<Ë<	L	ÌL(ÌL	Ì	L(ÌL(ÌL(ÌL Ì	L%Ì!L(Ì$L%Ì%L(c               ƒ   óB
  K  — t        j                  «       } | j                  dt        d¬«       | j                  ddd¬«       | j                  dd	¬
«       | j                  ddd¬«       | j	                  «       }|j
                  ad|j
                  z   }t        «       }|j                  rut        j                  j                  |j                  «      rLt        |j                  d¬«      5 }|D ]&  }|j                  «       }|sŒ|j                  |«       Œ( 	 d d d «       t        dt!        |«      › �d¬«       ddddœ}t        |j"                  dd¬«      }	 ddlm}  |«       4 ƒd {  –—† }	|	j(                  j+                  d¬«      ƒ d {  –—† }
|
j-                  t.        d¬«      ƒ d {  –—† }|j1                  «       ƒ d {  –—† }|j3                  t4        dz   dd¬«      ƒ d {  –—†  |j7                  d«      ƒ d {  –—†  g }t9        d|j:                  dz   «      D �]	  }|d |j
                  dddddddd!œ
}t=        |d"|«      ƒ d {  –—† }|rt?        |jA                  d#«      «      d$vr!t        d%|› d&t?        |«      d d' › �d¬«        nž|jA                  d(«      xs g }|D ]*  }|jA                  d)«      |vsŒ|jC                  |d)   «       Œ, t        d%|› d*t!        |«      › d+t!        |«      › d,|jA                  d-«      › �d¬«       tE        jF                  d«      ƒ d {  –—†  �Œ t        d.t!        |«      › d/�d¬«       |D �cg c]  }t?        |«      |vsŒ|‘Œ }}t!        |«      t!        |«      z
  |d0<   t        d1t!        |«      › d2|d0   › d3�d¬«       tI        |«      D ]¾  \  }}tK        ||||«      ƒ d {  –—† }|r9|jM                  tO        jP                  |d4¬5«      d6z   «       |jS                  «        tE        jF                  tU        jV                  d7d8«      «      ƒ d {  –—†  |dz   d9z  dk(  sŒ”t        d:|dz   › dt!        |«      › d;|d<   › d=|d>   › �d¬«       ŒÀ |
jY                  «       ƒ d {  –—†  d d d «      ƒd {  –—†  |jY                  «        t        d?|d<   › d=|d>   › d@|d0   › �d¬«       y # 1 sw Y   �Œ¬xY w7 �Œf7 �ŒE7 �Œ)7 �Œ7 �Œô7 �ŒÞ7 �Œ–7 �Œ¿c c}w 7 �Œ,7 ŒÂ7 Œs7 Œe# 1 ƒd {  –—†7  sw Y   ŒuxY w# |jY                  «        w xY w­w)ANz--pagesé   )ÚtypeÚdefaultz--typeÚyanshouzyanshou/jiance/fangan/qita)rˆ   Úhelpz--outz/tmp/ys100_inc.jsonl)rˆ   z
--existingr!   u   å·²å­˜åœ¨ itemId é›†å�ˆæ–‡ä»¶Úyanshou100_zutf-8)Úencodingu   å·²æœ‰ itemId: T)Úflushr   )rj   rS   Úskip_existingÚw)Úasync_playwright)Úheadless)Ú
user_agentÚignore_https_errorsú/rJ   rK   rL   iÜ  rO   é   )
r   ÚlimitÚ
publicTypeÚitemNameÚstartÚendÚcityÚareaÚparTypeÚsunTypez/item/searchr   )Ú0Ú200u   é¡µu   : APIå¤±è´¥ éÈ   ÚdataÚitemIdz: u    æ�¡, ç´¯è®¡ z, total=Úcountu
   åˆ—è¡¨å…± u    ä¸ª itemIdrŽ   u   éœ€æŠ“ u    (è·³è¿‡å·²æœ‰ ú)F)Úensure_asciirb   g      ð?gÍÌÌÌÌÌü?rT   u   è¯¦æƒ… z: ok=rj   z fail=rS   u   å®Œæˆ�: ok=z skip_existing=)-ÚargparseÚArgumentParserÚadd_argumentÚintÚ
parse_argsr‡   Ú	args_typers   ÚexistingÚosÚpathÚexistsÚopenr4   rt   ÚprintÚlenÚoutÚplaywright.async_apir�   ÚchromiumÚlaunchÚnew_contextÚUAÚnew_pagerl   r   rm   rk   Úpagesr   r   r:   rr   ro   rp   Ú	enumerater„   Úwriter
   r   r�   ÚrandomÚuniformÚclose)ÚapÚargsrh   Úexisting_idsÚfÚlinerv   Úout_fpr�   r3   ÚbrowserÚctxr   Úall_idsÚpgr   ÚdÚitemsÚitr.   Únew_idsÚiidrƒ   s                          r   ÚmainrÐ   ©   s¾  è ø€ ä	×	 Ñ	 Ó	"€BØ‡O�O�I¤C°€OÔ3Ø‡O�O�H iÐ6R€OÔSØ‡O�O�GÐ%;€OÔ<Ø‡O�O�L¨"Ð3R€OÔSØ�=‰=‹?€DØ—	‘	€IØ §	¡	Ñ)€Iä“5€LØ‡}‚}œŸ™Ÿ™¨¯©Ô6Ü�$—-‘-¨'Ô2ð 	+°aØò +�Ø—z‘z“|�ÚØ ×$Ñ$ TÕ*ñ+÷	+ô
 
ˆOœC Ó-Ð.Ð
/°tÕ<à Q¸Ñ;€EÜ�$—(‘(˜C¨'Ô2€Fð(Ý9Ù#Ó%÷ $	"ð $	"¨ØŸJ™J×-Ñ-°tÐ-Ó<×<ˆGØ×+Ñ+´rÈtÐ+ÓT×TˆCØŸ™›×'ˆDØ—)‘)œD 3™JÐ3EÈu�)ÓU×UÐUØ×'Ñ'¨Ó-×-Ð-àˆGÜ˜A˜tŸz™z¨A™~Ó.ó '�Ø#%°À$Ç)Á)Ø')°B¸rÈ2Ø#%°"ÀñE�ô # 4¨¸ÓA×A�ÙœS §¡ v£Ó/°|ÑCÜ˜C ˜t <´°A³°t¸°¨~Ð>ÀdÕKÙØŸ™˜f›Ò+¨�Øò 5�BØ—v‘v˜hÓ'¨wÒ6ØŸ™ r¨(¡|Õ4ð5ô ˜˜B˜4˜r¤# e£* ¨]¼3¸w»<¸.ÈÐQR×QVÑQVÐW^ÓQ_ÐP`ÐaÐimÕnÜ—m‘m AÓ&×&Ò&ð'ô �Jœs 7›|˜n¨KÐ8ÀÕEà")ÖH˜Q¬S°«V¸<Ò-G’qÐHˆGÐHÜ%(¨£\´C¸³LÑ%@ˆE�/Ñ"Ü�GœC ›L˜>¨¸¸Ñ9OÐ8PÐPQÐRÐZ^Õ_ä# GÓ,ò t‘��3Ü.¨t°S¸%ÀÓK×K�ÙØ—L‘L¤§¡¨D¸uÔ!EÈÑ!LÔMØ—L‘L”NÜ—m‘m¤F§N¡N°3¸Ó$<Ó=×=Ð=Ø˜‘E˜R‘< 1Ó$Ü˜G A a¡C 5¨¬#¨g«,¨°u¸UÀ4¹[¸MÈÐPUÐVcÑPdÐOeÐfÐnrÖsðtð —-‘-“/×!Ð!÷I$	"÷ $	"ðL 	�‰ŒÜ	ˆK˜˜d™�} F¨5°Ñ+?Ð*@ÀÐPUÐVeÑPfÐOgÐ
hÐptÖu÷e	+ñ 	+úð$	"ùØ<ùØTùØ'ùØUùØ-ùð Bùð 'ûò Ið
 Lùð >øð "øðI$	"ø÷ $	"÷ $	"ñ $	"ûðL 	�‰�üs\  ‚C)TÃ+SÄSÄ?TÅT
 Å)SÅ*T
 Å- S5ÆSÆS5Æ,SÆ-S5ÇSÇ"S5Ç'SÇ(S5È SÈA
S5ÉS!ÉA0S5Ê=A(S5Ì%S$Ì&%S5ÍS'ÍS'Í"AS5Ï S,ÏA+S5Ð,S/Ð-S5Ð=A S5Ñ=S1Ñ>S5ÒT
 ÒS3ÒT
 Ò0TÓSÓTÓT
 ÓS5ÓS5ÓS5ÓS5ÓS5Ó!S5Ó$S5Ó'S5Ó/S5Ó1S5Ó3T
 Ó5TÓ;S>Ó<TÔT
 Ô
TÔTÚ__main__)F)Ú__doc__r§   ro   r
   rV   Úsysr¾   r®   r¹   r   r   rF   r„   rÐ   Ú__name__Úrun© rG   r   ú<module>r×      sZ   ðñ÷ 4× 3× 3Ó 3àv€Ø#€ó4ò8#òLOòd?vðB ˆzÒØ€G‡K�K‘“Õð rG   