获取广东电视台节目表 环境依赖Python3 + Django4 + Nginx + uWSGI,用于部署WEB项目站点展示节目列表、节目列表下载预览或提供节目列表API接口使用,过于繁杂,以下代码基于Python3抓取官方节目表后直接生成需要的epg.xml,方便部署在OpenWRT路由器上使用。

获取代码

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
import datetime
import requests
import warnings
from bs4 import BeautifulSoup as bs
from xml.etree.ElementTree import Element, SubElement, ElementTree

# 定义请求头,模拟浏览器访问
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}

# 忽略 XMLParsedAsHTMLWarning
warnings.filterwarnings('ignore')

# 获取广东电视台频道列表
def get_channels_gdtv():
url = 'http://epg.gdtv.cn/f/1.xml' # 获取广东电视台频道列表的XML文件
res = requests.get(url, headers=headers)
res.encoding = 'utf-8'
soup = bs(res.text, 'html.parser')
contents = soup.select('channel')
channels = []

for content in contents:
channel_id = content.attrs['id']
name = content.ctitle.text.strip() # 使用 strip() 清理可能的空格和换行
channels.append({'id': channel_id, 'name': name})
return channels

# 处理节目标题中的 HTML 实体和标签
def clean_html(text):
# 将 HTML 实体转换为普通字符(例如 & -> &)
text = bs(text, "html.parser").get_text()
return text.replace('<br />', '\n').replace('<br>', '\n').strip()

# 获取指定日期范围内的节目表
def get_epgs_gdtv(channel_id, start_date, end_date):
epgs = []
current_date = start_date
while current_date <= end_date:
url = f'http://epg.gdtv.cn/f/{channel_id}/{current_date.strftime("%Y-%m-%d")}.xml'
res = requests.get(url, headers=headers, timeout=8)
res.encoding = 'utf-8'
soup = bs(res.text, 'html.parser')
epgs_contents = soup.select('content')

for epga in epgs_contents:
starttime = datetime.datetime.fromtimestamp(int(epga.attrs['time1']))
endtime = datetime.datetime.fromtimestamp(int(epga.attrs['time2']))
title = clean_html(epga.get_text())
epgs.append({
'title': title,
'start': starttime,
'end': endtime
})
current_date += datetime.timedelta(days=1)
return epgs

# 创建 XMLTV 文件
def create_epg_xml(channels, epg_data, output_file):
tv = Element('tv')

# 添加频道信息
for channel in channels:
channel_element = SubElement(tv, 'channel', id=channel['id'])
display_name = SubElement(channel_element, 'display-name')
display_name.text = channel['name']

# 添加节目表
for channel_id, programs in epg_data.items():
for program in programs:
programme = SubElement(tv, 'programme', start=program['start'].strftime('%Y%m%d%H%M%S +0800'),
stop=program['end'].strftime('%Y%m%d%H%M%S +0800'),
channel=channel_id)
title = SubElement(programme, 'title')
title.text = program['title']

# 保存为文件
tree = ElementTree(tv)
tree.write(output_file, encoding='utf-8', xml_declaration=True)

# 主函数
if __name__ == "__main__":
today = datetime.datetime.now().date()
start_date = today - datetime.timedelta(days=6) # 六天前
end_date = today + datetime.timedelta(days=2) # 两天后

print("获取频道列表...")
channels = get_channels_gdtv()

epg_data = {}
print("抓取节目表...")
for channel in channels:
channel_id = channel['id']
epg_data[channel_id] = get_epgs_gdtv(channel_id, start_date, end_date)

print("生成 XMLTV 文件...")
output_file = "epg.xml"
create_epg_xml(channels, epg_data, output_file)
print(f"完成!EPG 文件已保存为 {output_file}")

执行代码

1
2
3
4
5
[root@localhost IPTV]# python gdtv_to_epg.py
获取频道列表...
抓取节目表...
生成 XMLTV 文件...
完成!EPG 文件已保存为 epg.xml

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

  1. CCTV-1综合
  2. CCTV-2财经
  3. CCTV-3综艺测试
  4. CCTV-4中文国际
  5. CCTV-5体育测试
  6. CCTV-6电影(测试)
  7. CCTV-7国防军事
  8. CCTV-8电视剧(测试)
  9. CCTV-9纪录
  10. CCTV-10科教
  11. CCTV-11戏曲
  12. CCTV-12社会与法
  13. CCTV-13新闻
  14. CCTV-14少儿
  15. CCTV-15音乐
  16. CGTN
  17. CCTV-17
  18. CCTV-1高清
  19. CCTV5+体育高清
  20. CCTV-2高清
  21. CCTV-3高清测试
  22. CCTV-4高清
  23. CCTV-5高清测试
  24. CCTV-6高清测试
  25. CCTV-7国防军事高清
  26. CCTV-8高清测试
  27. CCTV-9高清
  28. CCTV-10高清
  29. CCTV-11高清
  30. CCTV-12高清
  31. CCTV-13高清
  32. CCTV-14少儿高清
  33. CCTV-15高清
  34. CCTV-17高清
  35. 广东卫视
  36. 广东珠江
  37. 广东新闻
  38. 广东民生
  39. 广东体育
  40. 大湾区卫视
  41. 广东影视
  42. 广东少儿
  43. 广东4K超高清 宽色域AVS2
  44. 广东移动
  45. 南方购物
  46. 岭南戏曲
  47. 广东卫视高清
  48. 广东体育高清
  49. 广东珠江高清
  50. 大湾区卫视高清
  51. 广东影视高清
  52. 广东民生高清
  53. 广东少儿高清
  54. 广东新闻高清
  55. 岭南戏曲高清
  56. 广东珠江超清
  57. VSPN电竞
  58. 精选频道1
  59. 经济科教
  60. 嘉佳卡通
  61. 现代教育
  62. 卡酷动画
  63. 金鹰卡通
  64. 炫动卡通
  65. CETV-1
  66. 山东教育
  67. 财富天下
  68. CETV-2
  69. CETV-4
  70. 经济科教高清
  71. 嘉佳卡通高清
  72. 现代教育高清
  73. 金鹰纪实高清
  74. 上海纪实高清
  75. IPTV谍战剧场
  76. IPTV相声小品
  77. IPTV野外
  78. IPTV法治
  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. 海南卫视高清

