Files
tvbox_collect/FGBLH/py/91porn.py
T
2026-07-05 10:21:24 +00:00

192 lines
6.0 KiB
Python

#coding=utf-8
#!/usr/bin/python
import sys
sys.path.append('..')
import json
import re
from base.spider import Spider
class Spider(Spider):
def getName(self):
return "91Porn"
def init(self, extend):
self.baseUrl = "https://91porn.com"
self.header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept-Language": "zh-CN,zh;q=0.9",
"Referer": self.baseUrl + "/index.php"
}
self.cookies = {}
# ✨ 核心改造:动态从 config.json 的 ext 参数中读取配置
self.username = ""
self.password = ""
self.email = ""
try:
if extend:
extendDict = json.loads(extend) if isinstance(extend, str) else extend
self.username = str(extendDict.get('username', '')).strip()
self.password = str(extendDict.get('password', '')).strip()
self.email = str(extendDict.get('email', '')).strip()
except Exception:
pass
self.is_ready = False
def safe_bypass_and_verify(self):
if self.is_ready:
return True
try:
rsp = self.fetch(self.baseUrl + "/email_verify.php", headers=self.header, timeout=5)
self.cookies.update(rsp.cookies.get_dict())
self.cookies['language'] = 'cn_CN'
self.cookies['CNAM'] = '1'
# 如果外部没有配置邮箱,则直接作为普通游客会话放行
if not self.email:
self.is_ready = True
return True
post_data = {"email": self.email, "recover": "Submit", "submit": "true"}
v_hd = self.header.copy()
v_hd["Content-Type"] = "application/x-www-form-urlencoded"
v_hd["Referer"] = self.baseUrl + "/email_verify.php"
rsp_v = self.post(self.baseUrl + "/email_verify.php", data=post_data, headers=v_hd, cookies=self.cookies, timeout=5)
self.cookies.update(rsp_v.cookies.get_dict())
self.is_ready = True
return True
except Exception:
self.is_ready = True
return False
def homeContent(self, filter):
result = {}
classList = [
{"type_name": "今日排行", "type_id": "hot"},
{"type_name": "最近更新", "type_id": "rp"},
{"type_name": "本月最热", "type_id": "md"}
]
result['class'] = classList
return result
def homeVideoContent(self):
return {'list': []}
def categoryContent(self, cid, page, filter, ext):
self.safe_bypass_and_verify()
result = {'page': int(page), 'pagecount': 1, 'limit': 0, 'total': 0, 'list': []}
page = int(page)
url = self.baseUrl + "/v.php?category=" + cid + "&page=" + str(page)
if cid == "hot":
url = self.baseUrl + "/index.php"
elif cid == "rp":
url = self.baseUrl + "/v.php?next=watch&page=" + str(page)
try:
rsp = self.fetch(url, headers=self.header, cookies=self.cookies, timeout=5)
html = self.html(rsp.text)
items = html.xpath("//div[contains(@class, 'well')]")
videos = []
for item in items:
try:
a_tag = item.xpath(".//a[contains(@href, 'view_video.php')]")
if not a_tag:
continue
href = a_tag[0].get('href', '')
v_match = re.search(r'viewkey=([a-zA-Z0-9]+)', href)
if not v_match:
continue
vod_id = v_match.group(1)
name_nodes = item.xpath(".//span[contains(@class, 'video-title')]/text()")
vod_name = name_nodes[0].strip() if name_nodes else "精彩视频"
img_nodes = item.xpath(".//img[contains(@class, 'img-responsive')]/@src")
vod_pic = img_nodes[0].strip() if img_nodes else ""
if vod_pic.startswith('//'):
vod_pic = "https:" + vod_pic
remark_nodes = item.xpath(".//span[@class='duration']/text()")
vod_remarks = remark_nodes[0].strip() if remark_nodes else "完整版"
videos.append({"vod_id": vod_id, "vod_name": self.cleanText(self.removeHtmlTags(vod_name)), "vod_pic": vod_pic, "vod_remarks": vod_remarks})
except:
continue
result['list'] = videos
result['limit'] = len(videos)
result['pagecount'] = page + 1 if len(videos) >= 10 else page
except Exception:
pass
return result
def detailContent(self, did):
self.safe_bypass_and_verify()
tid = did[0]
url = self.baseUrl + "/view_video.php?viewkey=" + tid
try:
rsp = self.fetch(url, headers=self.header, cookies=self.cookies, timeout=5)
html_text = rsp.text.replace('&', '&')
root = self.html(html_text)
title_nodes = root.xpath("//h4[contains(@class, 'login_register_header')]/text() | //title/text()")
title = title_nodes[0].strip().replace(" - 91porn", "").strip() if title_nodes else "精彩视频"
cover_nodes = root.xpath("//video/@poster")
cover_pic = cover_nodes[0] if cover_nodes else ""
real_video_url = ""
strencode_match = re.search(r'strencode2\([\"\']([^\"\'\)]+)[\"\']\)', html_text)
if strencode_match:
ciphertext = strencode_match.group(1)
try:
from urllib.parse import unquote
decrypted_html = unquote(ciphertext)
except:
import urllib
decrypted_html = urllib.unquote(ciphertext)
src_match = re.search(r"src=['\"]([^'\"]+)['\"]", decrypted_html)
if src_match:
real_video_url = src_match.group(1)
if not real_video_url:
src_nodes = root.xpath("//video/source/@src | //video/@src")
if src_nodes:
real_video_url = src_nodes[0]
if not real_video_url:
real_video_url = url
vod = {"vod_id": tid, "vod_name": self.cleanText(self.removeHtmlTags(title)), "vod_pic": cover_pic, "type_name": "在线视频", "vod_content": "资源解析就绪", "vod_play_from": "91Porn秒解流", "vod_play_url": "直连资源源$" + real_video_url}
return {'list': [vod]}
except Exception:
pass
return {'list': []}
def playerContent(self, flag, pid, vipFlags):
need_parse = 1 if "view_video.php" in pid else 0
return {"url": pid, "header": self.header, "parse": need_parse}
def searchContent(self, key, quick):
return {'list': []}
def searchContentPage(self, key, quick, page):
return {'list': []}
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def localProxy(self, params):
return None
def destroy(self):
pass