Ë
    nÖzj1/  ã                   óî  — 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
Z	dZdZej                  j                  d«      ZdZdZd„ Zd	„ Zdd
„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdd„Zedk(  r‡ddlZ ej<                  «       ZejA                  dd¬«       ejA                  de!d¬«       ejA                  dd¬«       ejE                  «       Z#e#jH                  r e«        y ee#jJ                  ¬«       yy)u—   
é�’å²›å¸‚ç”Ÿæ€�çŽ¯å¢ƒå±€ - å»ºè®¾é¡¹ç›®çŽ¯å¢ƒå½±å“�è¯„ä»·æ–‡ä»¶å�—ç�†æƒ…å†µå…¬ç¤º çˆ¬è™«
åˆ—è¡¨é¡µ: ASP.NET WebForms (postbackåˆ†é¡µ) + curlè¯¦æƒ…é¡µ
é    Nõ   é�’å²›å¸‚ç”Ÿæ€�çŽ¯å¢ƒå±€zAhttp://mbee.qingdao.gov.cn:8082/m2/ZWGKNew/webgs/list1.aspx?m=357z ~/gov_crawler/qingdao_results.dbzroot@1.94.217.116ú/root/search.dbc                  óœ   — t        j                  t        «      } | j                  d«       | j                  d«       | j	                  «        | S )Nz¹CREATE TABLE IF NOT EXISTS crawl_results (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT, url TEXT UNIQUE, content TEXT,
        publish_date TEXT, summary TEXT
    )zDELETE FROM crawl_results)Úsqlite3ÚconnectÚDB_PATHÚexecuteÚcommit)Úconns    ú"/root/gov_crawler/crawl_qingdao.pyÚinit_dbr      s>   € Ü�?‰?œ7Ó#€DØ‡L�Lð 	ô 
ð
 	‡L�LÐ,Ô-Ø‡K�K„MØ€Kó    c                 óD   — t        | xs d«      }|j                  dd«      S )NÚ ú'z'')ÚstrÚreplace)ÚvÚss     r   Úescr      s    € ÜˆAŠG�‹€AØ�9‰9�S˜$ÓÐr   c                 ót  — |rSt         j                  j                  |«      j                  «       }t         j                  j                  | |dddœ¬«      }n#t         j                  j                  | ddi¬«      }t         j                  j                  |d¬«      }|j                  «       j                  d	d
«      S )z%Fetch a page with optional POST data.z<Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36z!application/x-www-form-urlencoded)ú
User-AgentzContent-Type)ÚdataÚheadersr   )r   é   )Útimeoutzutf-8Úignore)	ÚurllibÚparseÚ	urlencodeÚencodeÚrequestÚRequestÚurlopenÚreadÚdecode)ÚurlÚ	post_dataÚbodyÚreqÚresps        r   Ú
fetch_pager,      s¢   € áÜ�|‰|×%Ñ% iÓ0×7Ñ7Ó9ˆÜ�n‰n×$Ñ$ S¨tØXØ?ñ>
Ð$ó ‰ô
 �n‰n×$Ñ$ SØÐXð3
Ð$ó ˆô �>‰>×!Ñ! #¨rÐ!Ó2€DØ�9‰9‹;×Ñ˜g xÓ0Ð0r   c                 ó  — t        j                  d| «      }t        j                  d| «      }t        j                  d| «      }|r|j                  d«      nd|r|j                  d«      nd|r|j                  d«      dœS ddœS )z+Extract ASP.NET hidden fields for postback.z__VIEWSTATE.*?value="([^"]*)"z#__EVENTVALIDATION.*?value="([^"]*)"z&__VIEWSTATEGENERATOR.*?value="([^"]*)"é   r   )Ú__VIEWSTATEÚ__EVENTVALIDATIONÚ__VIEWSTATEGENERATOR©ÚreÚsearchÚgroup)ÚhtmlÚvsÚevÚvsgs       r   Úextract_viewstater:   ,   sy   € ä	�‰Ð3°TÓ	:€BÜ	�‰Ð9¸4Ó	@€BÜ
�)‰)Ð=¸tÓ
D€Cá&(�r—x‘x ”{¨bÙ,.˜RŸX™X aœ[°BÙ03 §	¡	¨!£ñð ð :<ñð r   c                 óþ   — t        j                  d| t         j                  «      }|sg S |j                  d«      }t        j                  d|«      }|D ��cg c]  \  }}|j                  «       d|z   f‘Œ c}}S c c}}w )z*Extract project links from list page HTML.z%<div class="table-list">(.*?)</tbody>r.   zF<a[^>]*href="(/m2/webgs/list1detaile\.aspx\?n=[^"]+)"[^>]*>([^<]+)</a>zhttp://mbee.qingdao.gov.cn:8082)r3   r4   ÚDOTALLr5   ÚfindallÚstrip)r6   ÚareaÚ	list_htmlÚlinksÚhrefÚtitles         r   Úextract_linksrD   7   sr   € ô �9‰9Ð=¸tÄRÇYÁYÓO€DÙØˆ	à—
‘
˜1“€IÜ�J‰JØQØó€Eð Z_×_É+È$ÐPUˆU�[‰[‹]Ð=ÀÑDÒEÓ_Ð_ùÓ_s   ÁA9c           
      ó®  — t        j                  d| t         j                  «      }|sy|j                  d«      }t        j                  d|t         j                  «      }g }d}|D �]ˆ  }t        j                  d|t         j                  «      }|sŒ,t        t        j                  d|«      «      }g }	g }
