Ë
    |<|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dl
Z
ddlmZmZ dZedz   ZdZdZdZej&                  j)                  d	d
«      Zej&                  j)                  dd«      ZdZdZdZ eej6                  «      D ]k  \  ZZej=                  d«      r	  eejA                  dd«      d   «      ZŒ4edk(  sŒ:edz    e"ej6                  «      k  sŒS	  eej6                  edz      «      ZŒm edk\  rendZ#d„ Z$d„ Z%dd„Z&d„ Z'd„ Z(d„ Z)d„ Z*d„ Z+d„ Z,d„ Z-e.dk(  r e-«        yy# e!$ r Y Œ«w xY w# e!$ r Y Œ¶w xY w)uU  
crawl_hyx_tzgg.py - è¡¡é˜³åŽ¿-è¥¿æ¸¡é«˜æ–°åŒºé€šçŸ¥å…¬å‘Š
https://www.hyx.gov.cn/zwgk/bmxxgkml/xdgxq/tzgg/
é˜²æŠ¤: å¸�è�”CDN(403) + ç‘žæ•°4ä»£JSæ³¨å…¥(80ç«¯å�£æŒ‘æˆ˜, æ­£æ–‡éœ€æµ�è§ˆå™¨è§£å¯†) -> å¿…é¡» Playwright
åˆ—è¡¨: li > a, æ–‡æœ¬ "YYYY-MM-DD æ ‡é¢˜", è¯¦æƒ… /tzgg/YYYYMMDD/iNNNNNNN.html
åˆ†é¡µ: index.html / pages/N.html (å…±3é¡µ 41æ�¡, æ¯�é¡µ15/15/11)
è¯¦æƒ…: å�šå±±CMS(/bcms), meta ArticleTitle/PubDate + div#div_content æ­£æ–‡
  - æ™®é€šæ–‡ç« : div_content å†… HTML (p/table/img)
  - PDFåž‹æ–‡ç« : div_content å†… span.edui-pdf[data-pdf=/DFS//file/...] -> ä¸‹è½½PDF -> fitzæ��å�–æ–‡æœ¬
é    N)ÚBeautifulSoupÚCommentzhttp://www.hyx.gov.cnz$/zwgk/bmxxgkml/xdgxq/tzgg/index.htmlu%   è¡¡é˜³åŽ¿-è¥¿æ¸¡é«˜æ–°åŒºé€šçŸ¥å…¬å‘Šu   æ¹–å�—zcrawl_hyx_tzgg.pyÚDB_PATHz/root/search.dbÚ
JSONL_PATHÚ zoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36g      ø?é   z--pages=ú=z--pagesc                 ó  — | syt        j                  | «      } | j                  dd«      j                  dd«      j                  dd«      j                  dd«      } t        j                  dd| «      } | j                  «       S )Nr   u   â€‹u   â€Œu   â€�u   ï»¿ú\s+ú )Úhtml_libÚunescapeÚreplaceÚreÚsubÚstrip)Úts    ú#/root/gov_crawler/crawl_hyx_tzgg.pyÚclean_titler   3   so   € ÙØÜ×Ñ˜!Ó€AØ	�	‰	�(˜BÓ×'Ñ'¨°"Ó5×=Ñ=¸hÈÓK×SÑSÐT\Ð^`Óa€AÜ
�‰ˆv�s˜AÓ€AØ�7‰7‹9Ðó    c                 ó~   — | j                   j                  ddg¬«      }|j                  t        dddddœ¬«      }||fS )	NTz--no-sandbox)ÚheadlessÚargszzh-CNiV  i„  )ÚwidthÚheight)Ú
user_agentÚlocaleÚignore_https_errorsÚviewport)ÚchromiumÚlaunchÚnew_contextÚUA)ÚpÚbÚctxs      r   Úmake_browserr'   =   sM   € Ø	�
‰
×Ñ 4¨~Ð.>ÐÓ?€AØ
�-‰-ÜØØ Ø¨3Ñ/ð	 ó €Cð ˆcˆ6€Mr   c                 ó
  — t        d«      D ]f  }	 | j                  ||dz  d¬«       t        |dz  «      D ];  }| j                  d«       | j                  «       }d|v sŒ)| j                  d«         y	 Œh y
