
    <|j                    x   d Z ddlmZ ddlZddlmZ ddlmZ ddlmZm	Z	m
Z
mZ ddlmZ ddlmZmZ dd	lmZ  ej(                  d
ej*                        Z ej(                  dej*                        Z ej(                  d      Z ed      Z ed       G d d             ZddZddZddZddZddZddZ y)u2   论坛主题列表解析 - 复用自 pm001-crawler    )annotationsN)	dataclass)datetime)parse_qsunquoteurljoinurlparse)ZoneInfo)BeautifulSoupTag)parserzdispbbs\.asp\?zdispuser\.asp\?z0\d{4}/\d{1,2}/\d{1,2}\s+\d{1,2}:\d{2}(?::\d{2})?zAsia/ShanghaiT)slotsc                  ^    e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   d	ed
<   ded<   y)
TopicEntryinttopic_idboard_idstrtitleurl
author_keyauthor_name
str | Noneprofile_urlr   last_update_timeN)__name__
__module____qualname____annotations__     %/opt/daily-market/src/forum_topics.pyr   r      s-    MMJ	HOr!   r   c                   t        | d      }g }t               }|j                  dt              D ]  }t	        |j                  dd            }|||v r&|j                  dd      }d	j                  |j                        j                         }	|	r|	d
v ri|t        j                  |	      r||j                  dd      t        ||n|      }
|
|
j                  dd      }t        |      }|t        |
||      \  }}}|r|s|j!                  |       |j#                  t%        |||	t'        ||d         ||||             " |S )u<   从板块列表页解析主题条目和对应作者信息。lxmlahrefr'    div	listtitle)class_ >      打印   树形list_s
Tstrip)r   r   r   r   r   r   r   r   )r   setfind_allTOPIC_LINK_PATTERNextract_topic_idgetfind_parentjoinstripped_stringsr2   DATE_PATTERN	fullmatchfind_topic_containerget_textparse_last_updateextract_authoraddappendr   r   )htmlr   base_urlsouptopicsseen_topic_idsanchorr   title_containerr   	containerrow_textlast_updater   r   r   s                   r"   parse_topic_listrM   "   s~   v&D!F"uN--*<-= '
#FJJvr$:;x>9 ,,U;,G001779!55"|'='=e'D"v'9'9%'9'Q'](?3JP_`	%%d$%7'1/=iQY/Z,
K8$!!HfVn5%''!,		
9'
R Mr!   c                    t        t        |       j                        }|j                  d      xs |j                  d      }|sy	 t	        |d         S # t
        $ r Y yw xY w)u$   从主题链接中提取主题 ID。IDidNr   )r   r	   queryr7   r   
ValueError)r'   rQ   valuess      r"   r6   r6   T   s[    Xd^))*EYYt_/		$F6!9~ s   A 	A! A!c                   t         j                  |       }|sy	 t        j                  |d         }|j                  |j                  t              }|j                  t              S # t        t
        t        f$ r Y yw xY w)u-   从文本中解析主题最后更新时间。N)tzinfo)r;   findalldate_parserparserR   	TypeErrorOverflowErrorrV   replaceASIA_SHANGHAI
astimezone)textmatchesvalues      r"   r?   r?   `   sy    ""4(G!!'"+. ||]3M**	 	=1 s   A) )B ?B c                |   | }|`|j                  dg       }|j                  dk(  rt        d |D              r|S t        |j                  t
              r|j                  nd}|`dD ]S  }| j                  |      }|t        |j                  dd            t        | j                  dd            kD  sQ|c S  y)	uT   定位主题条目对应的容器节点，便于提取更新时间和作者信息。Nclassr)   c              3  $   K   | ]  }|d v  
 yw)>   listlist_r1Nr    ).0names     r"   	<genexpr>z'find_topic_container.<locals>.<genexpr>s   s     (Y1D)D(Ys   )trtabler)   lir,   Tr1   )	r7   rh   any
isinstanceparentr   r8   lenr>   )rH   currentclassesrh   rJ   s        r"   r=   r=   n   s    G

++gr*<<5 S(YQX(Y%YN$.w~~s$C'..	 
 - &&t,	 S););Ct);)L%MPSTZTcTcdgosTcTtPu%u r!   c           	     L   | j                  dd      D cg c]  }| }}t        fdt        |      D        d      }||d| n|}|D cg c]*  }t        j	                  |j                  dd            s)|, }}|s5|D cg c]*  }t        j	                  |j                  dd            s)|, }}|sy|d	   }d
j                  |j                        j                         }	|j                  dd      }
t        |
      }|r|	sy||	t        ||
      fS c c}w c c}w c c}w )uK   从主题容器中提取作者名称、作者标识和作者主页链接。r%   Tr&   c              3  2   K   | ]  \  }}|u s|  y w)Nr    )rg   idxitemtopic_anchors      r"   ri   z!extract_author.<locals>.<genexpr>   s     X	T4<CWXs   Nr'   r(   )NNNr   r,   )r4   next	enumerateAUTHOR_LINK_PATTERNsearchr7   r9   r:   r2   extract_author_keyr   )rJ   rw   rD   r%   anchorstopic_index
candidatesauthor_linksauthor_anchorrh   r'   keys    `          r"   r@   r@   ~   s    #,,St,<=Qq=G=XYw-?XZ^_K*5*A+&wJ)[!-@-G-GfVXHY-ZA[L[#*\a.A.H.HvWYIZ.[\\ OM88M22399;DVR(D
T
"Cdgh--- > \\s   	D*D8D*D!/D!c                    t        t        |       j                        }d|v r|d   rd|d   d    S d|v r|d   rdt        |d   d          S y)u-   从作者链接中提取作者唯一标识。rP   zid:r   rh   zname:N)r   r	   rQ   r   )r'   rQ   s     r"   r|   r|      se    Xd^))*Eu}tU4[^$%%5=wuV}Q/0122r!   )rC   r   r   r   rD   r   returnzlist[TopicEntry])r'   r   r   z
int | None)r_   r   r   zdatetime | None)rH   r   r   z
Tag | None)rJ   r   rw   r   rD   r   r   z)tuple[str | None, str | None, str | None])r'   r   r   r   )!__doc__
__future__r   redataclassesr   r   urllib.parser   r   r   r	   zoneinfor
   bs4r   r   dateutilr   rX   compile
IGNORECASEr5   rz   r;   r]   r   rM   r6   r?   r=   r@   r|   r    r!   r"   <module>r      s    8 " 	 !  = =  " *  RZZ 12==A  bjj!3R]]C rzzMN)   /d	+ .(r!   