前期准备工作

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
[root@localhost ~]# cat /etc/redhat-release
Rocky Linux release 9.4 (Blue Onyx)

[root@localhost demoCA]# openssl version
OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)

[root@localhost ~]# pwd
/root

[root@localhost ~]# mkdir -p demoCA


[root@localhost ~]# cp /etc/pki/tls/openssl.cnf .


[root@localhost ~]# vi openssl.cnf

[ CA_default ]

dir = /root/demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.

certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key


[ policy_match ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional


[root@localhost ~]# cd demoCA/


#root@localhost demoCA]# mkdir newcerts private


[root@localhost demoCA]# chmod 700 private


[root@localhost demoCA]# touch index.txt


[root@localhost demoCA]# echo 01 > serial


[root@localhost demoCA]# tree -L 1
.
├── index.txt
├── newcerts
├── private
└── serial

2 directories, 2 files


newcerts:存放 CA 已签署颁发过的数字证书

private:存放 CA 的私钥

serial:存放证书序列号,可自定义第一张证书的序号(e.g. 0001),之后每新建一张证书,序列号会自动加1

index.txt:存放证书信息

生成CA证书RSA私钥

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost demoCA]# openssl genrsa -passout pass:google -des3 -out ~/demoCA/private/cakey.pem 2048


[root@localhost demoCA]# tree -L 2
.
├── index.txt
├── newcerts
├── private
│   └── cakey.pem
└── serial

2 directories, 3 files

生成CA的根证书公钥

CA证书签名请求 & 对证书进行自签名

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
[root@localhost demoCA]# openssl req -x509 -passin pass:google -new -nodes -key ~/demoCA/private/cakey.pem -days 3650 -s
ubj "/C=CN/ST=GuangDong/L=GZ/O=Approach/CN=www.heiok.com" -out cacert.pem


[root@localhost demoCA]# tree -L 2
.
├── cacert.pem
├── index.txt
├── newcerts
├── private
│   └── cakey.pem
└── serial

2 directories, 4 files


[root@localhost demoCA]# cat cacert.pem
-----BEGIN CERTIFICATE-----
MIIDkzCCAnugAwIBAgIUV3Ql0iptpwoskmLaWoWD2kMmkgQwDQYJKoZIhvcNAQEL
BQAwWTELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nRG9uZzELMAkGA1UEBwwC
R1oxETAPBgNVBAoMCEFwcHJvYWNoMRYwFAYDVQQDDA13d3cuaGVpb2suY29tMB4X
DTI0MTIyNTA4MjkwOVoXDTM0MTIyMzA4MjkwOVowWTELMAkGA1UEBhMCQ04xEjAQ
BgNVBAgMCUd1YW5nRG9uZzELMAkGA1UEBwwCR1oxETAPBgNVBAoMCEFwcHJvYWNo
MRYwFAYDVQQDDA13d3cuaGVpb2suY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA1/hreZ4fTBB4rf3JX1KmnFp5F+JicASvYGgoGsyhYAiHsD5AWvqF
rbuolZqtK6qpxMcFhP7HKyvVM/gtbtWvcdfQFsvcdBOHifKDjnerGRcI6sThY7jg
qI4fJRjNN7wOTpFMS1J6BxUx9x9LMP6NPnhKUqmWqvhExOGOCxqKGkZdgNp1gPri
sWJVqZdoX6hDfbe1n4qkVT6j322rt6+dU+52T8sBkTVc+9dZx67d0d6nhUdl6TnI
Z7qNPmAr7F17IwWHAcGks/qp4izVHCjKljlEg+jFMb1Su1sMQRjyFn1pkAroS8iH
vbhuW6tfX/c8WH/Rry6FlJlvQIcUaSdFKQIDAQABo1MwUTAdBgNVHQ4EFgQUkMyf
n8Vx4qeP/S9cdZ6Du4CuibUwHwYDVR0jBBgwFoAUkMyfn8Vx4qeP/S9cdZ6Du4Cu
ibUwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAIjDmxvVLuJGA
4A8I7QXIhSmFPG2WPems70C2N6hXeybMVN9wGFHp7v9m23Xe83J7wogZMbspRR+Z
tDML/s51P2JQOTQ91eJ6bj21gWQa/Guhb2H8fQtEoXONYfIfIZMIYL2o66GkPOFy
QCeWS3NJdgwDRNcDXIxguZAA0PMnKZkYT5B0G4K0wN9oEqE3+2ZjpF70Wnpo5aWp
1ZbgZFEAhvv6f1Qjc+4GeCVq92b98qXbrkGcim9Vb6ZLhdXFCcJZyxjDJsIBkEW6
OudF00OwP6OWSI5DN4bniXpHcJQQ15CPZdEiGpsHA6Ac6+fb+ENiodbwfdR/eJxX
0g1ALTFR3A==
-----END CERTIFICATE-----

查看 CA 证书的内容