# t        $ r Y Œuw xY w)u.   ç‘žæ•°æŒ‘æˆ˜: commit + è½®è¯¢ title å�« è¡¡é˜³é   iè  Úcommit)ÚtimeoutÚ
wait_untilé   i   u   è¡¡é˜³iÜ  TF)ÚrangeÚgotoÚwait_for_timeoutÚtitleÚ	Exception)ÚpageÚurlr+   ÚattemptÚir   s         r   Úrobust_gotor7   H   s’   € ä˜“8ò 
ˆð		Ø�I‰I�c 7¨T¡>¸hˆIÔGÜ˜7 a™<Ó(ò  �Ø×%Ñ% dÔ+Ø—J‘J“L�Ø˜q’=Ø×)Ñ)¨$Ô/Úñ ð
ð øô ò 	Ùð	ús   �AA6ÁA6Á2A6Á6	BÂBc                 ó
  — |dk(  rt         }nt        › d|› d�}t        | |«      st        d|› d�d¬«       g S | j	                  dd	«      }g }|D ]²  }t        j                  d
|d   «      }|sŒ|j                  d«      t        |j                  d«      «      }}|d   xs d}	|	j                  d«      s$t        j                  j                  t        |	«      }	t        j                  d|	«      sŒŸ|j                  |	||f«       Œ´ |S )u;   Playwright æŠ“ä¸€é¡µåˆ—è¡¨, è¿”å›ž [(abs_url, title, date)]r   z /zwgk/bmxxgkml/xdgxq/tzgg/pages/z.htmlú[list] page=z FAILT©ÚflushÚlizàels => els.map(e => {
        const a = e.querySelector('a');
        const t = e.textContent.replace(/\s+/g,' ').trim();
        return a && t ? {t: t.slice(0, 120), h: a.getAttribute('href')} : null;
    }).filter(Boolean)z^(\d{4}-\d{2}-\d{2})\s*(.*)$r   é   Úhr   Úhttpzi\d+\.html$)ÚLIST_URLÚBASE_URLr7   ÚprintÚeval_on_selector_allr   ÚmatchÚgroupr   Ú
startswithÚurllibÚparseÚurljoinÚsearchÚappend)
r3   Úpage_nor4   ÚitemsÚoutÚitÚmÚdater1   r>   s
             r   Ú
fetch_listrR   X   s   € à�!‚|Ü‰ä�
Ð:¸7¸)À5ÐIˆÜ�t˜SÔ!Ü�˜W˜I UÐ+°4Õ8Øˆ	Ø×%Ñ% dð -ó €Eð
 €CØò 	)ˆÜ�H‰HÐ4°b¸±gÓ>ˆÙØØ—g‘g˜a“j¤+¨a¯g©g°a«jÓ"9ˆeˆØˆs‰GŠM�rˆØ�|‰|˜FÔ#Ü—‘×$Ñ$¤X¨qÓ1ˆAÜ�9‰9�^ QÕ'Ø�J‰J˜˜5 $Ð'Õ(ð	)ð €Jr   c           	      ó¢  — t         j                  j                  t        |«      }	 | j                  j                  |d¬«      }|j                  dk7  r!t        d|j                  › d|dd › �d¬	«       y
