forked from lucheng7996/TE
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iptv-zb.py
352 lines (299 loc) · 13.9 KB
/
iptv-zb.py
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
import time
import os
import re
import base64
import requests
import threading
from queue import Queue
from datetime import datetime
import pytz
# 获取远程直播源文件
url = "https://mirror.ghproxy.com/https://raw.githubusercontent.com/Fairy8o/IPTV/main/DIYP-v4.txt"
r = requests.get(url)
open('DIYP-v4.txt', 'wb').write(r.content)
keywords = ['凤凰卫视', '凤凰资讯', 'TVB翡翠', 'TVB明珠', 'TVB星河', 'J2', '无线', '有线', '天映', 'VIU', 'RTHK', 'HOY',
'香港卫视', 'Viut'] # 需要提取的关键字列表
pattern = '|'.join(keywords) # 创建正则表达式模式,匹配任意一个关键字
with open('DIYP-v4.txt', 'r', encoding='utf-8') as file, open('HK.txt', 'w', encoding='utf-8') as HK:
HK.write('\n港澳频道,#genre#\n')
for line in file:
if re.search(pattern, line): # 如果行中有任意关键字
HK.write(line) # 将该行写入输出文件
keywords = ['民视', '中视', '台视', '华视', '新闻台', '东森', '龙祥', '公视', '三立', '大爱', '年代新闻', '人间卫视',
'人間', '大立'] # 需要提取的关键字列表
pattern = '|'.join(keywords) # 创建正则表达式模式,匹配任意一个关键字
with open('DIYP-v4.txt', 'r', encoding='utf-8') as file, open('TW.txt', 'w', encoding='utf-8') as TW:
TW.write('\n台湾频道,#genre#\n')
for line in file:
if re.search(pattern, line): # 如果行中有任意关键字
TW.write(line) # 将该行写入输出文件
# 读取要合并的香港频道和台湾频道文件
file_contents = []
file_paths = ["HK.txt", "TW.txt"] # 替换为实际的文件路径列表
for file_path in file_paths:
with open(file_path, 'r', encoding="utf-8") as file:
content = file.read()
file_contents.append(content)
# 生成合并后的文件
with open("GAT.txt", "w", encoding="utf-8") as output:
output.write('\n'.join(file_contents))
# 线程安全的队列,用于存储下载任务
task_queue = Queue()
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 '
'Safari/537.36'}
# 文件读取
class Record:
def __init__(self, name, url):
self.name = name # 频道名称
self.url = url # 频道链接
def __str__(self):
return f"{self.name},{self.url}"
# 抽象类读取文件
class FileReader:
def read_data(self) -> list[Record]:
'''读取文件的数据'''
pass
class TextFileReader(FileReader):
def __init__(self, path):
self.path = path # 定义成员变量记录文件路径
def read_data(self) -> list[Record]:
f = open(self.path, "r", encoding="UTF-8")
record_list = []
for line in f.readlines():
data_list = line.strip().split(",")
record = Record(data_list[0], data_list[1])
record_list.append(record)
f.close()
return record_list
class GetChannel():
def __init__(self, urls, org = "Chinanet"):
self.urls = urls
self.org = org
def get_channel(self):
urls_a = []
urls_all = []
count = 0
for url in self.urls:
url_0 = str(base64.b64encode((f'"Server: udpxy" && region="{url}" && org="{self.org}"').encode("utf-8")),
"utf-8")
url_64 = f'https://fofa.info/result?qbase64={url_0}'
print(url_64)
try:
response = requests.get(url_64, headers=headers)
page_content = response.text
pattern = r'href="(http://\d+\.\d+\.\d+\.\d+:\d+)"'
page_urls = re.findall(pattern, page_content)
for urlx in page_urls:
try:
response = requests.get(url=urlx + '/status', timeout=3)
response.raise_for_status() # 返回状态码不是200异常
page_content = response.text
#pattern = r'class="proctabl"'
pattern = r'value="Restart"'
page_proctabl = re.findall(pattern, page_content)
if page_proctabl:
urls_a.append(urlx)
print(f"{urlx} 可以访问")
except requests.RequestException as e:
pass
except:
print(f"{url_64} 访问失败")
pass
urls_a = list(set(urls_a))
index = 1
urls_cunt = 3 # 取3个不同IP
for i in urls_a:
if i in urls_all:
continue
else:
if index > urls_cunt:
continue
else:
index += 1
urls_all.append(i)
print(urls_all)
return urls_all
#urls_hn = ["changsha","hengyang","zhuzhou"]
urls_hn = ["hunan"]
#urls_sc = ['chengdu']
urls_sc = ['sichuan']
urls_bj = ["beijing"]
#urls_fj = ["fuzhou","xiamen"]
urls_fj = ["fujian"]
tf_hn = TextFileReader("hunan.txt")
tf_sc = TextFileReader("sichuan.txt")
tf_bj = TextFileReader("beijing.txt")
tf_fj = TextFileReader("fujian.txt")
channelsx_hn = tf_hn.read_data()
channelsx_sc = tf_sc.read_data()
channelsx_bj = tf_bj.read_data()
channelsx_fj = tf_fj.read_data()
u_hn = GetChannel(urls_hn)
urls_hn_all = set(u_hn.get_channel())
u_sc = GetChannel(urls_sc)
urls_sc_all = set(u_sc.get_channel())
u_bj = GetChannel(urls_bj, "China Unicom Beijing Province Network")
urls_bj_all = set(u_bj.get_channel())
u_fj = GetChannel(urls_fj)
urls_fj_all = set(u_fj.get_channel())
results = []
channel = []
resultsx = []
resultxs = []
error_channels = []
def get_channel(urls, channels):
for urlx in urls:
for a in channels:
channel = [f'{a.name},{a.url.replace("http://8.8.8.8:8", urlx)}']
results.extend(channel)
return results
results.extend(set(get_channel(urls_bj_all, channelsx_bj))) # 去重得到唯一的URL列表
results.extend(set(get_channel(urls_fj_all, channelsx_fj))) # 去重得到唯一的URL列表
results.extend(set(get_channel(urls_sc_all, channelsx_sc))) # 去重得到唯一的URL列表
results.extend(set(get_channel(urls_hn_all, channelsx_hn))) # 去重得到唯一的URL列表
results = sorted(set(results)) #排序
# 定义工作线程函数
def worker():
while True:
result = task_queue.get()
channel_name, channel_url = result.split(',', 1)
try:
response = requests.get(channel_url, stream=True, timeout=3)
if response.status_code == 200:
result = channel_name, channel_url
resultsx.append(result)
numberx = (len(resultsx) + len(error_channels)) / len(results) * 100
print(
f"可用频道:{len(resultsx)} 个, 不可用频道:{len(error_channels)} 个 , 总频道:{len(results)} 个 ,总进度:{numberx:.2f} %。")
else:
error_channels.append(result)
numberx = (len(resultsx) + len(error_channels)) / len(results) * 100
print(
f"可用频道:{len(resultsx)} 个 , 不可用频道:{len(error_channels)} 个, 总频道:{len(results)} 个 ,总进度:{numberx:.2f} %。")
except:
error_channels.append(result)
numberx = (len(resultsx) + len(error_channels)) / len(results) * 100
print(
f"可用频道:{len(resultsx)} 个 , 不可用频道:{len(error_channels)} 个 , 总频道:{len(results)} 个 ,总进度:{numberx:.2f} %。")
# 标记任务完成
task_queue.task_done()
# 创建多个工作线程
num_threads = 15
for _ in range(num_threads):
t = threading.Thread(target=worker, daemon=True)
t.start()
# 添加下载任务到队列
for result in results:
task_queue.put(result)
# 等待所有任务完成
task_queue.join()
def channel_key(channel_name):
match = re.search(r'\d+', channel_name)
if match:
return int(match.group())
else:
return float('inf') # 返回一个无穷大的数字作为关键字
for resulta in resultsx:
channel_name, channel_url = resulta
resultx = channel_name, channel_url
resultxs.append(resultx)
# 对频道进行排序
resultxs.sort(key=lambda x: channel_key(x[0]))
# now_today = datetime.date.today()
result_counter = 18 # 每个频道需要的个数
with open("IPTV_ZB.txt", 'w', encoding='utf-8') as file:
channel_counters = {}
file.write('央视频道,#genre#\n')
for result in resultxs:
channel_name, channel_url = result
if 'CCTV' in channel_name:
if channel_name in channel_counters:
if channel_counters[channel_name] >= result_counter:
continue
else:
file.write(f"{channel_name},{channel_url}\n")
channel_counters[channel_name] += 1
else:
file.write(f"{channel_name},{channel_url}\n")
channel_counters[channel_name] = 1
channel_counters = {}
file.write('\n卫视频道,#genre#\n')
for result in resultxs:
channel_name, channel_url = result
if '卫视' in channel_name or '凤凰' in channel_name:
if channel_name in channel_counters:
if channel_counters[channel_name] >= result_counter:
continue
else:
file.write(f"{channel_name},{channel_url}\n")
channel_counters[channel_name] += 1
else:
file.write(f"{channel_name},{channel_url}\n")
channel_counters[channel_name] = 1
channel_counters = {}
file.write('\n湖南频道,#genre#\n')
for result in resultxs:
channel_name, channel_url = result
if '湖南' in channel_name or '长沙' in channel_name or '金鹰' in channel_name or '衡阳' in channel_name or '株洲' in channel_name or '张家界' in channel_name\
or '娄底' in channel_name or '邵阳' in channel_name or '宁乡' in channel_name or '怀化' in channel_name or '岳阳' in channel_name or '郴州' in channel_name\
or '常德' in channel_name or '永州' in channel_name or '浏阳' in channel_name or '益阳' in channel_name or '安仁' in channel_name or '桂东' in channel_name\
or '茶陵' in channel_name or '临澧' in channel_name or '武冈' in channel_name or '新化' in channel_name or '津市' in channel_name or '溆浦' in channel_name\
or '湘西' in channel_name or '湘潭' in channel_name:
if channel_name in channel_counters:
if channel_counters[channel_name] >= result_counter:
continue
else:
file.write(f"{channel_name},{channel_url}\n")
channel_counters[channel_name] += 1
else:
file.write(f"{channel_name},{channel_url}\n")
channel_counters[channel_name] = 1
channel_counters = {}
file.write('\n其他频道,#genre#\n')
for result in resultxs:
channel_name, channel_url = result
if 'CCTV' not in channel_name and '卫视' not in channel_name and '测试' not in channel_name and '湖南' not in \
channel_name and '长沙' not in channel_name and '金鹰' not in channel_name and '凤凰' not in \
channel_name and '衡阳' not in channel_name and '株洲' not in channel_name and '张家界' not in \
channel_name and '娄底' not in channel_name and '邵阳' not in channel_name and '宁乡' not in \
channel_name and '怀化' not in channel_name and '岳阳' not in channel_name and '郴州' not in \
channel_name and '常德' not in channel_name and '永州' not in channel_name and '浏阳' not in \
channel_name and '益阳' not in channel_name and '安仁' not in channel_name and '桂东' not in \
channel_name and '茶陵' not in channel_name and '临澧' not in channel_name and '武冈' not in \
channel_name and '新化' not in channel_name and '津市' not in channel_name and '溆浦' not in \
channel_name and '湘西' not in channel_name and '湘潭' not in channel_name:
if channel_name in channel_counters:
if channel_counters[channel_name] >= result_counter:
continue
else:
file.write(f"{channel_name},{channel_url}\n")
channel_counters[channel_name] += 1
else:
file.write(f"{channel_name},{channel_url}\n")
channel_counters[channel_name] = 1
# 合并所有的txt文件
file_contents = []
file_paths = ["IPTV_ZB.txt", "GAT.txt"] # 替换为实际的文件路径列表
for file_path in file_paths:
with open(file_path, 'r', encoding="utf-8") as file:
content = file.read()
file_contents.append(content)
# 写入合并后的txt文件
with open("IPTV_ZB.txt", "w", encoding="utf-8") as output:
output.write('\n'.join(file_contents))
# 写入更新日期时间
# file.write(f"{now_today}更新,#genre#\n")
# 获取当前时间
local_tz = pytz.timezone("Asia/Shanghai")
now = datetime.now(local_tz)
#now = datetime.now()
output.write(f"\n更新时间,#genre#\n")
output.write(f"{now.strftime("%Y-%m-%d")},url\n")
output.write(f"{now.strftime("%H:%M:%S")},url\n")
output.close()
print(f"电视频道成功写入IPTV_ZB.txt")
os.remove("DIYP-v4.txt")
os.remove("HK.txt")
os.remove("TW.txt")
os.remove("GAT.txt")