Для затравки, рабочий алгоритм от ИИ (python скрипт) - получение плейлиста с RuTube
Скрипт запрашивает ТВ трансляции, в том числе имеющее ограничения региона (РФ).
Для обхода ограничения, используется https прокси РФ
полученный с помощью скрипта плейлист можно смотреть без прокси
Код: Выделить всё
import requests
import json
import re
import warnings
warnings.filterwarnings('ignore')
requests.packages.urllib3.disable_warnings()
#источник проксей https://github.com/zloi-user/hideip.me/blob/master/https.txt
proxies_ru = {
'http': 'https://95.164.1.87:443',
'https': 'https://95.164.1.87:443'
}
headers = {
'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64)'
}
channels = {} # {id: title}
# ==========================
# БАЗОВЫЙ ЗАПРОС С FALLBACK
# ==========================
def request_with_fallback(url, ref=None, json_mode=False, force_proxy=None):
"""
force_proxy:
None -> сначала без прокси, потом proxies_ru
True -> только через proxies_ru
"""
proxy_chain = []
if force_proxy is True:
proxy_chain = [proxies_ru]
else:
proxy_chain = [None, proxies_ru]
for proxy in proxy_chain:
try:
session = requests.Session()
session.verify = False
headers_local = headers.copy()
if ref:
headers_local["Referer"] = ref
session.get(ref, headers=headers_local, proxies=proxy, timeout=10)
r = session.get(url, headers=headers_local, proxies=proxy, timeout=15)
session.close()
if json_mode:
return r.json()
return r.text
except Exception:
continue
return None
# ==========================
# ПОЛУЧЕНИЕ РЕАЛЬНОГО M3U8
# ==========================
def get_stream_url(m3u_page_url):
text = request_with_fallback(m3u_page_url)
if not text:
return None
urls = re.findall(r'(https?://[^\s"]+)', text)
return urls[-1] if urls else None
def get_stream_by_id(video_id):
api_url = f"http://rutube.ru/api/play/options/{video_id}"
data = request_with_fallback(api_url, json_mode=True)
if not data:
return None
try:
if not data.get("live_streams"):
return None
hls = data["live_streams"].get("hls")
if not hls or not hls[0].get("url"):
return None
return get_stream_url(hls[0]["url"])
except Exception:
return None
# ==========================
# ПАРСИНГ СПИСКОВ
# ==========================
def parse_items(data):
items = []
if not data:
return 0
if data.get("results"):
items = data["results"]
elif data.get("feed") and data["feed"].get("resources"):
resources = data["feed"]["resources"]
if len(resources) > 1 and resources[1].get("items"):
items = resources[1]["items"]
if not items:
return 0
for item in items:
if (
item.get("title")
and (item.get("duration") in (None, 0))
and item.get("id")
and (item.get("origin_type") != "ifrm")
):
channels[item["id"]] = item["title"]
return len(items)
# ==========================
# СБОР КАНАЛОВ
# ==========================
def collect_channels():
print("Autowidget...")
data = request_with_fallback(
url="http://rutube.ru/api/feeds/autowidget/2?client=wdp&show_hidden_videos=True&show_user_hidden_videos=True&origin__type=rst,rspa",
ref="http://rutube.ru/",
json_mode=True,
force_proxy=True
)
parse_items(data)
print("Person pages...")
for i in range(1, 10):
url = (
"http://rutube.ru/api/video/person/23520886/"
"?client=wdp&show_hidden_videos=True"
"&show_user_hidden_videos=True"
"&origin__type=rst,rspa&page=" + str(i)
)
data = request_with_fallback(
url=url,
ref="http://rutube.ru/",
json_mode=True
)
count = parse_items(data)
if count == 0:
break
print("Category pages...")
for i in range(1, 501):
url = (
"https://rutube.ru/pangolin/api/web/v1/video/category/43"
"?client=wdp&show_hidden_videos=True"
"&show_user_hidden_videos=True"
"&origin__type=rst,rspa&page=" + str(i)
)
data = request_with_fallback(
url=url,
ref="http://rutube.ru/",
json_mode=True,
force_proxy=True
)
count = parse_items(data)
if count == 0:
break
print("Всего найдено каналов:", len(channels))
# ==========================
# ГЕНЕРАЦИЯ M3U
# ==========================
def generate_m3u(filename="playlist.m3u"):
with open(filename, "w", encoding="utf-8") as f:
f.write("#EXTM3U\n")
for video_id, title in channels.items():
print("Обработка:", title)
stream_url = get_stream_by_id(video_id)
if not stream_url:
continue
f.write(f'#EXTINF:-1,{title}\n')
f.write(f'{stream_url}\n')
print("Файл создан:", filename)
# ==========================
# MAIN
# ==========================
if __name__ == "__main__":
collect_channels()
generate_m3u()