|j                  «       }t        |«      dk  ry
ddl
}ddl}|j                  |d¬«      }g }|D ]4  }	|	j                  «       j                  «       }
|
sŒ$|j                  |
«       Œ6 |j!                  «        dj#                  |«      S # t$        $ r<}t        dt'        |«      j(                  › dt+        |«      dd › �d¬	«       Y d}~y
d}~ww xY w)uB   ç”¨ Playwright request(å¸¦ç‘žæ•°cookie) ä¸‹è½½ PDF å¹¶æ��å�–æ–‡æœ¬iÈ¯  ©r+   éÈ   z    PDF status z: NéZ   Tr:   r   iô  r   Úpdf)ÚstreamÚfiletypeú
z    PDF err: r   éd   )rG   rH   rI   rA   ÚrequestÚgetÚstatusrB   ÚbodyÚlenÚfitzÚioÚopenÚget_textr   rK   ÚcloseÚjoinr2   ÚtypeÚ__name__Ústr)r3   Úpdf_relÚpdf_urlÚrespÚdatara   rb   ÚdocÚpartsr$   r   Úes               r   Úfetch_pdf_textrq   t   s&  € ä�l‰l×"Ñ"¤8¨WÓ5€GðØ�|‰|×Ñ °ÐÓ7ˆØ�;‰;˜#ÒÜ�O D§K¡K =°°7¸3¸B°<°.ÐAÈÕNØØ�y‰y‹{ˆÜˆt‹9�sŠ?ØÛÛØ�i‰i˜t¨eˆiÓ4ˆØˆØò 	 ˆAØ—
‘
“×"Ñ"Ó$ˆAÚØ—‘˜Q•ð	 ð 	�	‰	ŒØ�y‰y˜ÓÐøÜò Ü�œd 1›g×.Ñ.Ð/¨q´°Q³¸¸°°Ð?ÀtÕLÜûðús+   ¦AD	 Á3D	 ÂAD	 Ã3D	 Ä		EÄ2E	Å	Ec           	      óÂ  — t        | |«      sddddg fS 	 | j                  dd«      }|sddddg fS | j                  «       }d}t	        j
                  d|«      }|rt        |j                  d«      «      }d}t	        j
                  d|«      }|r|j                  d«      }|j                  d	«      r”t        | |d	   «      }t        |«      d
kD  r|||dg fS dt        j                  |«      › dt        j                  j                  t         |d	   «      › d�}	|||	dt        j                  j                  t         |d	   «      dfgfS t#        |d   d«      }
|
j%                  g d¢«      D ]  }|j'                  «        Œ |
j%                  d„ ¬«      D ]  }|j)                  «        Œ dD ](  }|
j+                  |«      D ]  }|j'                  «        Œ Œ* t-        |
j/                  d«      «      }g }|
j%                  dd¬«      D ]Â  }|d   j1                  «       }|j3                  d«      s|j3                  d«      r't        j                  j                  t         |«      |d<   |j5                  «       j7                  d«      sd|j5                  «       v sŒ‘t        |j9                  «       «      }|sŒ­|j;                  |d   |f«       ŒÄ |
j%                  dd¬«      D ]_  }|d    j1                  «       }|j3                  d«      s|j3                  d«      sŒ9t        j                  j                  t         |«      |d <   Œa t=        |
«      }	|||	||fS # t        $ r
 ddddg fcY S w xY w)!u8   è¿”å›ž (title, pubdate, content, has_table, attachments)NFz#div_contentzÍe => {
            const pdf = e.querySelector('.edui-pdf');
            return {
                pdf: pdf ? pdf.getAttribute('data-pdf') : null,
                html: e.innerHTML,
            };
        }r   z%name="ArticleTitle" content="([^"]*)"r   z+name="PubDate" content="(\d{4}-\d{2}-\d{2})rW   rU   z<p>z</p>
