o
    +m)i@k                     @   s   d dl Z e jd d dlm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 d dlmZ G dd deZedkrJd dlmZ ee  dS dS )	    Nz..)Spider)etree)urljoinc                   @   s   e Zd Zdd Zd1ddZdd Zd2d	d
Zdd Zdd Zdd Z	dd Z
dd Zd3ddZdd Zdd Zdd Zdd Zd4d!d"Zd5d#d$Zd%d& Zd'd( Zd)d* Zd+d, Zd6d/d0Zd S )7r   c                 C   s   dS )Nu   苹果视频 selfr   r   &   /storage/emulated/0/lz/py/sy/七区.pygetName      zSpider.getName c                 C   sB   d| _ d| _ddddd| j d| _g d	| _| d
| j   d S )Nzhttps://618636.xyzzhttps://h5.xxoo168.orgzsMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36zJtext/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8zzh-CN,zh;q=0.9,en;q=0.8zgzip, deflatez
keep-alive)z
User-AgentAcceptzAccept-LanguagezAccept-Encoding
ConnectionReferer)3743404944413945423866464847u,   苹果视频爬虫初始化完成，主站: )hostapi_hostheadersspecial_categorieslog)r   extendr   r   r   init   s   
	zSpider.initc                 C   s$   zt |W S    | d Y dS )u(   将HTML内容转换为可查询的对象u   HTML解析失败N)r   HTMLr!   )r   contentr   r   r   html"   s
   
zSpider.html   c                 C   sJ   zt ||t j}|rt| |kr||W S W dS W dS    Y dS )u   正则表达式提取字符串r   )research
IGNORECASElengroupsgroup)r   patternstringindexmatchr   r   r   regStr*   s   zSpider.regStrc                 C      d S Nr   )r   urlr   r   r   isVideoFormat4   r
   zSpider.isVideoFormatc                 C   r3   r4   r   r   r   r   r   manualVideoCheck7   r
   zSpider.manualVideoCheckc                 C   s@  i }ddddddddddd	dd
dddddddddddddddddddddddddddddg}||d< z>| j | j| jd}|rQ|jd kr]| d! g |d"< |W S | |j}|sq| d# g |d"< |W S | j|d$d%}||d"< W |S  ty } z| d&t	|  g |d"< W Y d'}~|S d'}~ww )(u   获取首页内容和分类618636.xyz_37   国产AVtype_id	type_name618636.xyz_43   探花AV618636.xyz_40   网黄UP主618636.xyz_49   绿帽淫妻618636.xyz_44   国产传媒618636.xyz_41	   福利姬618636.xyz_39   字幕618636.xyz_45	   水果派618636.xyz_42   主播直播618636.xyz_38   欧美618636.xyz_66FC2618636.xyz_46   性爱教学618636.xyz_48	   三及片618636.xyz_47   动漫classr      u   首页请求失败listu   首页HTML解析失败   limitu   首页获取出错: N)
fetchr   r   status_coder!   r&   text_get_videos	Exceptionstr)r   filterresultclassesrspdocvideoser   r   r   homeContent:   sJ   


zSpider.homeContentc                 C   sx   ddddddddddd	d
dddddddddddddddddddddddddddddddgiS )u   分类定义 - 兼容性方法rW   r8   r9   r:   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   r   r   r   r   r   homeVideoContentd   s"   zSpider.homeVideoContentc              
   C   s  z| d\}}d| d| d}|r!|dkr!|dd| d}| d|  | j|| jd}|r8|jd	krB| d
 dg iW S | |j}	|	sT| d dg iW S | j|	|dd}
d}d}|		d}|rz1d}|D ]*}d|jv szd|j
 v r|	dd }td|}|rt|d}|d } nqlW n   Y |
