# -*- coding: utf-8 -*- import re,json,requests from urllib.parse import quote,urljoin try: from base.spider import Spider as BaseSpider except Exception: class BaseSpider: def __init__(self): return None class Spider(BaseSpider): def __init__(self): self.host='https://www.adultporna-av107.com' self.session=requests.Session() self.headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36','Referer':self.host+'/zzzz','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'} self.classes=[('每日最新','/topic/'),('国产视频','/t/163/'),('网曝黑料','/t/232/'),('主播大秀','/t/236/'),('AV解说','/t/233/'),('国产自拍','/t/48/'),('抖阴视频','/t/231/'),('国模私拍','/t/45/'),('空姐模特','/t/67/'),('91制片厂','/t/131/'),('糖心VLOG','/t/128/'),('日本有码','/label/sortjp/'),('国产传媒','/label/sortcnseries/'),('番号专区','/label/sortseries/')] def init(self,extend=''): return None def getName(self): return 'AdultPorna' def isVideoFormat(self,url): return str(url).split('?')[0].lower().endswith(('.m3u8','.mp4','.flv','.avi','.mkv','.mov')) def manualVideoCheck(self): return True def destroy(self): return None def _get(self,url): u=url if str(url).startswith('http') else urljoin(self.host,url) r=self.session.get(u,headers=self.headers,timeout=15,verify=False) r.encoding=r.apparent_encoding or 'utf-8' return r.text def _url(self,u): return urljoin(self.host,u.replace('\\/','/')) if u else '' def _txt(self,s): return re.sub(r'\s+',' ',re.sub(r'<[^>]+>',' ',s or '')).strip() def _pic(self,s): m=re.search(r']+(?:data-original|data-src|data-lazyload|src)=["\']([^"\']+)["\']',s,re.I) return self._url(m.group(1)) if m else '' def _parse_list(self,html): arr=[];seen=set() blocks=re.findall(r']+href=["\'](/voddetail/(\d+)/?)["\'][^>]*>.*?',html,re.I|re.S) for href,vid in blocks: if vid in seen: continue i=html.find(href);chunk=html[max(0,i-800):i+2500] tm=re.search(r']+href=["\']'+re.escape(href)+r'["\'][^>]*(?:title=["\']([^"\']+)["\'])?',chunk,re.I|re.S) am=re.search(r']+alt=["\']([^"\']+)["\']',chunk,re.I) name=(tm.group(1) if tm and tm.group(1) else '') or (am.group(1) if am else '') or vid sm=re.search(r']*>(.*?)',chunk,re.I|re.S) arr.append({'vod_id':vid,'vod_name':self._txt(name),'vod_pic':self._pic(chunk),'vod_remarks':self._txt(sm.group(1)) if sm else ''}) seen.add(vid) return arr def homeContent(self,filter=False): html=self._get('/zzzz') return {'class':[{'type_id':i,'type_name':n} for n,i in self.classes],'list':self._parse_list(html),'filters':{}} def homeVideoContent(self): return {'list':self._parse_list(self._get('/zzzz'))} def categoryContent(self,tid,pg,filter,extend): tid=str(tid);pg=str(pg or '1') path=tid if tid.startswith('/') else '/t/'+tid.strip('/')+'/' if pg!='1': path=path.rstrip('/')+'/page/'+pg+'/' html=self._get(path) data=self._parse_list(html) return {'list':data,'page':int(pg),'pagecount':999 if data else int(pg),'limit':24,'total':999999} def detailContent(self,ids): vid=str(ids[0]).strip('/').split('/')[-1] html=self._get('/voddetail/'+vid+'/') name='';pic='';content='' for p in [r']+property=["\']og:title["\'][^>]+content=["\']([^"\']+)["\']',r']*>(.*?)',r'title=["\']([^"\']+)["\']']: m=re.search(p,html,re.I|re.S) if m and self._txt(m.group(1)): name=self._txt(m.group(1));break m=re.search(r']+property=["\']og:image["\'][^>]+content=["\']([^"\']+)["\']',html,re.I) pic=self._url(m.group(1)) if m else self._pic(html) em=re.search(r'(?:剧情|简介|介绍|详情)[^<]*]+>\s*<[^>]+>(.*?)