<p><a href="u)   " target="_blank">æŸ¥çœ‹åŽŸæ–‡PDF</a></p>u   æŸ¥çœ‹åŽŸæ–‡PDFÚhtmlzhtml.parser)ÚscriptÚstyleÚiframeÚobjectÚmetaÚlinkr1   c                 ó"   — t        | t        «      S )N)Ú
isinstancer   )Úss    r   ú<lambda>zparse_detail.<locals>.<lambda>·   s   € ¬J°q¼'Ó,B€ r   )Ústring)z#xgwdPz.xgwdPz.ewmz#qrcodeÚtableÚaT)Úhrefr�   ú/r?   )
z.pdfz.docz.docxz.xlsz.xlsxz.zipz.rarz.wpsz.jpgz.pngÚfileÚimg)Úsrcr…   )r7   Úeval_on_selectorr2   Úcontentr   rJ   r   rE   r]   rq   r`   r   ÚescaperG   rH   rI   rA   r   Úfind_allÚ	decomposeÚextractÚselectÚboolÚfindr   rF   ÚlowerÚendswithrd   rK   ri   )r3   r4   ÚinfoÚhdr1   ÚtmÚpubdateÚpmÚtxtr‡   ÚsoupÚtagÚcÚselr   Ú	has_tableÚattachmentsr€   r>   r„   r|   s                        r   Úparse_detailr�   Ž   s]  € ä�t˜SÔ!Ø�T˜4 ¨Ð*Ð*ð	+Ø×$Ñ$ ^ð 6ó ˆñ Ø�T˜4 ¨Ð*Ð*à	�‰‹€BØ€EÜ	�‰Ð;¸RÓ	@€BÙ	Ü˜BŸH™H Q›KÓ(ˆØ€GÜ	�‰ÐAÀ2Ó	F€BÙ	Ø—(‘(˜1“+ˆð ‡x�x�„Ü˜T 4¨¡;Ó/ˆÜˆs‹8�cŠ>à˜' 3¨¨rÐ1Ð1àœŸ™¨Ó.Ð/Ð/BÄ6Ç<Á<×CWÑCWÔX`ÐbfÐglÑbmÓCnÐBoð  p\ð  ]ˆØ�g˜w¨´·±×1EÑ1EÄhÐPTÐUZÑP[Ó1\Ð^oÐ0pÐ/qÐqÐqô ˜˜f™ }Ó5€DØ�}‰}Ò]Ó^ò ˆØ�‰�ðà�]‰]Ñ"Bˆ]ÓCò ˆØ	�	‰	�ðð 7ò ˆØ—‘˜SÓ!ò 	ˆAØ�K‰K�Mñ	ðô �T—Y‘Y˜wÓ'Ó(€IØ€KØ�]‰]˜3 Tˆ]Ó*ò 5ˆØˆf‰I�O‰OÓˆØ�<‰<˜Ô §¡¨VÔ 4ÜŸ™×,Ñ,¬X°qÓ9ˆAˆf‰IØ�7‰7‹9×ÑÐpÔqÐu{ð  @A÷  @Gñ  @Gó  @Iò  vIÜ˜aŸj™j›lÓ+ˆCÚØ×"Ñ" A f¡I¨sÐ#3Õ4ð5ð �}‰}˜U¨ˆ}Ó-ò ;ˆØ�‰J×ÑÓˆØ�<‰<˜Ô §¡¨VÕ 4ÜŸ™×-Ñ-¬h¸Ó:ˆC�ŠJð;ô �$‹i€GØ�'˜7 I¨{Ð:Ð:øôe ò +Ø�T˜4 ¨Ð*Ò*ð+ús   •M ÍMÍMc                 óš   — |s| S | j                  «       r| gng }|D ]  \  }}|j                  d|› d|› d�«       Œ dj                  |«      S )Nz<p><a href="z" target="_blank">z</a></p>z

)r   rK   rf   )r‡   rœ   ro   Úabs_urlr–   s        r   Úappend_attachmentsr    Ï   s[   € ÙØˆØ Ÿ™œˆW‰I¨b€EØ#ò N‰ˆ�Ø�‰�| G 9Ð,>¸s¸eÀ8ÐLÕMðNà�;‰;�uÓÐr   c                 ó°   — 	 | j                  dt        f«      }|j                  «       D �ch c]  }|d   ’Œ	 c}S c c}w # t        $ r t	        «       cY S w xY w)Nz.SELECT page_url FROM gov_raw WHERE site_name=?r   )ÚexecuteÚ	SITE_NAMEÚfetchallr2   Úset)ÚconnÚcurÚrows      r   Úload_existing_urlsr©   Ø   sN   € ðØ�l‰lÐKÌiÈ\ÓZˆØ"%§,¡,£.Ö1˜3��A“Ò1Ð1ùÒ1øÜò Ü‹uŠðús   ‚)? «:·? º? ¿AÁAc                 óž  — | j                  d|t        f«      }|j                  «       ry	 d}	 ddlm}  ||«      }| j                  d|||||t        t        t        ||f
«      }|j                  dkD  ryt        j                  dd|«      }	t        j                  |	«      }	t        j                  d	d
|	«      j                  «       d d }	| j                  d|j                  |t        |	f«       yy# t
        $ r Y Œ¼w xY w# t        j                   $ r=}