CA证书已包含与密钥文件对应的公钥信息

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
[root@localhost demoCA]# openssl x509 -in cacert.pem -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
57:74:25:d2:2a:6d:a7:0a:2c:92:62:da:5a:85:83:da:43:26:92:04
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, ST = GuangDong, L = GZ, O = Approach, CN = www.heiok.com
Validity
Not Before: Dec 25 08:29:09 2024 GMT
Not After : Dec 23 08:29:09 2034 GMT
Subject: C = CN, ST = GuangDong, L = GZ, O = Approach, CN = www.heiok.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:d7:f8:6b:79:9e:1f:4c:10:78:ad:fd:c9:5f:52:
a6:9c:5a:79:17:e2:62:70:04:af:60:68:28:1a:cc:
a1:60:08:87:b0:3e:40:5a:fa:85:ad:bb:a8:95:9a:
ad:2b:aa:a9:c4:c7:05:84:fe:c7:2b:2b:d5:33:f8:
2d:6e:d5:af:71:d7:d0:16:cb:dc:74:13:87:89:f2:
83:8e:77:ab:19:17:08:ea:c4:e1:63:b8:e0:a8:8e:
1f:25:18:cd:37:bc:0e:4e:91:4c:4b:52:7a:07:15:
31:f7:1f:4b:30:fe:8d:3e:78:4a:52:a9:96:aa:f8:
44:c4:e1:8e:0b:1a:8a:1a:46:5d:80:da:75:80:fa:
e2:b1:62:55:a9:97:68:5f:a8:43:7d:b7:b5:9f:8a:
a4:55:3e:a3:df:6d:ab:b7:af:9d:53:ee:76:4f:cb:
01:91:35:5c:fb:d7:59:c7:ae:dd:d1:de:a7:85:47:
65:e9:39:c8:67:ba:8d:3e:60:2b:ec:5d:7b:23:05:
87:01:c1:a4:b3:fa:a9:e2:2c:d5:1c:28:ca:96:39:
44:83:e8:c5:31:bd:52:bb:5b:0c:41:18:f2:16:7d:
69:90:0a:e8:4b:c8:87:bd:b8:6e:5b:ab:5f:5f:f7:
3c:58:7f:d1:af:2e:85:94:99:6f:40:87:14:69:27:
45:29
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
90:CC:9F:9F:C5:71:E2:A7:8F:FD:2F:5C:75:9E:83:BB:80:AE:89:B5
X509v3 Authority Key Identifier:
90:CC:9F:9F:C5:71:E2:A7:8F:FD:2F:5C:75:9E:83:BB:80:AE:89:B5
X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
22:30:e6:c6:f5:4b:b8:91:80:e0:0f:08:ed:05:c8:85:29:85:
3c:6d:96:3d:e9:ac:ef:40:b6:37:a8:57:7b:26:cc:54:df:70:
18:51:e9:ee:ff:66:db:75:de:f3:72:7b:c2:88:19:31:bb:29:
45:1f:99:b4:33:0b:fe:ce:75:3f:62:50:39:34:3d:d5:e2:7a:
6e:3d:b5:81:64:1a:fc:6b:a1:6f:61:fc:7d:0b:44:a1:73:8d:
61:f2:1f:21:93:08:60:bd:a8:eb:a1:a4:3c:e1:72:40:27:96:
4b:73:49:76:0c:03:44:d7:03:5c:8c:60:b9:90:00:d0:f3:27:
29:99:18:4f:90:74:1b:82:b4:c0:df:68:12:a1:37:fb:66:63:
a4:5e:f4:5a:7a:68:e5:a5:a9:d5:96:e0:64:51:00:86:fb:fa:
7f:54:23:73:ee:06:78:25:6a:f7:66:fd:f2:a5:db:ae:41:9c:
8a:6f:55:6f:a6:4b:85:d5:c5:09:c2:59:cb:18:c3:26:c2:01:
90:45:ba:3a:e7:45:d3:43:b0:3f:a3:96:48:8e:43:37:86:e7:
89:7a:47:70:94:10:d7:90:8f:65:d1:22:1a:9b:07:03:a0:1c:
eb:e7:db:f8:43:62:a1:d6:f0:7d:d4:7f:78:9c:57:d2:0d:40:
2d:31:51:dc

生成服务器证书密钥文件 & 证书签名请求

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
[root@localhost demoCA]# openssl req -utf8 -newkey rsa:2048 -nodes -keyout client.key -subj "/C=CN/ST=广东省/O=广东省服
务器/CN=广东省服务器" -out client.csr

[root@localhost demoCA]# tree -L 2
.
├── cacert.pem
├── client.csr
├── client.key
├── index.txt
├── newcerts
├── private
│   └── cakey.pem
└── serial

2 directories, 6 files

[root@localhost demoCA]# cat client.csr
-----BEGIN CERTIFICATE REQUEST-----
MIICoDCCAYgCAQAwWzELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCeW5v+S4nOecgTEb
MBkGA1UECgwS5bm/5Lic55yB5pyN5Yqh5ZmoMRswGQYDVQQDDBLlub/kuJznnIHm
nI3liqHlmagwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyuYovU3Vh
MmZfOZlYYy6SFJq8Xk7ZznhZRI8eTerfe08tqH2L/XWXPnlZWbOrvRME+Njmi6Wv
ZaXyNiWb39GRkxVRMBWYU7OLE8aUdowznTtFeJAnm/gHZhfmUaIMp3R+zyLs5POy
ZJ0o4cD3YVk+ep7FN+uPefrWgc4u3QXZoX011JrCwgP4hMYL7qgytXfQ0Y045oU6
zciKI05XeAlT9+rtiM4k1ee6DZY8GvH5UoNEwC7onDK2BhM9iIu82OscVrgaKNrJ
yDgoUa/8h8I6Ar9a+7w/3/lT+wnq9pWmek2WqNCb4DsystOurHZQCL7orn3z6wCa
L9TntnUL0cbzAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAKTZwHQsRaFPexJoc
rR+qklzdGScCEYJbiB6qk6Q+UFa8l0yO/xnKXQ0iCCbwZ2MtUM2Bw6d/95hlIaq6
ENDrtrGSK2BkUNvocr+IM1YJHdG/jPFyKJanY6AlokQEo03pfuGgRQMlnOu2ZQls
/2EFPBv6CVwidgTY2cqZHGw3cicoPiZ39ikj07P+V+uira1YqUSkyV+xf8M3G5vK
luHBKq71DvJNH+LFJawOpILWReAhIXaxT+6lI17JqCiH9Rs0Srw7/V76Ks6sLpo8
eZr/WxsOCzDvztyhyyiB1QJj5cjnl6wU/g3NhHvo7JjFqobOH86Pa72v53OJ1lHI
Idh1Iw==
-----END CERTIFICATE REQUEST-----