t||d|dW S  ty } z| dt|  dg iW  Y d}~S d}~ww )u   分类内容 - 修复版_https://z/index.php/vod/type/id/.html1/page/u   访问分类URL: rX   rY   u   分类页面请求失败rZ   u   分类页面HTML解析失败r[   )category_idr]      d   z//ul[@class="pagination"]/li/aNu   尾last./@hrefr   z/page/(\d+)\.htmlr'   rZ   page	pagecountr]   totalu   分类内容获取出错: )splitreplacer!   r^   r   r_   r&   r`   ra   xpathlowerr(   r)   intr-   rb   rc   )r   tidpgrd   r"   domainr;   r5   rg   rh   ri   ry   rz   Zpage_elements	last_pageelemhrefZ
page_matchrj   r   r   r   categoryContenty   sV   




zSpider.categoryContentrp   c              
   C   s   zY| j  dtj| d| d}| d|  | j|| jd}|r(|jdkr2| d dg iW S | |j	}|sD| d	 dg iW S | j
|d
d}d}d}	|t||d
|	dW S  tyy }
 z| dt|
  dg iW  Y d}
~
S d}
~
ww )u   搜索功能 - 修复版z/index.php/vod/search/wd/rq   ro   u   搜索URL: rX   rY   u   搜索请求失败rZ   u   搜索页面解析失败r[   r\   rs   rt   rw   u   搜索出错: N)r   urllibparsequoter!   r^   r   r_   r&   r`   ra   r   rb   rc   )r   keyquickr   
search_urlrg   rh   ri   ry   rz   rj   r   r   r   searchContent   s2    



zSpider.searchContentc              
   C   s   z|d }| drr|d}t|dkrr|d }|d }d|dd }tj|}| d	|  tj|}tj	|j
}	|	d
dgd }
|	ddgd }|	ddgd }| |}d|||dddd| dgiW S d|v rt|ddkr|d\}}}n|d\}}d| d| d}| d|  | j|| jd}|r|jdkr| d dg iW S | |j}|s| d dg iW S | ||j|}|rd|giW S dg iW S  ty } z| dt|  dg iW  Y d}~S d}~ww )u   详情页面 - 修复版r   special_rm      r'         N)   特殊分区视频，直接使用链接: vr   bmrZ   u   直接播放   第1集$)vod_idvod_namevod_picvod_remarksvod_yearvod_play_fromvod_play_urlrn   z/index.php/vod/detail/id/ro   u   访问详情URL: rX   rY   u   详情页面请求失败u   详情页面HTML解析失败u   详情获取出错: )
startswithr{   r+   joinr   r   unquoter!   urlparseparse_qsqueryget_decrypt_titler^   r   r_   r&   r`   _get_detailrb   rc   )r   idsvidpartsrr   video_idencoded_urlplay_url
parsed_urlquery_params	video_urlZpic_urltitle_encryptedtitler   Z
detail_urlrg   rh   
video_inforj   r   r   r   detailContent   s\   






zSpider.detailContentc              
   C   s  z|  d| d|  |drx|d}t|dkrx|d }|d }d|dd	 }tj|}|  d
