Files
tvbox-1/py/ssjh.py
T
2026-02-25 22:39:46 +08:00

152 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# coding=utf-8
import os
import logging
import sys
import asyncio
import aiohttp
BASE_URL = "http://api.hclyz.com:81/mf"
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
TARGET_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "..", "lib"))
M3U_FILE = os.path.join(TARGET_DIR, "18/sbjh.m3u")
BLACK_LIST = ["支付宝风控解除", "依依实力带飞"]
HEADERS = {"User-Agent": "Mozilla/5.0"}
VALID_PREFIX = ("http://", "https://", "rtmp://")
MAX_WORKERS = 15
def setup_logging():
logger = logging.getLogger("ScraperLogger")
logger.setLevel(logging.INFO)
formatter = logging.Formatter('[%(asctime)s] %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
return logger
log = setup_logging()
async def safe_get_json(url, session):
try:
async with session.get(url, headers=HEADERS, timeout=10) as r:
if r.status != 200:
return None
return await r.json(content_type=None)
except Exception as e:
log.error(f"Request Exception: {url} -> {e}")
return None
def is_valid_stream(url):
url = url.lower()
return url.startswith(VALID_PREFIX) and (".m3u8" in url or ".flv" in url or ".mp4" in url or url.startswith("rtmp://"))
async def process_platform(item, session, sem):
async with sem:
room_title = item.get("title", "").strip()
number = item.get("Number", "")
address = item.get("address", "")
log.info(f"📺 Concurrent requests{room_title}{number}")
detail = await safe_get_json(f"{BASE_URL}/{address}", session)
if not detail:
return room_title, [], 1, 0
zhubo = detail.get("zhubo", [])
if not zhubo:
return room_title, [], 1, 0
group_name = f"{room_title}"
results = []
errors = 0
filtered = 0
for vod in zhubo:
name = vod.get("title", "").strip()
url = vod.get("address", "").strip()
if any(keyword in name for keyword in BLACK_LIST):
log.info(f"🚫 Blocked words: {name}")
filtered += 1
continue
if not url or not is_valid_stream(url):
errors += 1
continue
results.append((group_name, name, url))
return room_title, results, errors, filtered
async def main_async():
total_error = 0
total_success = 0
total_filtered = 0
log.info("🚀 Task initiated.")
log.info(f"📂 Output the absolute path{M3U_FILE}")
# aiohttp 连接池配置
connector = aiohttp.TCPConnector(limit=MAX_WORKERS)
async with aiohttp.ClientSession(connector=connector) as session:
home = await safe_get_json(f"{BASE_URL}/json.txt", session)
if not home:
log.error("❌ Retrieval failed, collection terminated.")
sys.exit(1)
data = home.get("pingtai", [])[1:]
data = sorted(data, key=lambda x: int(x.get("Number", 0) or 0), reverse=True)
m3u_lines = ["#EXTM3U"]
seen_urls = set()
log.info(f"⚡ Multi-threading (Async): {MAX_WORKERS}")
sem = asyncio.Semaphore(MAX_WORKERS)
tasks = [process_platform(item, session, sem) for item in data]
results = await asyncio.gather(*tasks)
for room_title, res, errors, filtered in results:
total_error += errors
total_filtered += filtered
for group_name, name, url in res:
if url in seen_urls:
continue
seen_urls.add(url)
m3u_lines.append(f'#EXTINF:-1 group-title="{group_name}",{name}')
m3u_lines.append(url)
total_success += 1
try:
os.makedirs(os.path.dirname(M3U_FILE), exist_ok=True)
with open(M3U_FILE, "w", encoding="utf-8") as f:
f.write("\n".join(m3u_lines))
log.info(f"📄 It has been generated and saved.")
log.info(f"✅ Absolute path: {M3U_FILE}")
except Exception as e:
log.error(f"❌ Failed to write to file: {e}")
sys.exit(1)
summary_msg = f"Collection completed, valid{total_success}Shield{total_filtered}abnormal{total_error}"
log.info(summary_msg)
print(f"::notice title=📁 Save path: {M3U_FILE}::{summary_msg}")
def main():
asyncio.run(main_async())
if __name__ == "__main__":
main()