CA签发服务器证书

根据 openssl.cnf 加载CA证书并集合服务器证书签名请求文件来完成签名

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
[root@localhost demoCA]# openssl ca -passin pass:google -config ~/openssl.cnf -in client.csr -out client_cert.pem -batch

Using configuration from /root/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Dec 25 08:55:30 2024 GMT
Not After : Dec 25 08:55:30 2025 GMT
Subject:
countryName = CN
stateOrProvinceName = \U5E7F\U4E1C\U7701
organizationName = \U5E7F\U4E1C\U7701\U670D\U52A1\U5668
commonName = \U5E7F\U4E1C\U7701\U670D\U52A1\U5668
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
E2:AF:5A:FB:F3:B8:25:2C:62:D9:3B:09:EA:1A:65:0E:3E:12:54:18
X509v3 Authority Key Identifier:
90:CC:9F:9F:C5:71:E2:A7:8F:FD:2F:5C:75:9E:83:BB:80:AE:89:B5
Certificate is to be certified until Dec 25 08:55:30 2025 GMT (365 days)

Write out database with 1 new entries
Data Base Updated

[root@localhost demoCA]# tree -L 3
.
├── cacert.pem
├── client_cert.pem
├── client.csr
├── client.key
├── index.txt
├── index.txt.attr
├── index.txt.old
├── newcerts
│   └── 01.pem
├── private
│   └── cakey.pem
├── serial
└── serial.old

2 directories, 11 files

[root@localhost demoCA]# ll
total 36
-rw-r--r--. 1 root root 1302 Dec 25 16:29 cacert.pem
-rw-r--r--. 1 root root 4443 Dec 25 16:55 client_cert.pem
-rw-r--r--. 1 root root 989 Dec 25 16:42 client.csr
-rw-------. 1 root root 1704 Dec 25 16:42 client.key
-rw-r--r--. 1 root root 225 Dec 25 16:55 index.txt
-rw-r--r--. 1 root root 21 Dec 25 16:55 index.txt.attr
-rw-r--r--. 1 root root 0 Dec 25 15:59 index.txt.old
drwxr-xr-x. 2 root root 20 Dec 25 16:55 newcerts
drwx------. 2 root root 23 Dec 25 16:21 private
-rw-r--r--. 1 root root 3 Dec 25 16:55 serial
-rw-r--r--. 1 root root 3 Dec 25 15:59 serial.old