t        |«      D �]r  \  }}t        j                  d|«      }t        j                  d	d|«      }|rod
|j                  d«      › d|j                  d«      › d�}t        j                  dd|«      }t        j                  dd|«      }t        j                  dd|«      }|}ntt        j                  dd|«      }|j                  dd«      }|j                  dd«      }|j                  dd«      }t        j                  dd|«      j                  «       }|}|rG|	j                  |«       |
j                  |j                  d«      › d|j                  d«      › �«       �Œb|	j                  |«       �Œu |r‘|	r|	d   nd}t        |	«      dkD  r|	dd ng }t        |«      dk\  r8|d   }|d   }|j                  d«      |z   }|j                  d|› d|› d�«       �Œ6t        |«      dk(  s�ŒF|j                  d|› d|d   › d�«       �Œct        |	«      dk\  ré|	d   }|	d   }d}|D ]S  }t        j                  d|«      }|sŒd
|j                  d«      › d|j                  d«      › d|j                  d«      › �}ŒU |rPst        j                  dd«      nd}|rt        j                  dd|«      nd}|j                  d|› d|› d�«       �Œ'|r|j                  d|› d|› d�«       �ŒC|j                  d|› d�«       �ŒZt        |	«      dk(  s�Œj|	d   s�Œq|j                  d|	d   › d�«       �Œ‹ dj                  |«      }|j                  dd «      }t        j                  dd|«      }t        j                  dd|«      j                  «       dd! }||fS )"zqExtract content from the detail page table.
    Returns (content_html, summary_text) - content is HTML formatted.z0<div class="table-detail[^>]*>(.*?)</div>\s*<div)r   r   r.   z<tr>(.*?)</tr>r   z<td[^>]*>(.*?)</td>Úrowspanz&<a[^>]*href="([^"]+)"[^>]*>([^<]+)</a>z	<br\s*/?>z	<a href="z">é   z</a>z<a[^>]*>.*?</a>z<[^>]+>z\s+z&nbsp;ú õ   Â z&amp;ú&u    â†’ r   Nu   ï¼šz<div class="cl">z</div>u	   </a> â†’ u    ï¼ˆç©ºï¼‰</div>ú
u   ï¼ˆç©ºï¼‰â†’u	   ï¼ˆç©ºï¼‰éô  )r3   r4   r<   r5   r=   ÚboolÚ	enumerateÚsubr   r>   ÚappendÚlenÚrstripÚjoin)r6   Úcontent_divÚ
table_htmlÚrowsÚ
html_linesÚrowspan_labelÚrowÚcellsÚhas_rowspanÚcleaned_labelsÚcleaned_valuesÚciÚcÚ	pdf_matchÚc_no_brÚa_tagÚrestÚcleanedÚc_cleanÚ	remainingÚ	sub_labelÚvalueÚcombined_labelÚlabelÚpdf_textÚpmÚ	pdf_valueÚcontent_htmlÚsummary_texts                                r   Úextract_contentrp   E   sR  € ô —)‘)Ø;ØŒb�i‰ió€Kñ Øà×"Ñ" 1Ó%€Jô �:‰:Ð'¨´R·Y±YÓ?€Dà€JØ€Màó KPˆä—
‘
Ð1°3¼¿	¹	ÓBˆÙØäœ2Ÿ9™9 Z°Ó5Ó6ˆàˆØˆä˜uÓ%ó 	/‰EˆB�äŸ	™	Ð"KÈQÓOˆIô —f‘f˜\¨2¨qÓ1ˆGáà# I§O¡O°AÓ$6Ð#7°r¸)¿/¹/È!Ó:LÐ9MÈTÐR�Ü—v‘vÐ0°"°gÓ>�Ü—v‘v˜j¨"¨dÓ3�Ü—v‘v˜f b¨$Ó/�Ø‘ô Ÿ&™& ¨R°Ó9�Ø!Ÿ/™/¨(°CÓ8�Ø!Ÿ/™/¨&°#Ó6�Ø!Ÿ/™/¨'°3Ó7�ÜŸ&™& ¨¨WÓ5×;Ñ;Ó=�Ø!�áØ×%Ñ% gÔ.à×%Ñ%¨¯©¸Ó);Ð(<¸EÀ)Ç/Á/ÐRSÓBTÐAUÐ&VÖWà×%Ñ% gÖ.ð9	/ñ> Ù1?˜N¨1Ò-ÀRˆMÜ.1°.Ó.AÀAÒ.E˜ q rÑ*È2ˆIÜ�9‹~ Ò"Ø% a™L�	Ø! !™�à!.×!5Ñ!5°eÓ!<¸yÑ!H�Ø×!Ñ!Ð$4°^Ð4DÀAÀeÀWÈFÐ"SÖTÜ�Y“ 1Ô$Ø×!Ñ!Ð$4°]°OÀ1ÀYÈqÁ\ÀNÐRXÐ"YÖZä�>Ó" aÒ'Ø& qÑ)�Ø& qÑ)�à�Øò b�AÜŸ™Ð#LÈaÓP�BÚØ%.¨r¯x©x¸«{¨m¸2¸b¿h¹hÀq»k¸]È)ÐTV×T\ÑT\Ð]^ÓT_ÐS`Ð#a™ðbñ
 ñ HQ¤§¡ z°2°wÔ ?ÐVX�IÙAJ¤§¡ v¨r°9Ô =ÐPR�IØ×%Ñ%Ð(8¸¸¸qÀÀ
È&Ð&QÖRÙØ×%Ñ%Ð(8¸¸¸qÀÀÀvÐ&NÖOà×%Ñ%Ð(8¸¸Ð?OÐ&PÖQÜ�^Ó$¨Ô)¨n¸QÔ.?Ø×!Ñ!Ð$4°^ÀAÑ5FÐ4GÀvÐ"NÖOðWKPðZ —9‘9˜ZÓ(€LØ×'Ñ'¨¸ÓD€Lô —6‘6˜* b¨,Ó7€LÜ—6‘6˜& # |Ó4×:Ñ:Ó<¸T¸cÐB€Là˜Ð%Ð%r   c                 óš   — t        j                  d| t         j                  «      }|r#|j                  d«      j	                  «       }|r|S |S )z[Extract full project name from detail page.
    Falls back to list page title if not found.u0   é¡¹ç›®å��ç§°ï¼š</td>\s*<td[^>]*>\s*(.*?)\s*</td>r.   )r3   r4   r<   r5   r>   )r6   Ú