|  tj|}	tj	|	j
}
|
ddgd }|rx|dr^d| }n|dsit| j|}|  d|  dd|dW S |dr|  d tj|}	tj	|	j
}
|
ddgd }|s|
D ]}|dv r|
| d } nq|rtj|}|drd| }n|dst| j|}|  d|  dd|dW S |  d | j|| jd}|r|jdkr| |j}|r|  d|  dd|dW S |  d dd|dW S |ddkr(|d}|d }|d }n	|dd }d}|  d| d|  || jv r|  d | j d| d }| j|| jd}|ry|jdkry| |j}|ry|  d!|  dd|dW S |  d" | ||W S |  d# | ||W S  ty } z3|  d$t|  d|v r|d\}}d%| d&| }n| j d&| }dd|dW  Y d	}~S d	}~ww )'u   播放链接 - 修复版u   获取播放链接: flag=z, id=r   rm   r   r'   r   r   Nr   r   r   r   //https:httpu)   从特殊链接中提取到视频地址: r   playUrlr5   u*   ID 是一个完整URL，直接解析参数)r5   srcfileu(   从 URL 参数中提取到视频地址: u7   URL 中没有找到视频参数，尝试从页面提取rX   rY   u    从页面提取到视频地址: u3   无法从页面提取视频链接，返回原始URLu
   视频ID: u   , 分类ID: u9   特殊分类，尝试从详情页提取直接播放链接z/index.php/vod/play/id/ro   u&   从播放页面提取到视频地址: u-   从播放页面提取失败，尝试API方式u!   使用API方式获取视频地址u   播放链接获取出错: rn   /html/kkyd.html?m=)r!   r   r{   r+   r   r   r   r   r   r   r   r   r   r   r^   r   r_   _extract_direct_video_urlr`   countr    _get_video_by_apirb   rc   )r   flagidvipFlagsr   rr   r   r   r   r   r   r   r   rg   play_page_urlrj   r   play_idr   r   r   playerContent  s   
















zSpider.playerContentc              
   C   s  z| j  d| }| d|  | j }|| j d| jdd | j||d}|rw|jdkrw| }| d|  |	d	d
krP|	di 	dd}n
|	di 	dd}|rq|
dd}| d|  dd|dW S | d n| d|r|jnd  d|v r|d\}}	d| d|	 }
n| j d| }
| d|
  dd|
dW S  ty } z2| dt|  d|v r|d\}}	d| d|	 }
n| j d| }
dd|
dW  Y d}~S d}~ww )u   通过API获取视频地址z/api/v2/vod/reqplay/u   请求API获取视频地址: /ZXMLHttpRequest)r   OriginzX-Requested-WithrX   rY   u   API响应: retcoder   dataZhttpurl_previewr   Zhttpurlz?300u   从API获取到视频地址: r   r   u$   API响应中没有找到视频地址u   API请求失败，状态码: u	   无响应rm   rn   r   u)   API请求失败，回退到播放页面: r'   u   API方式获取视频出错: N)r   r!   r   copyupdater   r^   r_   jsonr   r|   r{   rb   rc   )r   r   r   Zapi_urlZapi_headersZapi_responser   r   r   r   r   rj   r   r   r   r   u  sJ   

zSpider._get_video_by_apic              
   C   s   zDg d}|D ]:}t ||t j}|D ]-}t|tr|d }|dd}tj|}|	dr4d| }q|	dr@|    W S qqW dS  t
ya } z| d	t|  W Y d}~dS d}~ww )
u(   从HTML内容中提取直接播放链接)zv=([^&]+\.(?:m3u8|mp4))z-"url"\s*:\s*["\']([^"\']+\.(?:mp4|m3u8))["\']z+src\s*=\s*["\']([^"\']+\.(?:mp4|m3u8))["\']zhttp[^\s<>"\'?]+\.(?:mp4|m3u8)r   \r   r   r   r   Nu   提取直接播放URL出错: )r(   findallr*   
isinstancetupler|   r   r   r   r   rb   r!   rc   )r   html_contentpatternsr.   matchesr1   Zextracted_urlrj   r   r   r   r     s*   



z Spider._extract_direct_video_urlNc           	   
   C   s   z9g }| d}|s| d}| dt| d |D ]}| ||}|r+|| q|r7|r7|d| W S |W S  tyW } z| dt|  g W  Y d}~S d}~ww )u3   获取影片列表 - 根据实际网站结构修复z5//ul[@class="thumbnail-group"]//a[@class="thumbnail"]z"//a[contains(@class, "thumbnail")]u   找到 u    个视频元素Nu   获取影片列表出错: )r}   r!   r+   _extract_videoappendrb   rc   )	r   rh   rr   r]   ri   elementsr   videorj   r   r   r   ra     s"   


zSpider._get_videosc              
   C   s  z| dd }|dr| j| }d|v pd|v }|rh|| jv rhtj|}tj|j}|	ddgd }|rPt
d|}|rG|d	}	ntt|d
 }	ntt|d
 }	d| d|	 dtj| }
n| d|}|sxtt|d
 }d| }
|rd| d| }
| d}|s| d}|s| d}|s| d}|s| d}|s| d W dS |d  }| |}| d}|s| d}|r|d nd}|r|drd| }n
|dr| j| }|
||dddW S  ty } z| dt|  W Y d}~dS d}~ww )u   提取影片信息 - 修复版rv   r   r   z/html/28k.htmlz/html/ar.htmlr   r   z/([a-f0-9-]+)/[^/]+\.m3u8r'   i@B r   rm   z/id/(\d+)\.htmlz618636.xyz_z(.//span[@class="title km-script"]/text()z).//span[contains(@class, "title")]/text()z&.//p[contains(@class, "title")]/text()z.//h3/text()z.//h4/text()u'   未找到标题元素，跳过该视频Nz.//img/@data-originalz.//img/@srcr   r   )r   r   r   r   r   u   提取影片信息出错: )r}   r   r   r    r   r   r   r   r   r   r(   r)   r-   rc   hashr   r2   r!   stripr   rb   )r   elementrr   linkZis_special_linkr   r   r   Zvideo_id_matchr   Zfinal_vod_idr   
title_elemr   r   Zpic_elempicrj   r   r   r   r     sp   

 













zSpider._extract_videoc           	   
   C   s~   z g }|D ]}t |}|dA }t|}|| qd|}|W S  ty> } z| dt|  |W  Y d}~S d}~ww )u   解密标题   r   u   标题解密失败: N)ordchrr   r   rb   r!   rc   )	r   encrypted_textZdecrypted_charschar
code_pointZdecrypted_codeZdecrypted_charZdecrypted_textrj   r   r   r   r   &  s   
zSpider._decrypt_titlec                 C   st  z|  |ddg}|  |ddg}|r|dr| j| }|  |ddg}|  |dg}|  |d	g}g }	g }
g d
}g }|D ]}t||}|| q?|rsg }|D ]}t| j|}|d|  qS|rs|	d |
d| |	s| 	d |	d |
d|  |||dddd|||d|	d|
dW S  t
y } z| 	dt|  W Y d}~dS d}~ww )u   获取详情信息 - 修复版z//h1/text()z//title/text()z)//div[contains(@class,"dyimg")]//img/@srcz%//img[contains(@class,"poster")]/@srcr   z+//div[contains(@class,"yp_context")]/text()z.//div[contains(@class,"introduction")]//text()u=   //span[contains(text(),"主演")]/following-sibling::*/text()u=   //span[contains(text(),"导演")]/following-sibling::*/text())zhref="(/html/28k\.html[^"]*)"zhref="(/html/ar\.html[^"]*)"zhref="(/html/kkyd\.html[^"]*)"r   u   默认播放源#u-   未找到播放源，使用默认播放方式r   z$$$)r   r   r   r<   r   vod_arear   	vod_actorvod_directorvod_contentr   r   u   获取详情出错: N)	_get_textr   r   r(   r   r"   r   r   r   r!   rb   rc   )r   rh   r   r   r   r   descZactordirector	play_from	play_urlsZplayer_link_patternsZplayer_linksr.   r   episodesr   full_urlrj   r   r   r   r   6  sZ   



zSpider._get_detailc                 C   sN   |D ]"}z| |}|D ]}|r| r|   W   S qW q   Y qdS )u   通用文本提取r   )r}   r   )r   rh   	selectorsselectorZtextsr`   r   r   r   r   q  s   
zSpider._get_textc                 C   s   t d|  dS )u   日志输出u   [苹果视频] N)print)r   messager   r   r   r!   }  s   z
Spider.logGET
   c              
   C   s   z$|du r| j }|dkrtj|||dd}|W S tj||||dd}|W S  tyD } z| d| dt|  W Y d}~dS d}~ww )u   网络请求Nr   F)r   timeoutverify)r   r   r   r   u   网络请求失败: u
   , 错误: )r   requestsr   postrb   r!   rc   )r   r5   r   methodr   r   responserj   r   r   r   r^     s   zSpider.fetch)r   )r'   )rp   )NNr4   )Nr   Nr   )__name__
__module____qualname__r	   r#   r&   r2   r6   r7   rk   rl   r   r   r   r   r   r   ra   r   r   r   r   r!   r^   r   r   r   r   r      s,    


*
5"?f1

N;r   __main__)syspathr   base.spiderr   r   timeurllib.parser   r(   r   lxmlr   r   r   
BaseSpiderregisterr   r   r   r   <module>   s(        