Sync all projects
This commit is contained in:
@@ -808,6 +808,12 @@
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/采集聚合成人.py"
|
||||
},
|
||||
{
|
||||
"key": "猫咪TV",
|
||||
"name": "🐬猫咪TV.py|🔞[成人]",
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/猫咪TV.py"
|
||||
},
|
||||
{
|
||||
"key": "BadNews",
|
||||
"name": "🐬BadNews.py|🔞[成人](挂梯)",
|
||||
@@ -928,6 +934,12 @@
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/8X8X.py"
|
||||
},
|
||||
{
|
||||
"key": "Jable",
|
||||
"name": "🐬Jable.py|🔞[成人]",
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/Jable.py"
|
||||
},
|
||||
{
|
||||
"key": "Xvideos",
|
||||
"name": "🐬Xvideos.py|🔞[成人]",
|
||||
|
||||
@@ -551,6 +551,12 @@
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/采集聚合成人.py"
|
||||
},
|
||||
{
|
||||
"key": "猫咪TV",
|
||||
"name": "🐬猫咪TV.py|🔞[成人]",
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/猫咪TV.py"
|
||||
},
|
||||
{
|
||||
"key": "樱花传媒",
|
||||
"name": "🐬樱花传媒.py|🔞[成人]",
|
||||
@@ -671,6 +677,12 @@
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/8X8X.py"
|
||||
},
|
||||
{
|
||||
"key": "Jable",
|
||||
"name": "🐬Jable.py|🔞[成人]",
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/Jable.py"
|
||||
},
|
||||
{
|
||||
"key": "Xvideos",
|
||||
"name": "🐬Xvideos.py|🔞[成人]",
|
||||
|
||||
@@ -747,6 +747,12 @@
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/蜜桃视频.py"
|
||||
},
|
||||
{
|
||||
"key": "猫咪TV",
|
||||
"name": "🐬猫咪TV.py|🔞",
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/猫咪TV.py"
|
||||
},
|
||||
{
|
||||
"key": "樱花传媒",
|
||||
"name": "🐬樱花传媒.py|🔞",
|
||||
@@ -867,6 +873,12 @@
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/8X8X.py"
|
||||
},
|
||||
{
|
||||
"key": "Jable",
|
||||
"name": "🐬Jable.py|🔞",
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/Jable.py"
|
||||
},
|
||||
{
|
||||
"key": "Xvideos",
|
||||
"name": "🐬Xvideos.py|🔞",
|
||||
|
||||
+13
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"spider": "./tvbox.jar",
|
||||
"spider": "",
|
||||
"logo": "https://img.freepik.com/free-vector/cute-dolphin-swimming-cartoon-vector-icon-illustration-animal-nature-icon-isolated-flat-vector_138676-12582.jpg?semt=ais_hybrid&w=740&q=80",
|
||||
"wallpaper":"http://tool.teyonds.com/api",
|
||||
"warningText": "注意:如果别人倒卖海豚影视接口收费的都是骗子,没有qq群微信群,只有tg官方交流群 TG:@hshsjk",
|
||||
@@ -580,6 +580,12 @@
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/蜜桃视频.py"
|
||||
},
|
||||
{
|
||||
"key": "猫咪TV",
|
||||
"name": "🐬猫咪TV.py|🔞",
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/猫咪TV.py"
|
||||
},
|
||||
{
|
||||
"key": "樱花传媒",
|
||||
"name": "🐬樱花传媒.py|🔞",
|
||||
@@ -700,6 +706,12 @@
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/8X8X.py"
|
||||
},
|
||||
{
|
||||
"key": "Jable",
|
||||
"name": "🐬Jable.py|🔞",
|
||||
"type": 3,
|
||||
"api": "https://ghfast.top/https://raw.githubusercontent.com/FGBLH/HKL/refs/heads/main/py/Jable.py"
|
||||
},
|
||||
{
|
||||
"key": "Xvideos",
|
||||
"name": "🐬Xvideos.py|🔞",
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import urllib.parse
|
||||
import requests
|
||||
|
||||
try:
|
||||
from base.spider import Spider as BaseSpider
|
||||
except ImportError:
|
||||
class BaseSpider:
|
||||
pass
|
||||
|
||||
class Spider(BaseSpider):
|
||||
BASE_URL = "https://jable.sbs"
|
||||
FALLBACK_URLS = ["https://jable.sbs", "https://jable.tv"]
|
||||
HEADERS = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
||||
"Referer": BASE_URL + "/",
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.name = "JableTV"
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(self.HEADERS)
|
||||
self._class_cache = None
|
||||
|
||||
def init(self, extend="{}"):
|
||||
return None
|
||||
|
||||
def getName(self):
|
||||
return self.name
|
||||
|
||||
def homeContent(self, filter):
|
||||
html = self._get(self.BASE_URL + "/latest-updates/")
|
||||
return {"class": self._classes(), "filters": {}, "list": self._parse_list(html), "parse": 0, "jx": 0}
|
||||
|
||||
def homeVideoContent(self):
|
||||
return {"list": self._parse_list(self._get(self.BASE_URL + "/latest-updates/"))}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
page = self._to_int(pg, 1)
|
||||
path = str(tid or "latest-updates").strip("/")
|
||||
url = self.BASE_URL + "/" + path + "/" if page <= 1 else self.BASE_URL + "/" + path + "/" + str(page) + "/"
|
||||
data = self._parse_list(self._get(url))
|
||||
return {"page": page, "pagecount": page if len(data) < 10 else page + 1, "limit": 24, "total": 99999, "list": data, "parse": 0, "jx": 0}
|
||||
|
||||
def detailContent(self, ids):
|
||||
result = {"list": [], "parse": 0, "jx": 0}
|
||||
if not ids:
|
||||
return result
|
||||
url = self._fix_url(ids[0] if str(ids[0]).startswith("http") else self.BASE_URL + "/videos/" + str(ids[0]).strip("/") + "/")
|
||||
html = self._get(url)
|
||||
name = self._clean(self._match(html, r'<h4[^>]*>(.*?)</h4>') or self._match(html, r'<meta[^>]+property=["\']og:title["\'][^>]+content=["\']([^"\']+)') or self._match(html, r'<title>(.*?)</title>').split("-")[0])
|
||||
pic = self._match(html, r'<meta[^>]+property=["\']og:image["\'][^>]+content=["\']([^"\']+)') or self._match(html, r'<video[^>]+poster=["\']([^"\']+)') or self._match(html, r'<img[^>]+(?:data-src|src)=["\']([^"\']+)')
|
||||
tags = ",".join([self._clean(x) for x in re.findall(r'<a[^>]+href=["\'][^"\']*/tags/[^"\']+["\'][^>]*>(.*?)</a>', html, re.S)])
|
||||
remarks = self._clean(" ".join(re.findall(r'<h6[^>]*>(.*?)</h6>', html, re.S)[:3]))
|
||||
content = self._clean(self._match(html, r'<div[^>]+class=["\'][^"\']*(?:description|info|text)[^"\']*["\'][^>]*>(.*?)</div>') or remarks or name)
|
||||
m3u8 = self._m3u8(html)
|
||||
result["list"].append({"vod_id": url, "vod_name": name, "vod_pic": urllib.parse.urljoin(self.BASE_URL, pic), "type_name": tags, "vod_year": "", "vod_area": "", "vod_remarks": remarks, "vod_actor": tags, "vod_director": "", "vod_content": content, "vod_play_from": "Jable", "vod_play_url": "正片$" + (m3u8 or url)})
|
||||
return result
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
page = self._to_int(pg, 1)
|
||||
q = urllib.parse.quote(str(key))
|
||||
url = self.BASE_URL + "/search/" + q + "/" if page <= 1 else self.BASE_URL + "/search/" + q + "/" + str(page) + "/"
|
||||
data = self._parse_list(self._get(url))
|
||||
return {"page": page, "pagecount": page if len(data) < 10 else page + 1, "limit": 24, "total": 99999, "list": data, "parse": 0, "jx": 0}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
result = {"parse": 0, "playUrl": "", "url": id or "", "jx": 0, "header": {"User-Agent": self.HEADERS["User-Agent"], "Referer": self.BASE_URL + "/"}}
|
||||
if not id:
|
||||
return result
|
||||
if ".m3u8" in id or ".mp4" in id:
|
||||
return result
|
||||
play_page = self._fix_url(id if str(id).startswith("http") else self.BASE_URL + "/videos/" + str(id).strip("/") + "/")
|
||||
html = self._get(play_page)
|
||||
m3u8 = self._m3u8(html)
|
||||
if m3u8:
|
||||
result["url"] = m3u8
|
||||
result["header"] = {"User-Agent": self.HEADERS["User-Agent"], "Referer": play_page, "Origin": self.BASE_URL}
|
||||
else:
|
||||
result["url"] = play_page
|
||||
result["parse"] = 1
|
||||
return result
|
||||
|
||||
def _classes(self, html=None):
|
||||
if self._class_cache:
|
||||
return self._class_cache
|
||||
self._class_cache = [
|
||||
{"type_id": "latest-updates", "type_name": "最近更新"},
|
||||
{"type_id": "hot", "type_name": "热门影片"},
|
||||
{"type_id": "new-release", "type_name": "全新上市"},
|
||||
{"type_id": "tags/chinese-subtitle", "type_name": "中文字幕"},
|
||||
{"type_id": "tags/drama", "type_name": "剧情"},
|
||||
{"type_id": "tags/cosplay", "type_name": "角色扮演"},
|
||||
]
|
||||
return self._class_cache
|
||||
|
||||
def _parse_list(self, html):
|
||||
data, seen = [], set()
|
||||
cards = re.findall(r'(<div[^>]+class=["\'][^"\']*video-img-box[^"\']*["\'][\s\S]*?</h6>[\s\S]*?</div>\s*</div>)', html or "", re.S | re.I)
|
||||
if not cards:
|
||||
cards = re.findall(r'(<a[^>]+href=["\'][^"\']*/videos/[^"\']+["\'][\s\S]*?</a>)', html or "", re.S | re.I)
|
||||
for item in cards:
|
||||
href = self._match(item, r'href=["\']([^"\']*/videos/[^"\']+)["\']')
|
||||
if not href:
|
||||
continue
|
||||
name = self._clean(self._match(item, r'<h6[^>]*class=["\'][^"\']*title[^"\']*["\'][^>]*>\s*<a[^>]*>(.*?)</a>') or self._match(item, r'title=["\']([^"\']+)') or self._match(item, r'alt=["\']([^"\']+)'))
|
||||
pic = self._match(item, r'(?:data-src|data-original|data-lazy-src|data-lazyload)=["\']([^"\']+)') or self._match(item, r'<img[^>]+src=["\']([^"\']+)')
|
||||
remarks = self._clean(self._match(item, r'<span[^>]+class=["\'][^"\']*(?:duration|label|badge)[^"\']*["\'][^>]*>(.*?)</span>') or self._match(item, r'(\d{1,2}:\d{2}(?::\d{2})?)'))
|
||||
full = self._fix_url(urllib.parse.urljoin(self.BASE_URL, href))
|
||||
if full not in seen and name and not re.fullmatch(r'\d{1,2}:\d{2}(?::\d{2})?', name):
|
||||
seen.add(full)
|
||||
data.append({"vod_id": full, "vod_name": name, "vod_pic": urllib.parse.urljoin(self.BASE_URL, pic), "vod_remarks": remarks})
|
||||
return data
|
||||
|
||||
def _get(self, url, headers=None):
|
||||
for real in self._candidate_urls(self._fix_url(url)):
|
||||
h = dict(self.HEADERS)
|
||||
h["Referer"] = self.BASE_URL + "/"
|
||||
if headers:
|
||||
h.update(headers)
|
||||
try:
|
||||
r = self.session.get(real, headers=h, timeout=15, verify=False)
|
||||
r.encoding = "utf-8"
|
||||
if r.status_code < 400 and "Just a moment" not in r.text and "cf-browser-verification" not in r.text:
|
||||
return r.text
|
||||
except Exception:
|
||||
continue
|
||||
return ""
|
||||
|
||||
def _candidate_urls(self, url):
|
||||
urls = [url]
|
||||
for host in self.FALLBACK_URLS:
|
||||
p = urllib.parse.urlparse(url)
|
||||
if p.netloc and host not in url:
|
||||
urls.append(host + p.path + ("?" + p.query if p.query else ""))
|
||||
return list(dict.fromkeys(urls))
|
||||
|
||||
def _fix_url(self, url):
|
||||
return str(url or "").replace("https://jable.tv", self.BASE_URL).replace("http://jable.tv", self.BASE_URL).replace("https://www.jable.tv", self.BASE_URL)
|
||||
|
||||
def _m3u8(self, html):
|
||||
return self._match(html, r'var\s+hlsUrl\s*=\s*["\']([^"\']+\.m3u8[^"\']*)') or self._match(html, r'["\'](https?://[^"\']+\.m3u8[^"\']*)["\']')
|
||||
|
||||
def _match(self, text, pattern):
|
||||
m = re.search(pattern, text or "", re.S | re.I)
|
||||
return m.group(1).strip() if m else ""
|
||||
|
||||
def _clean(self, text):
|
||||
text = re.sub(r'<.*?>', '', text or '')
|
||||
text = text.replace(' ', ' ').replace('&', '&').replace('&', '&').replace('"', '"')
|
||||
return re.sub(r'\s+', ' ', text).strip()
|
||||
|
||||
def _to_int(self, value, default=0):
|
||||
try:
|
||||
return int(value)
|
||||
except Exception:
|
||||
return default
|
||||
@@ -0,0 +1,162 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import urllib.parse
|
||||
import requests
|
||||
try:
|
||||
from base.spider import Spider as BaseSpider
|
||||
except ImportError:
|
||||
class BaseSpider:
|
||||
def __init__(self):
|
||||
return None
|
||||
class Spider(BaseSpider):
|
||||
BASE_URL = "https://maomi66.cc"
|
||||
HEADERS = {
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 12; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36",
|
||||
"Referer": "https://maomi66.cc/",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
|
||||
}
|
||||
def __init__(self):
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(self.HEADERS)
|
||||
self._class_cache = []
|
||||
def getName(self):
|
||||
return "猫咪AV"
|
||||
def init(self, extend=""):
|
||||
return None
|
||||
def isVideoFormat(self, url):
|
||||
return bool(re.search(r'\.(m3u8|mp4|flv|avi|mkv|mov)(\?|$)', url or '', re.I))
|
||||
def manualVideoCheck(self):
|
||||
return True
|
||||
def homeContent(self, filter):
|
||||
html = self._get(self.BASE_URL)
|
||||
classes = self._classes(html)
|
||||
return {"class": classes, "list": self._parse_list(html), "filters": {}, "parse": 0, "jx": 0}
|
||||
def homeVideoContent(self):
|
||||
return {"list": self._parse_list(self._get(self.BASE_URL))}
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
page = self._to_int(pg, 1)
|
||||
html = self._get(self.BASE_URL + "/list/%s-%s.html" % (tid, page))
|
||||
data = self._parse_list(html)
|
||||
return {"list": data, "page": page, "pagecount": page + 1 if data else page, "limit": len(data) or 20, "total": (page + 1) * (len(data) or 20)}
|
||||
def detailContent(self, ids):
|
||||
vid = ids[0] if isinstance(ids, list) and ids else str(ids)
|
||||
url = vid if str(vid).startswith("http") else self.BASE_URL + "/video/%s.html" % vid
|
||||
html = self._get(url)
|
||||
title = self._clean(self._match(html, r'<h1[^>]*>(.*?)</h1>') or self._match(html, r'<h2[^>]*>(.*?)</h2>') or self._match(html, r'<title[^>]*>(.*?)</title>'))
|
||||
if not title:
|
||||
title = "视频%s" % re.sub(r'\D+', '', str(vid))
|
||||
pic = self._fix(self._match(html, r'<meta[^>]+property=["\']og:image["\'][^>]+content=["\']([^"\']+)') or self._match(html, r'<video[^>]+poster=["\']([^"\']+)') or self._match(html, r'(?:data-original|data-src|src)=["\']([^"\']+\.(?:jpg|jpeg|png|webp|gif)[^"\']*)'))
|
||||
play = self._extract_play(html)
|
||||
tags = []
|
||||
for x in re.findall(r'<a[^>]+href=["\']/list/\d+-1\.html["\'][^>]*>(.*?)</a>', html, re.S):
|
||||
t = self._clean(x)
|
||||
if t and t not in tags:
|
||||
tags.append(t)
|
||||
content = self._clean(self._match(html, r'<div[^>]+class=["\'][^"\']*(?:des|intro|content|info)[^"\']*["\'][^>]*>(.*?)</div>')) or title
|
||||
vod = {
|
||||
"vod_id": str(vid).split("/")[-1].replace(".html", ""),
|
||||
"vod_name": title,
|
||||
"vod_pic": pic,
|
||||
"type_name": "/".join(tags[:3]),
|
||||
"vod_year": "",
|
||||
"vod_area": "",
|
||||
"vod_remarks": "",
|
||||
"vod_actor": "",
|
||||
"vod_director": "",
|
||||
"vod_content": content,
|
||||
"vod_play_from": "默认",
|
||||
"vod_play_url": "播放$%s" % (play or url)
|
||||
}
|
||||
return {"list": [vod]}
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
q = urllib.parse.quote(str(key or ""))
|
||||
page = self._to_int(pg, 1)
|
||||
html = self._get(self.BASE_URL + "/search.php?content=%s&type=1&page=%s" % (q, page))
|
||||
data = self._parse_list(html)
|
||||
if not data:
|
||||
html = self._get(self.BASE_URL + "/search.php?content=%s&type=1" % q)
|
||||
data = self._parse_list(html)
|
||||
return {"list": data, "page": page, "pagecount": page + 1 if data else page, "limit": len(data) or 20, "total": (page + 1) * (len(data) or 20)}
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
url = urllib.parse.unquote(str(id or ""))
|
||||
if "/video/" in url or re.fullmatch(r'\d+', url):
|
||||
page = url if url.startswith("http") else self.BASE_URL + "/video/%s.html" % url
|
||||
play = self._extract_play(self._get(page))
|
||||
url = play or page
|
||||
return {"parse": 0, "playUrl": "", "url": self._fix(url), "header": self.HEADERS}
|
||||
def _classes(self, html):
|
||||
arr = []
|
||||
for tid, name in re.findall(r'href=["\']/list/(\d+)-1\.html["\'][^>]*>(.*?)</a>', html or "", re.S):
|
||||
name = self._clean(name)
|
||||
if tid and name and not any(x["type_id"] == tid for x in arr):
|
||||
arr.append({"type_id": tid, "type_name": name})
|
||||
if not arr:
|
||||
arr = [
|
||||
{"type_id": "69829818", "type_name": "国产精品"},
|
||||
{"type_id": "71188148", "type_name": "国产自拍"},
|
||||
{"type_id": "43659662", "type_name": "日本精品"},
|
||||
{"type_id": "37440125", "type_name": "欧美极品"},
|
||||
{"type_id": "19211697", "type_name": "中文字幕"},
|
||||
{"type_id": "77777777", "type_name": "动漫精品"}
|
||||
]
|
||||
self._class_cache = arr
|
||||
return arr
|
||||
def _parse_list(self, html):
|
||||
out = []
|
||||
blocks = re.findall(r'<li[\s\S]*?</li>', html or "", re.I)
|
||||
if not blocks:
|
||||
blocks = re.findall(r'<a[^>]+href=["\']/video/\d+\.html["\'][\s\S]*?</a>', html or "", re.I)
|
||||
for item in blocks:
|
||||
vid = self._match(item, r'href=["\'][^"\']*/video/(\d+)\.html["\']')
|
||||
if not vid:
|
||||
continue
|
||||
name = self._clean(self._match(item, r'<h5[^>]*>\s*<a[^>]*>(.*?)</a>') or self._match(item, r'title=["\']([^"\']+)') or self._match(item, r'alt=["\']([^"\']+)'))
|
||||
pic = self._fix(self._match(item, r'data-original=["\']([^"\']+)') or self._match(item, r'data-src=["\']([^"\']+)') or self._match(item, r'<img[^>]+src=["\']([^"\']+)'))
|
||||
remark = self._clean(self._match(item, r'<span[^>]*>(.*?)</span>') or self._match(item, r'<em[^>]*>(.*?)</em>'))
|
||||
if not name:
|
||||
name = "视频%s" % vid
|
||||
vod = {"vod_id": vid, "vod_name": name, "vod_pic": pic, "vod_remarks": remark}
|
||||
if not any(x["vod_id"] == vid for x in out):
|
||||
out.append(vod)
|
||||
return out
|
||||
def _extract_play(self, html):
|
||||
play = self._match(html, r'hls\.loadSource\(["\']([^"\']+)["\']\)') or self._match(html, r'video\.src\s*=\s*["\']([^"\']+)["\']') or self._match(html, r'<source[^>]+src=["\']([^"\']+)["\']') or self._match(html, r'["\'](https?://[^"\']+play\.php\?[^"\']+)["\']') or self._match(html, r'["\'](/play\.php\?[^"\']+)["\']')
|
||||
return self._fix(play)
|
||||
def _get(self, url):
|
||||
if not url:
|
||||
return ""
|
||||
url = self._fix(url)
|
||||
headers = dict(self.HEADERS)
|
||||
headers["Referer"] = self.BASE_URL + "/"
|
||||
try:
|
||||
r = self.session.get(url, headers=headers, timeout=12, verify=False)
|
||||
if not r.encoding or r.encoding.lower() == "iso-8859-1":
|
||||
r.encoding = r.apparent_encoding or "utf-8"
|
||||
return r.text
|
||||
except requests.RequestException:
|
||||
return ""
|
||||
def _match(self, text, pattern, default=""):
|
||||
m = re.search(pattern, text or "", re.S | re.I)
|
||||
if not m:
|
||||
return default
|
||||
return m.group(1) if m.lastindex else m.group(0)
|
||||
def _clean(self, text):
|
||||
text = re.sub(r'<script[\s\S]*?</script>|<style[\s\S]*?</style>', ' ', text or '', flags=re.I)
|
||||
text = re.sub(r'<[^>]+>', ' ', text)
|
||||
text = text.replace(' ', ' ').replace('&amp;', '&').replace('&', '&').replace('&', '&').replace('"', '"').replace(''', "'").replace('<', '<').replace('>', '>')
|
||||
return re.sub(r'\s+', ' ', text).strip()
|
||||
def _fix(self, url):
|
||||
url = (url or "").strip().replace("\\/", "/")
|
||||
if not url:
|
||||
return ""
|
||||
if url.startswith("//"):
|
||||
return "https:" + url
|
||||
if url.startswith("/"):
|
||||
return self.BASE_URL + url
|
||||
return url
|
||||
def _to_int(self, value, default=1):
|
||||
try:
|
||||
return int(value)
|
||||
except Exception:
|
||||
return default
|
||||
Reference in New Issue
Block a user