File size: 2,409 Bytes
44b5a51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env python3
"""
Fetch a proxy list from a URL (e.g. Webshare download link) and output it in
9Hits format: server:port;user;pass|server2:port;user2;pass2

Stdlib only, no external dependencies.
"""

import sys
import urllib.error
import urllib.request


def fetch_and_convert(url):
    req = urllib.request.Request(
        url,
        headers={"User-Agent": "hits4me-fetch/1.0"},
    )
    try:
        with urllib.request.urlopen(req, timeout=60) as resp:
            raw_body = resp.read()
    except urllib.error.HTTPError as e:
        err_body = ""
        try:
            err_body = e.read().decode("utf-8", errors="replace").strip()
        except Exception:
            pass
        if err_body:
            sys.stderr.write(f"HTTP error {e.code}: {err_body[:300]}\n")
        else:
            sys.stderr.write(f"HTTP error {e.code}: {e.reason}\n")
        sys.exit(1)
    except Exception as e:
        sys.stderr.write(f"Failed to fetch proxy list: {e}\n")
        sys.exit(1)

    try:
        body = raw_body.decode("utf-8", errors="replace").strip()
    except Exception as e:
        sys.stderr.write(f"Failed to decode response: {e}\n")
        sys.exit(1)

    if not body:
        sys.stderr.write("Empty response received from proxy URL\n")
        sys.exit(1)

    # Check for JSON error response (e.g. Webshare {"download_token": [...]})
    if body.startswith("{"):
        sys.stderr.write(f"Proxy list returned error response: {body[:300]}\n")
        sys.exit(1)

    proxies = []
    for line in body.splitlines():
        line = line.strip()
        if not line or line.startswith("#"):
            continue
        parts = line.split(":", 3)
        if len(parts) == 4:
            ip, port, user, password = parts
            proxies.append(f"{ip}:{port};{user};{password}")
        elif len(parts) == 2:
            ip, port = parts
            proxies.append(f"{ip}:{port}")
        else:
            sys.stderr.write(f"Skipping malformed line: {line[:50]}\n")

    if not proxies:
        sys.stderr.write("No valid proxies found in response\n")
        sys.exit(1)

    sys.stdout.write("|".join(proxies) + "\n")
    sys.exit(0)


def main():
    if len(sys.argv) < 2 or not sys.argv[1].strip():
        sys.stderr.write("Usage: fetch_proxy_list.py <URL>\n")
        sys.exit(1)
    fetch_and_convert(sys.argv[1].strip())


if __name__ == "__main__":
    main()