list_titleÚmÚ
full_titles       r   Úextract_titleru   ®   sC   € ô 	�	‰	ÐEÀtÌRÏYÉYÓW€AÙØ—W‘W˜Q“Z×%Ñ%Ó'ˆ
ÙØÐØÐr   c                 óú   — t        j                  d| «      }|r7|j                  d«      › d|j                  d«      › d|j                  d«      › �S t        j                  d| «      }|r|j                  d«      dd S y	)
z&Extract publish date from detail page.u0   id="slsj"[^>]*>\s*(\d{4})å¹´(\d{2})æœˆ(\d{2})æ—¥r.   ú-rG   é   zPubDate[^>]*content="([^"]+)"Né
   r   r2   )r6   ÚdÚd2s      r   Úextract_pub_dater|   ¸   ss   € ô 	�	‰	ÐEÀtÓL€AÙØ—'‘'˜!“*�˜Q˜qŸw™w q›z˜l¨!¨A¯G©G°A«J¨<Ð8Ð8ä	�‰Ð3°TÓ	:€BÙ	Ø�x‰x˜‹{˜3˜BÐÐØr   c                  ó  — t        d«       t        j                  t        «      } | j	                  d«      j                  «       }| j                  «        |st        d«       yt        j                  d«      }|j	                  d«       d}d}|D ]J  }|\  }}}}	}
	 |j	                  d	|||xs d
