TubeScript-API/tools/expand_and_test_proxies.py
Cesar Mendivil 2923510c51 Add Playwright tools for extracting M3U8 URLs and proxy management
- Introduced `playwright_extract_m3u8.py` to extract M3U8 URLs from YouTube videos using Playwright.
- Added `README_PLAYWRIGHT.md` for usage instructions and requirements.
- Created `expand_and_test_proxies.py` to expand user-provided proxies and test their validity.
- Implemented `generate_proxy_whitelist.py` to generate a whitelist of working proxies based on testing results.
- Added sample proxy files: `user_proxies.txt` for user-defined proxies and `proxies_sample.txt` as a template.
- Generated `expanded_proxies.txt`, `whitelist.json`, and `whitelist.txt` for storing expanded and valid proxies.
- Included error handling and logging for proxy testing results.
2026-03-17 00:29:51 -07:00

114 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""
expand_and_test_proxies.py
Lee tools/user_proxies.txt, genera variantes (intenta también SOCKS5/SOCKS5H en puertos comunes)
y ejecuta tools/generate_proxy_whitelist.py con la lista expandida.
Uso:
python3 tools/expand_and_test_proxies.py
Salida:
- tools/expanded_proxies.txt (lista expandida)
- llama a generate_proxy_whitelist.py y produce tools/whitelist.json y tools/whitelist.txt
"""
import os
import re
import subprocess
from pathlib import Path
BASE = Path(__file__).resolve().parent
USER_FILE = BASE / 'user_proxies.txt'
EXPANDED_FILE = BASE / 'expanded_proxies.txt'
GEN_SCRIPT = BASE / 'generate_proxy_whitelist.py'
COMMON_SOCKS_PORTS = [1080, 10808, 9050]
def normalize_line(line: str) -> str | None:
s = line.strip()
if not s or s.startswith('#'):
return None
return s
def parse_host_port(s: str):
# remove scheme if present
m = re.match(r'^(?:(?P<scheme>[a-zA-Z0-9+.-]+)://)?(?P<host>[^:/@]+)(?::(?P<port>\d+))?(?:@.*)?$', s)
if not m:
return None, None, None
scheme = m.group('scheme')
host = m.group('host')
port = m.group('port')
port = int(port) if port else None
return scheme, host, port
def build_variants(s: str):
scheme, host, port = parse_host_port(s)
variants = []
# keep original if it has scheme
if scheme:
variants.append(s)
else:
# assume http by default if none
if port:
variants.append(f'http://{host}:{port}')
else:
variants.append(f'http://{host}:80')
# Try socks5h on same port if port present
if port:
variants.append(f'socks5h://{host}:{port}')
# Try socks5h on common ports
for p in COMMON_SOCKS_PORTS:
variants.append(f'socks5h://{host}:{p}')
# Deduplicate preserving order
seen = set()
out = []
for v in variants:
if v in seen:
continue
seen.add(v)
out.append(v)
return out
def main():
if not USER_FILE.exists():
print(f'No se encontró {USER_FILE}. Crea el archivo con proxies (uno por línea).')
return
all_variants = []
with USER_FILE.open('r', encoding='utf-8') as fh:
for line in fh:
s = normalize_line(line)
if not s:
continue
vars = build_variants(s)
all_variants.extend(vars)
# write expanded file
with EXPANDED_FILE.open('w', encoding='utf-8') as fh:
for v in all_variants:
fh.write(v + '\n')
print(f'Wrote expanded proxies to {EXPANDED_FILE} ({len(all_variants)} entries)')
# Call generator
cmd = [ 'python3', str(GEN_SCRIPT), '--input', str(EXPANDED_FILE), '--out-json', str(BASE / 'whitelist.json'), '--out-txt', str(BASE / 'whitelist.txt'), '--test-url', 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', '--concurrency', '6']
print('Running generator...')
try:
res = subprocess.run(cmd, capture_output=True, text=True, timeout=600)
print('Generator exit code:', res.returncode)
print('stdout:\n', res.stdout)
print('stderr:\n', res.stderr)
except Exception as e:
print('Error running generator:', e)
if __name__ == '__main__':
main()