[root@localhost demoCA]# cat client_cert.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=CN, ST=GuangDong, L=GZ, O=Approach, CN=www.heiok.com
Validity
Not Before: Dec 25 08:55:30 2024 GMT
Not After : Dec 25 08:55:30 2025 GMT
Subject: C=CN, ST=\xE5\xB9\xBF\xE4\xB8\x9C\xE7\x9C\x81, O=\xE5\xB9\xBF\xE4\xB8\x9C\xE7\x9C\x81\xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8, CN=\xE5\xB9\xBF\xE4\xB8\x9C\xE7\x9C\x81\xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:b2:b9:8a:2f:53:75:61:32:66:5f:39:99:58:63:
2e:92:14:9a:bc:5e:4e:d9:ce:78:59:44:8f:1e:4d:
ea:df:7b:4f:2d:a8:7d:8b:fd:75:97:3e:79:59:59:
b3:ab:bd:13:04:f8:d8:e6:8b:a5:af:65:a5:f2:36:
25:9b:df:d1:91:93:15:51:30:15:98:53:b3:8b:13:
c6:94:76:8c:33:9d:3b:45:78:90:27:9b:f8:07:66:
17:e6:51:a2:0c:a7:74:7e:cf:22:ec:e4:f3:b2:64:
9d:28:e1:c0:f7:61:59:3e:7a:9e:c5:37:eb:8f:79:
fa:d6:81:ce:2e:dd:05:d9:a1:7d:35:d4:9a:c2:c2:
03:f8:84:c6:0b:ee:a8:32:b5:77:d0:d1:8d:38:e6:
85:3a:cd:c8:8a:23:4e:57:78:09:53:f7:ea:ed:88:
ce:24:d5:e7:ba:0d:96:3c:1a:f1:f9:52:83:44:c0:
2e:e8:9c:32:b6:06:13:3d:88:8b:bc:d8:eb:1c:56:
b8:1a:28:da:c9:c8:38:28:51:af:fc:87:c2:3a:02:
bf:5a:fb:bc:3f:df:f9:53:fb:09:ea:f6:95:a6:7a:
4d:96:a8:d0:9b:e0:3b:32:b2:d3:ae:ac:76:50:08:
be:e8:ae:7d:f3:eb:00:9a:2f:d4:e7:b6:75:0b:d1:
c6:f3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
E2:AF:5A:FB:F3:B8:25:2C:62:D9:3B:09:EA:1A:65:0E:3E:12:54:18
X509v3 Authority Key Identifier:
90:CC:9F:9F:C5:71:E2:A7:8F:FD:2F:5C:75:9E:83:BB:80:AE:89:B5
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
0a:e7:5a:c0:f6:b5:14:f6:c4:6a:b8:d3:8b:fc:d9:c0:a6:7c:
22:e2:1b:93:db:55:89:44:7a:c3:47:e5:ba:5c:87:27:a9:32:
5b:a7:26:b7:e5:da:52:c8:ca:9e:3d:bc:64:7e:ff:81:78:68:
00:b0:23:1b:8b:9c:73:60:18:bd:7d:2d:5f:d6:41:20:cd:69:
55:13:74:d5:ce:c7:07:86:41:22:69:ee:5c:5a:46:13:83:ef:
46:90:a3:03:aa:f9:fd:a9:a8:2d:ca:3c:77:60:e6:ee:79:03:
7c:3a:33:78:a5:13:c9:4d:df:9b:58:af:e1:d3:41:89:cb:d9:
81:ae:35:01:08:ca:9c:7b:7f:a5:d2:5b:c5:ef:31:34:85:a3:
a6:17:a6:ae:dd:14:d5:0e:88:63:16:50:6c:eb:ff:0b:be:45:
6e:17:eb:65:9a:ab:e8:94:d1:a6:e9:ca:90:9b:8c:08:29:4b:
3f:ef:5d:6c:03:c4:b8:d8:d9:b0:04:80:43:30:31:c9:71:bc:
9b:82:67:b8:37:55:57:a8:47:42:58:43:35:9e:f1:e1:08:0f:
fd:17:f6:a2:92:88:83:c4:a7:1f:5b:af:c4:ac:ec:85:a5:af:
77:a8:79:b3:19:b2:92:9d:7e:0f:9a:20:3e:99:47:a3:48:59:
37:ba:07:ef
-----BEGIN CERTIFICATE-----
MIIDfDCCAmSgAwIBAgIBATANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJDTjES
MBAGA1UECAwJR3VhbmdEb25nMQswCQYDVQQHDAJHWjERMA8GA1UECgwIQXBwcm9h
Y2gxFjAUBgNVBAMMDXd3dy5oZWlvay5jb20wHhcNMjQxMjI1MDg1NTMwWhcNMjUx
MjI1MDg1NTMwWjBbMQswCQYDVQQGEwJDTjESMBAGA1UECAwJ5bm/5Lic55yBMRsw
GQYDVQQKDBLlub/kuJznnIHmnI3liqHlmagxGzAZBgNVBAMMEuW5v+S4nOecgeac
jeWKoeWZqDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALK5ii9TdWEy
Zl85mVhjLpIUmrxeTtnOeFlEjx5N6t97Ty2ofYv9dZc+eVlZs6u9EwT42OaLpa9l
pfI2JZvf0ZGTFVEwFZhTs4sTxpR2jDOdO0V4kCeb+AdmF+ZRogyndH7PIuzk87Jk
nSjhwPdhWT56nsU36495+taBzi7dBdmhfTXUmsLCA/iExgvuqDK1d9DRjTjmhTrN
yIojTld4CVP36u2IziTV57oNljwa8flSg0TALuicMrYGEz2Ii7zY6xxWuBoo2snI
OChRr/yHwjoCv1r7vD/f+VP7Cer2laZ6TZao0JvgOzKy066sdlAIvuiuffPrAJov
1Oe2dQvRxvMCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQU4q9a+/O4JSxi
2TsJ6hplDj4SVBgwHwYDVR0jBBgwFoAUkMyfn8Vx4qeP/S9cdZ6Du4CuibUwDQYJ
KoZIhvcNAQELBQADggEBAArnWsD2tRT2xGq404v82cCmfCLiG5PbVYlEesNH5bpc
hyepMlunJrfl2lLIyp49vGR+/4F4aACwIxuLnHNgGL19LV/WQSDNaVUTdNXOxweG
QSJp7lxaRhOD70aQowOq+f2pqC3KPHdg5u55A3w6M3ilE8lN35tYr+HTQYnL2YGu
NQEIypx7f6XSW8XvMTSFo6YXpq7dFNUOiGMWUGzr/wu+RW4X62Waq+iU0abpypCb
jAgpSz/vXWwDxLjY2bAEgEMwMclxvJuCZ7g3VVeoR0JYQzWe8eEID/0X9qKSiIPE
px9br8Ss7IWlr3eoebMZspKdfg+aID6ZR6NIWTe6B+8=
-----END CERTIFICATE-----

导出为 PKCS#12 文件

1
2
3
4
5
6
OpenSSL 1.0.2k-fips

[root@localhost demoCA]# openssl pkcs12 -export -in client_cert.pem -inkey client.key -out client.p12

Enter Export Password:
Verifying - Enter Export Password:

Adobe Acrobat添加OpenSSL 3.0.7版本生成的.p12文件会有加密算法与 KDF(密钥派生函数)问题,添加以下参数解决

参数说明:

-certpbe PBE-SHA1-3DES:指定证书的加密算法为 3DES(适用于旧软件)。
-keypbe PBE-SHA1-3DES:指定私钥的加密算法为 3DES。
-macalg SHA1:将 MAC 的算法强制设置为 SHA-1,而不是 OpenSSL 3.x 的默认 SHA-256 或更高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
OpenSSL 3.0.7

[root@localhost demoCA]# openssl pkcs12 -export -in client_cert.pem -inkey client.key -out client.p12 -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -macalg SHA1

Enter Export Password:
Verifying - Enter Export Password:


[root@localhost demoCA]# ll
total 40
-rw-r--r--. 1 root root 1302 Dec 25 16:29 cacert.pem
-rw-r--r--. 1 root root 4443 Dec 25 16:55 client_cert.pem
-rw-r--r--. 1 root root 989 Dec 25 16:42 client.csr
-rw-------. 1 root root 1704 Dec 25 16:42 client.key
-rw-------. 1 root root 2643 Dec 25 17:09 client.p12
-rw-r--r--. 1 root root 225 Dec 25 16:55 index.txt
-rw-r--r--. 1 root root 21 Dec 25 16:55 index.txt.attr
-rw-r--r--. 1 root root 0 Dec 25 15:59 index.txt.old
drwxr-xr-x. 2 root root 20 Dec 25 16:55 newcerts
drwx------. 2 root root 23 Dec 25 16:21 private
-rw-r--r--. 1 root root 3 Dec 25 16:55 serial
-rw-r--r--. 1 root root 3 Dec 25 15:59 serial.old