dt#        |
«      v r*t%        j&                  d«       t)        | |||||«      cY d }
~
S ‚ d }
~
ww xY w)Nz7SELECT id FROM gov_raw WHERE page_url=? AND site_name=?FÚotherr   )Úclassify_industryz¨INSERT OR IGNORE INTO gov_raw (page_url, source_url, title, content, publish_date, site_name, group_name, script_name, has_table, industry) VALUES (?,?,?,?,?,?,?,?,?,?)ú<[^>]+>r   r   r   rU   zTINSERT OR IGNORE INTO gov_search (rowid, title, site_name, summary) VALUES (?,?,?,?)TÚlockedr)   )r¢   r£   ÚfetchoneÚcrawler_libr¬   r2   Ú
GROUP_NAMEÚSCRIPT_NAMEÚrowcountr   r   r   r   r   Ú	lastrowidÚsqlite3ÚOperationalErrorri   ÚtimeÚsleepÚstore_record)r¦   r4   r1   r‡   rQ   r›   r§   Úindustryr¬   Úsummaryrp   s              r   r¹   r¹   à   sF  € Ø
�,‰,ÐPÐSVÔXaÐRbÓ
c€CØ
‡|�|„~ØðØˆð	Ý5Ù(¨Ó/ˆHð �l‰lð+ð �#�u˜g t¬Y¼
ÄKÐQZÐ\dÐeó	
ˆð �<‰<˜!ÒÜ—f‘f˜Z¨¨WÓ5ˆGÜ×'Ñ'¨Ó0ˆGÜ—f‘f˜V S¨'Ó2×8Ñ8Ó:¸4¸CÐ@ˆGØ�L‰LØfØ—‘ ¤y°'Ð:ôð Øøô# ò 	Ùð	ûô$ ×#Ñ#ò Ø”s˜1“vÑÜ�J‰J�qŒMÜ  c¨5°'¸4ÀÓKÕKØûð	úsF   «C< ®C- ¼B/C< Ã-	C9Ã6C< Ã8C9Ã9C< Ã<EÄ1EÅ EÅEÅEc                  óN  — d } t         sbt        j                  t        d¬«      } | j	                  d«       | j	                  d«       t        | «      }t        dt        |«      › d�d¬«       d	}d	}g }d	d
lm	}  |«       5 }t        |«      \  }}|j                  «       }	t        dt        dz   «      D �]š  }
t        |	|
«      }t        d|
› dt        |«      › �d¬«       |st        dd¬«        �n`|D �]W  \  }}}t         s
|v r|dz  }Œt        |	|«      \  }}}}}|€t        d|d d › d|› �d¬«       |dz  }ŒH|s|}|s|}t!        ||«      }t        t#        j$                  dd|«      j'                  «       «      }|dk  r"d|vr|st        d|d d › d|› �d¬«       |dz  }Œ±t         rC|j)                  |||||t*        t,        t.        dœ«       t        d|d d › d|› d�d¬«       |dz  }Œút1        | |||||«      }|r.|dz  }j3                  |«       t        d|d d › d|› d�d¬«       n|dz  }t5        j6                  t8        «       �ŒZ �Œ� |j;                  «        d d d «       t         rmt=        t         dd¬«      5 }|D ]+  }|j?                  tA        jB                  |d¬ «      d!z   «       Œ- 	 d d d «       t        d"t         › dt        |«      › d#�d¬«       | � | jE                  «        | j;                  «        t        d$|› d%|› �d¬«       y # 1 sw Y   Œ²xY w# 1 sw Y   ŒlxY w)&Né<   rT   zPRAGMA busy_timeout=60000zPRAGMA journal_mode=WALu
   å·²å…¥åº“ u    æ�¡, ç”¨äºŽåˆ—è¡¨çº§é¢„æŸ¥é‡�Tr:   r   )Úsync_playwrightr   r9   z items=zEmpty page, stop paginationz  skip empty: é   z | r­   r   é
   z<img)Úpage_urlr1   r‡   Úpublish_dater›   Ú	site_nameÚ
group_nameÚscript_namez
  JSONL + é(   z (ú)z  + Úwzutf-8)ÚencodingF)Úensure_asciirZ   zJSONL written: z rows)z[done] new=z skip=)#r   rµ   Úconnectr   r¢   r©   rB   r`   Úplaywright.sync_apir¾   r'   Únew_pager.   Ú_PAGESrR   r�   r    r   r   r   rK   r£   r±   r²   r¹   Úaddr·   r¸   ÚPAGE_INTERVALre   rc   ÚwriteÚjsonÚdumpsr*   )r¦   ÚexistingÚ	new_countÚ