dd |	xs d
|
xs d
dd |d
f«       |j                  dkD  r|dz  }ŒL |dkD  r3|j                  «        |j	                  d|f«       |j                  «        |j	                  d|f«      j                  «       d   }|j                  «        t        d|› dt        |«      › d|› d�«       y# t        $ r}t        d|› �«       Y d}~Œôd}~ww xY w)u@   å°†æœ¬åœ°æ•°æ�®ç›´æŽ¥å†™å…¥ search.dbï¼ˆæœ�åŠ¡å™¨æœ¬åœ°æ¨¡å¼�ï¼‰u   
ðŸ“¤ å�Œæ­¥åˆ° search.db...zPSELECT title, url, content, publish_date, summary FROM crawl_results ORDER BY idu     æœ¬åœ°æ²¡æœ‰æ•°æ�®Nr   zPRAGMA journal_mode=WALr   r   zwINSERT OR IGNORE INTO gov_raw (title, page_url, content, publish_date, summary, site_name, tags) VALUES (?,?,?,?,?,?,?)r   i ¡ i,  r.   z	  Error: z±INSERT INTO gov_search(rowid,title,site_name,summary) SELECT r.id,r.title,r.site_name,r.summary FROM gov_raw r WHERE r.id NOT IN (SELECT rowid FROM gov_search) AND r.site_name=?z.SELECT COUNT(*) FROM gov_raw WHERE site_name=?z  OK ú/u    æ�¡å�Œæ­¥åˆ° search.db (DBå…±u   æ�¡))Úprintr   r   r   r	   ÚfetchallÚcloseÚtotal_changesÚ	Exceptionr
   ÚfetchonerQ   )r   rV   ÚdstÚ	site_nameÚ	new_countÚrrC   r'   ÚcontentÚpub_dateÚsummaryÚeÚtotals                r   Úsync_to_serverrŽ   Ä   s™  € ä	Ð
)Ô*ä�?‰?œ7Ó#€DØ�<‰<ÐjÓk×tÑtÓv€DØ‡J�J„LáÜÐ$Ô%Øä
�/‰/Ð+Ó
,€CØ‡K�KÐ)Ô*à*€IØ€IØò #ˆØ12Ñ.ˆˆs�G˜X wð	#Ø�K‰Kð)ð ˜˜gšm¨¨W¨fÐ5°x²~À2Ø’-˜R  #Ð&¨	°2ð7ô	ð × Ñ  1Ò$Ø˜Q‘�	øð#ð �1‚}Ø�
‰
Œà�‰ðQð ˆLô		ð
 	�
‰
Œà�K‰KØ8¸9¸,óHßHPÉË
ÐSTñV€Eà‡I�I„Kä	ˆE�)�˜Aœc $›i˜[Ð(FÀuÀgÈTÐ
RÕSøô# ò 	#Ü�I˜a˜S�/×"Ñ"ûð	#ús   Â?E&Å&	FÅ/FÆFc           
      óò  ‡— t        «       }ddddœ}g }t        d«       t        t        «      }t	        |«      }t        |«      }|j                  |«       t        dt        |«      › d�«       | rt        |«      | k  r…t        |«      }d|d<   d|d	<   t        d
«       t        t        |«      }t        |«      }	|	D ]-  \  }
Št        ˆfd„|D «       «      rŒ|j                  |
‰f«       Œ/ t        dt        |	«      › d�«       t        dt        |«      › d�«       t        |«      D ]´  \  }\  }
Š| dkD  r|| k\  r n¢	 t        ‰«      }t        |«      \  }}t        |«      }t        ||
«      }|j                  d|d d ‰|||f«       |j!                  «        t        |xs d«      }t        d|› d|d d › �«       |dxx   dz  cc<   t'        j(                  d«       Œ¶ |j+                  «        t        dd› �«       t        d|d   › d|d    › d!|d   › �«       |d   dkD  rt-        «        y t        d"«       y # t"        $ r7}t        dt%        |«      d d › d|
d d › �«       |dxx   dz  cc<   Y d }~Œ¬d }~ww xY w)#Nr   )ÚnewÚskipÚerrorsu   ðŸ“ƒ ç¬¬1é¡µu     ðŸ“„ æ��å�– u    æ�¡z!ctl00$right_content$Pagination$pgÚ__EVENTTARGETÚ2Ú__EVENTARGUMENTu   ðŸ“ƒ ç¬¬2é¡µc              3   ó.   •K  — | ]  \  }}‰|k(  –— Œ y ­w©N© )Ú.0Ú_Úur'   s      €r   ú	<genexpr>zcrawl.<locals>.<genexpr>  s   øè ø€ Ò6¡D A q�s˜a•xÑ6ùs   ƒu   
ðŸ“„ å…±æ��å�– u%    æ�¡é“¾æŽ¥ï¼Œå¼€å§‹æŠ“å�–è¯¦æƒ…é¡µ...zcINSERT OR IGNORE INTO crawl_results (title, url, content, publish_date, summary) VALUES (?,?,?,?,?)rL   r   u     âœ… zB | é2   r�   r.   u     â�Œ é<   z | é(   r’   g333333Ó?rK   z2==================================================u   ðŸ�� æ–°å¢ž:u    è·³è¿‡:r‘   u    é”™è¯¯:u"   âš ï¸� æ— æ–°æ•°æ�®ï¼Œè·³è¿‡å�Œæ­¥)r   r   r,   ÚLIST_URLr:   rD   ÚextendrQ   ÚdictÚanyrP   rN   rp   r|   ru   r	   r
   rƒ   r   ÚtimeÚsleepr�   rŽ   )Ú