收视设备信息

  • 光猫型号: HG6142A
  • 盒子型号: TR100 IPTV-G9
  • 连接方式: LAN2
  • 单播组播:单播 & 组播
  • 认证时效: 7天(省内跨市联通网络可看)
  • 连接模式:桥接
  • VLAN ID: 45

获取IPTV频道

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
import requests
import json
import os
import sys

# 设置工作目录为脚本所在目录
os.chdir(os.path.dirname(os.path.abspath(__file__)))

s = requests.Session()
s.headers['User-Agent'] = 'okhttp/3.10.0'

# 获取所有频道信息
all_channels_response = s.get("http://120.87.12.38:8083/epg/api/custom/getAllChannel.json")
all_channels_data = all_channels_response.json()

if all_channels_data['status'] != '200' or 'channels' not in all_channels_data:
print("错误:无法获取频道列表或频道列表格式错误。")
sys.exit(1)

# 提取频道代码
channel_codes = [channel['params']['hwcode'] for channel in all_channels_data['channels'] if 'params' in channel and 'hwcode' in channel['params']]
channel_codes_str = ','.join(channel_codes)

# 获取访问令牌
token_response = s.get("http://120.87.11.11:33200/EPG/oauth/v2/token?grant_type=EncryToken&client_id=shuma2&authinfo=52A57E9F6583C26C2F2E0C6E3FC7452F164A4C84BDEE623FF387E69D25C4C1A57031D44BBAA6DEF42155B7524C4DED856EE61F320E7CFEDEA491B8AFDF90FF4B4830CEE38BAAEC1E88165B70BC52666557400555BED665177880021B8C65ECBF&UserID=0175205891367&DeviceType=TR100-G9&DeviceVersion=219.470.107&userdomain=1&datadomain=1&accountType=1")
access_token = token_response.json().get('access_token')

if not access_token:
print("错误:未能获取有效的 access token。")
sys.exit(1)

# 使用访问令牌请求数据
headers = {
'Authorization': access_token,
'User-Agent': 'okhttp/3.10.0',
'Connection': 'Keep-Alive',
'Content-Type': 'application/json;charset=utf-8'
}
data = json.dumps({"channelcodes": channel_codes_str})
# 请修改此处IP,确保与鉴权URL的IP一致
response = s.post("http://120.87.11.11:33200/EPG/interEpg/channellist/batch", headers=headers, data=data)

if not response.json():
print("错误:返回的数据为空。")
sys.exit(1)

# 保存响应数据到文件
with open('iptv.json', 'w', encoding='UTF-8') as f:
json.dump(response.json(), f)

# 复制 base.txt 到 iptv.txt 和 iptv.m3u8
with open('base.txt', 'r', encoding='UTF-8') as f_base, open('iptv.txt', 'w', encoding='UTF-8') as f_iptv, open('iptv.m3u8', 'w', encoding='UTF-8') as f_m3u8:
base_content = f_base.read()
f_iptv.write(base_content)
f_m3u8.write("#EXTM3U\n")

# 读取 iptv.json 并处理数据
with open('iptv.json', 'r', encoding='UTF-8') as f:
data = json.load(f)
if not data.get('channellist'):
print("错误:'channellist' 数据为空。")
sys.exit(1)

channels = {}

for item in data['channellist']:
hwcode = item['channelcode']
channel_info = next((ch for ch in all_channels_data['channels'] if ch['params'].get('hwcode') == hwcode), None)
if not channel_info:
continue

channel_name = channel_info['title']
timeshift_url = item['timeshifturl']
group = "其它"
if "CCTV" in channel_name or "CGTN" in channel_name:
group = "央视"
elif any(x in channel_name for x in ["广东", "广州", "大湾区", "南方", "岭南"]):
group = "广东"
elif "卫视" in channel_name:
group = "卫视"

if group:
if group not in channels:
channels[group] = []
channels[group].append((channel_name, timeshift_url))

# 写入处理后的数据到 iptv.txt 和 iptv.m3u8
with open('iptv.txt', 'a', encoding='UTF-8') as f_iptv, open('iptv.m3u8', 'a', encoding='UTF-8') as f_m3u8:
for group, ch_list in channels.items():
f_iptv.write(f"{group},#genre#\n")
for channel_name, url in ch_list:
f_iptv.write(f"{channel_name},{url}\n")
f_m3u8.write(f"#EXTINF:-1,{channel_name}\n{url}\n")

事以至此

想必以下方法你们都搞过啦

  • 修改注册表;
  • 修改组策略;
  • 添加凭证项;
  • 替换动态库;
  • 关闭防火墙。

不妨试试

  • 卸载共享主机打印驱动;
  • 重新安装共享主机驱动;
  • 重新连接共享主机打印;
  • 直至客机提示安装驱动。

设备信息

  • ASUS RT-AC 1200GU (F/W Ver:V3.0.0.4.380_10732 H/W Ver:A)
  • openwrt-23.05.4-ramips-mt7621-asus_rt-ac57u-v1-initramfs-kernel.bin
  • openwrt-23.05.4-ramips-mt7621-asus_rt-ac57u-v1-squashfs-sysupgrade.bin

改国内源

vi /etc/opkg/distfeeds.conf

1
2
3
4
5
6
src/gz openwrt_core https://mirrors.aliyun.com/openwrt/releases/23.05.4/targets/x86/64/packages
src/gz openwrt_base https://mirrors.aliyun.com/openwrt/releases/23.05.4/packages/x86_64/base
src/gz openwrt_luci https://mirrors.aliyun.com/openwrt/releases/23.05.4/packages/x86_64/luci
src/gz openwrt_packages https://mirrors.aliyun.com/openwrt/releases/23.05.4/packages/x86_64/packages
src/gz openwrt_routing https://mirrors.aliyun.com/openwrt/releases/23.05.4/packages/x86_64/routing
src/gz openwrt_telephony https://mirrors.aliyun.com/openwrt/releases/23.05.4/packages/x86_64/telephony

环境安装