skip_countÚ
jsonl_rowsr¾   r$   r%   r&   r3   rL   rM   rŸ   r1   rQ   ÚdtitleÚddater‡   r›   ÚattsÚ	plain_lenÚokÚfr¨   s                           r   ÚmainrÞ     sF  € Ø€DÝÜ�‰œw°Ô3ˆØ�‰Ð0Ô1Ø�‰Ð.Ô/Ü% dÓ+ˆÜ�
œ3˜x›=˜/Ð)GÐHÐPTÕUà€IØ€JØ€Jå3Ù	Ó	ð .˜aÜ˜a“‰ˆˆ3Ø�|‰|‹~ˆÜ˜Q¤¨¡
Ó+ó *	*ˆGÜ˜t WÓ-ˆEÜ�L  	¨´°U³°Ð=ÀTÕJÙÜÐ3¸4Õ@ÚØ(-ó $*Ñ$�˜ Ý! g°Ñ&9Ø !‘O�JØÜ:FÀtÈWÓ:UÑ7�˜˜w¨	°4Ø�>Ü˜N¨5°°"¨:¨,°c¸'¸ÐCÈ4ÕPØ !‘O�JØÙØ"�FÙØ �EÜ,¨W°dÓ;�Ü¤§¡ z°2°wÓ ?× EÑ EÓ GÓH�	Ø˜r’> f°GÑ&;ÁDÜ˜N¨6°#°2¨;¨-°s¸7¸)ÐDÈDÕQØ !‘O�JØÝØ×%Ñ%Ø$+°fÈØ(-¸IÜ%.¼jÜ'2ñ	'ô ô ˜J v¨c¨r { m°2°e°W¸AÐ>ÀdÕKØ ‘N�IØÜ! $¨°¸À%ÈÓS�ÙØ ‘N�IØ—L‘L Ô)Ü˜D ¨¨  ¨R°¨w°aÐ8ÀÖEà !‘O�JÜ—
‘
œ=Ö)òI$*ð*	*ðV 	
�‰Œ	÷].õ` Ü”*˜c¨GÔ4ð 	D¸Ø!ò D�Ø—‘œŸ
™
 3°UÔ;¸dÑBÕCñD÷	Dô 	�¤
˜|¨2¬c°*«oÐ->¸fÐEÈTÕRàÐØ�‰ŒØ�
‰
ŒÜ	ˆK˜	�{ &¨¨Ð
5¸TÖB÷s.ð .ú÷b	Dð 	Dús   Á>G LÉ>1LÌLÌL$Ú__main__)rÆ   )/Ú__doc__ÚsysÚosr   r·   rs   r   Úurllib.parserG   rµ   rÒ   Úbs4r   r   rA   r@   r£   r±   r²   Úenvironr]   r   r   r#   rÐ   Ú
_MAX_PAGESÚ	enumerateÚargvr6   r€   rF   ÚintÚsplitÚ
ValueErrorr`   rÎ   r   r'   r7   rR   rq   r�   r    r©   r¹   rÞ   rh   © r   r   ú<module>rí      s  ðñ	ó Û 	Û 	Û Û Û Û Û ç &ð #€ØÐ<Ñ<€Ø3€	Ø€
Ø!€Ø
�*‰*�.‰.˜Ð$5Ó
6€Ø�Z‰Z�^‰^˜L¨"Ó-€
àv€Ø€à€
Ù�c—h‘hÓò 
�D€A€qØ‡|�|�JÔð	Ù˜QŸW™W S¨!›_¨QÑ/Ó0‰Jð 
ˆi‹˜A ™E¡C¨¯©£MÓ1ð	Ù˜SŸX™X a¨!¡e™_Ó-‰Jð
ð " Q’‰¨A€òòóò ò8ò4>;òBòòòDGCðT ˆzÒÙ…Fð øðG	 ò 	Ùð	ûð
 ò 	Ùð	ús$   Â D,ÃD7Ä,D4Ä3D4Ä7D?Ä>D?