test_limitr   ÚstatsÚ	all_linksr6   Ú	viewstaterA   r(   Úhtml2Úlinks2rC   Úidxr‰   r‹   rŠ   rt   ÚsizerŒ   r'   s                     @r   Úcrawlr®   õ   sŒ  ø€ Ü‹9€DØ˜q¨AÑ.€EØ€Iô 
ˆ.ÔÜ”hÓ€DÜ! $Ó'€IÜ˜$Ó€EØ×Ñ�UÔÜ	ˆNœ3˜u›:˜, dÐ
+Ô,ñ œ˜Y›¨*Ò4ä˜“Oˆ	Ø%Hˆ	�/Ñ"Ø'*ˆ	Ð#Ñ$äˆnÔÜœ8 YÓ/ˆÜ˜uÓ%ˆà ò 	/‰JˆE�3ÜÓ6¨IÔ6Õ6Ø× Ñ  %¨ Õ.ð	/ô 	�œs 6›{˜m¨4Ð0Ô1ä	Ðœc )›nÐ-Ð-RÐ
SÔTä& yÓ1ò Ñˆ‰\ˆe�SØ˜Š>˜c ZÒ/Ùð	!Ü˜c“?ˆDä.¨tÓ4ÑˆG�WÜ'¨Ó-ˆHÜ& t¨UÓ3ˆJà�L‰LØuØ˜D˜SÐ! 3¨°¸7ÐCôð �K‰KŒMä�w’} "Ó%ˆDÜ�F˜4˜&  Z°° _Ð$5Ð6Ô7Ø�%‹L˜AÑ‹Lô 	�
‰
�3�ð1ð4 	‡J�J„Lä	ˆBˆvˆhˆ-ÔÜ	ˆL˜˜u™˜ h¨u°V©}¨o¸XÀeÈHÁoÐEVÐ
WÔXàˆU�|�aÒÜÕäÐ2Õ3øô ò 	!Ü�Fœ3˜q›6 # 2˜;˜- s¨5°°"¨:¨,Ð7Ô8Ø�(‹O˜qÑ �OˆOûð	!ús   Ä;B
H6È6	I6È?-I1É1I6Ú__main__z--fullÚ
store_true)Úactionz--test)ÚtypeÚdefaultz--sync)r¦   r—   )r   )&Ú__doc__ÚjsonÚosr3   r   Ú
subprocessÚsysr¤   Úurllib.parser   Úurllib.requestÚ	SITE_NAMEr    ÚpathÚ
expanduserr   Ú
SERVER_SSHÚSERVER_SEARCH_DBr   r   r,   r:   rD   rp   ru   r|   rŽ   r®   Ú__name__ÚargparseÚArgumentParserÚparserÚadd_argumentÚintÚ
parse_argsÚargsÚsyncÚtestr˜   r   r   ú<module>rÊ      s  ðñ÷ R× Q× Q× QÓ Qà&€	ØN€Ø
�'‰'×
Ñ
Ð?Ó
@€Ø €
Ø$Ð ò	ò ó1ò	ò`òf&òRò
ò.TóbB4ðH ˆzÒÛØ$ˆX×$Ñ$Ó&€FØ
×Ñ˜¨ÐÔ6Ø
×Ñ˜ s°AÐÔ6Ø
×Ñ˜¨ÐÔ6Ø×ÑÓ€Dà‡y‚yÙÕá˜Ÿ™Ö#ð r   