1
2
3
4
5
6
7
8
9
root@Openwrt:# opkg install python3-base

root@Openwrt:~# opkg install python3-pip

root@Openwrt:~# /usr/bin/python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip

root@Openwrt:~# opkg install requests

root@Openwrt:~# opkg install bs4

pip清华源

1
2
3
4
5
pip install pip -U

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U

设备信息

  • ASUS RT-AC 1200GU (F/W Ver:V3.0.0.4.380_10732 H/W Ver:A)
  • openwrt-23.05.4-ramips-mt7621-asus_rt-ac57u-v1-initramfs-kernel.bin
  • openwrt-23.05.4-ramips-mt7621-asus_rt-ac57u-v1-squashfs-sysupgrade.bin

安装插件

1
2
3
opkg update

opkg install fdisk swap-utils kmod-usb-storage kmod-fs-ext4 e2fsprogs kmod-usb-ohci kmod-usb-uhci block-mount

磁盘分区

1
2
3
4
5
6
7
8
9
10
11
12
13
fdisk -l (查看辨别U盘外设磁盘名称,如/dev/sda。)

fdisk /dev/sda (U盘分区)

p (查看U盘分区)
d (删除U盘分区)
n (新增U盘分区)
p (选主分区类型)
1 (分区数量选壹)
Enter(按回车键)
Enter(按回车键)
w (保存分区配置)
reboot(重启启动)

格式分区

1
2
3
fdisk -l (查看分区名称,如/dev/sda1。)

mkfs.ext4 /dev/sda (格式化分区为ext4)

挂载分区

1
2
3
mkdir /mnt/sda1

mount /dev/sda1 /mnt/sda1

数据迁移

1
2
3
cp -r /overlay/* /mnt/sda1

block info (查看U盘的UUID)

配置挂载

1
登录路由器管理界面 - 系统 - 挂载点 - 添加 - UUID、挂载点(作为外部overlay使用) - 保存应用

完成

ASN 和 BGP 的关系

  • ASN(自治系统号):是用于标识一个自治系统(AS)的唯一编号。一个 AS 是由一个或多个网络组成的,它们在技术和管理上由同一个实体控制。
  • BGP(边界网关协议):是用来交换自治系统之间路由信息的协议。如果一个 ASN 和其他 ASN 之间存在对等关系(PEER),它通常是通过 BGP 来实现的。

当一个 IP 地址与某个 ASN 关联时,这意味着这个 ASN 宣告了该 IP 地址的路由信息。如果该 ASN 与多个其他 ASN 存在对等互联关系(PEER 或 TRANSIT),就表明这个 IP 地址可能是 BGP 路由的一部分。


判断是否 BGP 路由

如果工具(如 HE.NET 的 BGP 查询工具)显示:

  • 该 IP 对应某个 ASN;
  • 该 ASN 和其他多个 ASN(如 B 和 C)有 PEER 或 TRANSIT 关系;
  • 这些对等关系是 BGP 特有的连接类型,

那么可以判断这个 IP 是通过 BGP 宣告的线路。

以下是关键术语的意义:

  • PEER(对等关系):两个 ASN 之间互相交换路由信息,但通常只交换彼此的客户流量,而不会传递第三方流量。
  • TRANSIT(中继关系):一个 ASN 向另一个 ASN 提供更广泛的互联网接入(包括其所有的下游路由)。
  • UPSTREAM(上游关系):你的 ASN 通过其他 ASN 接入互联网。

判断依据

假设在查询中,得到了以下信息:

  • IP 地址属于 ASN 65001(运营商 A)。
  • ASN 65001 和以下 ASN 存在 PEER 关系:
    • ASN 65002(运营商 B)
    • ASN 65003(运营商 C)

可以推断:

  1. ASN 65001 宣告了该 IP 地址的路由信息。
  2. PEER 关系意味着 ASN 65001 和其他 ASN(如 65002、65003)通过 BGP 互通。
  3. 因此,这个 IP 地址是通过 BGP 路由的线路。

补充说明

如果需要更精确的判断,可以进一步验证:

  1. 检查路由表或 Traceroute: 使用 Traceroute 查看数据包是否经过多个 ASN 的边界跳跃。例如,Traceroute 输出中会显示 ASN 的 IP 段变化,通常表示 BGP 路由在工作。
  2. ASN 的大小和互联关系: 如果一个 ASN 具有多个 PEER 或 TRANSIT 关系,且它是全球或区域范围的大型运营商(如中国电信、联通、移动等),它很可能是通过 BGP 提供服务。
  3. 询问运营商: 联系运营商,确认他们是否提供 BGP 服务,以及是否支持多运营商互联。

特殊情况

如果一个 ASN 仅与一个上游 ASN 互联,并且没有其他对等关系,那么它可能只是一个单运营商的专有线路,不能算作典型的 BGP 多线。


结论

如果 IP 对应的 ASN 与多个其他 ASN 存在 PEER 或 TRANSIT 关系,可以判断该线路是 BGP 的线路。

收视设备信息

  • 光猫型号: ZN-GE100
  • 盒子型号: HG680-KA
  • 连接方式: LAN or iTV
  • 单播组播:单播
  • 认证时效: 一个月

获取全部频道

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
import requests
from bs4 import BeautifulSoup
import re

# 1. 身份验证信息
auth_data = {
"UserID": "0209170330290",
"Lang": "",
"SupportHD": "1",
"NetUserID": "0209170330290@iptv.gd",
"DHCPUserID": "0209170330290@iptv.gd",
"Authenticator": "7D21702B6FA45DC20A4352BD1OOF9B694FBEFAAADD34B25FC818723AE666F7D0E6EE9B75AE7692A063041A58AC50DE673F03E178A576C195890F73D4F3C39A302FD7184CBDC91C0A0CE2AD077DA48E7A48BEC5F0BE97A15CDCAB45FF8725983F1F746501AF777AE74CB87D905E7E9E910C1A1E12FB1316689E5DD49D871EF76F",
"STBType": "FIBERHOME_HG680KA",
"STBVersion": "1.150150.13.2022v1",
"conntype": "2",
"STBID": "001005990016208092E98820115D2042",
"templateName": "iptvsnmv3",
"areaId": "86020",
"userToken": "32F1583A459D7E48A6310D54FBC1CCCA",
"userGroupId": "",
"productPackageId": "",
"mac": "58:19:2D:24:28:02",
"UserField": "",
"SoftwareVersion": "1.150150.13.2022v1",
"IsSmartStb": "1",
"desktopId": "",
"stbmaker": "",
"VIP": "",
}

# 2. 用于身份验证的URL
auth_url = "http://183.59.156.43:8082/EPG/jsp/ValidAuthenticationHWCTC.jsp"
channel_list_url = "http://183.59.156.43:8082/EPG/jsp/getchannellistHWCTC.jsp"

# 3. 创建会话
session = requests.Session()

# 4. 发起身份验证请求,获取Cookie
response = session.post(auth_url, data=auth_data)
if response.status_code == 200:
print("身份验证成功")
else:
print("身份验证失败")
exit(1)

# 5. 获取频道列表页面
response = session.get(channel_list_url)
if response.status_code == 200:
print("成功获取频道列表页面")
else:
print("获取频道列表页面失败")
exit(1)

# 6. 解析HTML并提取频道信息
html_content = response.text
soup = BeautifulSoup(html_content, "html.parser")
scripts = soup.find_all("script")

# 查找所有包含频道信息的脚本
m3u8_channels = ""
regex = re.compile(r',?(.+?)="(.*?)"')

for script in scripts:
if "CTCSetConfig" in script.string:
matches = regex.finditer(script.string)
info = {}
for match in matches:
key, value = match.groups()
if key == "ChannelName":
m3u8_channels += f'#EXTINF:-1 tvg-name="{value}",{value}\n'
if key == "ChannelSDP":
m3u8_channels += f"{value}\n"

# 7. 保存m3u8文件
with open("IPTV.m3u8", "w", encoding="utf-8") as m3u8_file:
m3u8_file.write(m3u8_channels)

print("IPTV.m3u8 文件已生成")

导出珠江频道

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
import requests
from bs4 import BeautifulSoup
import re

# 1. 身份验证信息
auth_data = {
"UserID": "0209170330290",
"Lang": "",
"SupportHD": "1",
"NetUserID": "0209170330290@iptv.gd",
"DHCPUserID": "0209170330290@iptv.gd",
"Authenticator": "7D21702B6FA45DC20A4352BD1OOF9B694FBEFAAADD34B25FC818723AE666F7D0E6EE9B75AE7692A063041A58AC50DE673F03E178A576C195890F73D4F3C39A302FD7184CBDC91C0A0CE2AD077DA48E7A48BEC5F0BE97A15CDCAB45FF8725983F1F746501AF777AE74CB87D905E7E9E910C1A1E12FB1316689E5DD49D871EF76F",
"STBType": "FIBERHOME_HG680KA",
"STBVersion": "1.150150.13.2022v1",
"conntype": "2",
"STBID": "001005990016208092E98820115D2042",
"templateName": "iptvsnmv3",
"areaId": "86020",
"userToken": "32F1583A459D7E48A6310D54FBC1CCCA",
"userGroupId": "",
"productPackageId": "",
"mac": "58:19:2D:24:28:02",
"UserField": "",
"SoftwareVersion": "1.150150.13.2022v1",
"IsSmartStb": "1",
"desktopId": "",
"stbmaker": "",
"VIP": "",
}

# 2. 用于身份验证的URL
auth_url = "http://183.59.156.43:8082/EPG/jsp/ValidAuthenticationHWCTC.jsp"
channel_list_url = "http://183.59.156.43:8082/EPG/jsp/getchannellistHWCTC.jsp"

# 3. 创建会话
session = requests.Session()

# 4. 发起身份验证请求,获取Cookie
response = session.post(auth_url, data=auth_data)
if response.status_code == 200:
print("身份验证成功")
else:
print("身份验证失败")
exit(1)

# 5. 获取频道列表页面
response = session.get(channel_list_url)
if response.status_code == 200:
print("成功获取频道列表页面")
else:
print("获取频道列表页面失败")
exit(1)

# 6. 解析HTML并提取频道信息
html_content = response.text
soup = BeautifulSoup(html_content, "html.parser")
scripts = soup.find_all("script")

# 查找所有包含频道信息的脚本
m3u8_channels = ""
regex = re.compile(r',?(.+?)="(.*?)"')
zhujiang_channel = ""

for script in scripts:
if "CTCSetConfig" in script.string:
matches = regex.finditer(script.string)
info = {}
channel_name = ""
channel_sdp = ""
for match in matches:
key, value = match.groups()
if key == "ChannelName":
channel_name = value
if key == "ChannelSDP":
channel_sdp = value

if channel_name:
m3u8_channels += f'#EXTINF:-1 tvg-name="{channel_name}",{channel_name}\n'
m3u8_channels += f"{channel_sdp}\n"

# 筛选出“广东珠江”频道
if channel_name == "广东珠江":
zhujiang_channel = f'#EXTINF:-1 tvg-name="{channel_name}",{channel_name}\n{channel_sdp}\n'

# 7. 保存 IPTV.m3u8 文件
with open("IPTV.m3u8", "w", encoding="utf-8") as m3u8_file:
m3u8_file.write(m3u8_channels)
print("IPTV.m3u8 文件已生成")

# 8. 保存 zhujiang.m3u8 文件
if zhujiang_channel:
with open("zhujiang.m3u8", "w", encoding="utf-8") as zhujiang_file:
zhujiang_file.write(zhujiang_channel)
print("zhujiang.m3u8 文件已生成")
else:
print("未找到“广东珠江”频道信息")
0%