Compare commits
13 Commits
43f7ab84b3
...
fbc3ef7f5b
Author | SHA1 | Date |
---|---|---|
![]() |
fbc3ef7f5b | |
![]() |
b249b749d1 | |
![]() |
51664d962d | |
![]() |
d1d1f8d50e | |
![]() |
6cbb92699a | |
![]() |
5e73cfe5b8 | |
![]() |
c2f0d0e5d1 | |
![]() |
a838f88610 | |
![]() |
e6760c6d72 | |
![]() |
40a07cbbc2 | |
![]() |
3a5d2e13fd | |
![]() |
37a4a6ec4d | |
![]() |
9a6a05e5af |
Binary file not shown.
|
@ -1 +1 @@
|
|||
f86f4034eea12ff0ccc59556719437d1
|
||||
ef69bccca6f1b89f487b45e2771cb2f5
|
||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
|||
4b09c54806c4f7dacfd502b0d33d46be
|
||||
709b0173f2e04d8b38df10838a16c32f
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
self 我的夸克网盘
|
||||
a632967760cf 电影/合集/以ABCD开头合集
|
||||
2f59bb5d96b9 电影/合集/以EFGH开头合集
|
||||
50828c368def 电影/合集/以IJKL开头合集
|
||||
e07e26aecc08 电影/合集/以MNOP开头合集
|
||||
0536a38a356e 电影/合集/以QRST开头合集
|
||||
e273ef697403 电影/合集/以UVWX开头合集
|
||||
c8ac6c88e5d8 电影/合集/以YZ开头合集
|
||||
49ab75d52e00 电影/合集/以数字开头合集
|
||||
8f1b4b7dc69e 电影/精选高画质高分电影
|
||||
5432beae4f1a 电影/韩国R级
|
||||
085212df385d 电视剧/TVB、ATV亚视
|
||||
cd4c5ac7e830 电视剧/已完结/数字开头
|
||||
d19c4ebe1ff7 电视剧/已完结/豆瓣评分9.0以上国产剧
|
||||
e1b2ba8b6d6c 电视剧/已完结/首字母ABCD
|
||||
166fa0a7ca6f 电视剧/已完结/首字母EFGH
|
||||
37a92c0b7f10 电视剧/已完结/首字母IJKL
|
||||
fb3386e42af2 电视剧/已完结/首字母NMOP
|
||||
46ce214f4ed7 电视剧/已完结/首字母QRST
|
||||
fe4681d7fb43 电视剧/已完结/首字母UVWX
|
||||
8d65e885b059 电视剧/已完结/首字母YZ
|
||||
d2dfa32647f6 音乐/书香音乐世纪典藏
|
||||
2b4978213b29 音乐/古典音乐精选合集
|
||||
651e5fa93057 音乐/大自然音乐系列合集
|
||||
12848381dce1 音乐/纯音乐合集
|
||||
805d76a08063 音乐/车载无损环绕音效音乐合集
|
||||
d1a0b7046b20 音乐/震撼心灵的史诗音乐合集
|
||||
a632967760cf 电影|合集|以ABCD开头合集
|
||||
2f59bb5d96b9 电影|合集|以EFGH开头合集
|
||||
50828c368def 电影|合集|以IJKL开头合集
|
||||
e07e26aecc08 电影|合集|以MNOP开头合集
|
||||
0536a38a356e 电影|合集|以QRST开头合集
|
||||
e273ef697403 电影|合集|以UVWX开头合集
|
||||
c8ac6c88e5d8 电影|合集|以YZ开头合集
|
||||
49ab75d52e00 电影|合集|以数字开头合集
|
||||
8f1b4b7dc69e 电影|精选高画质高分电影
|
||||
5432beae4f1a 电影|韩国R级
|
||||
085212df385d 电视剧|TVB、ATV亚视
|
||||
cd4c5ac7e830 电视剧|已完结|数字开头
|
||||
d19c4ebe1ff7 电视剧|已完结|豆瓣评分9.0以上国产剧
|
||||
e1b2ba8b6d6c 电视剧|已完结|首字母ABCD
|
||||
166fa0a7ca6f 电视剧|已完结|首字母EFGH
|
||||
37a92c0b7f10 电视剧|已完结|首字母IJKL
|
||||
fb3386e42af2 电视剧|已完结|首字母NMOP
|
||||
46ce214f4ed7 电视剧|已完结|首字母QRST
|
||||
fe4681d7fb43 电视剧|已完结|首字母UVWX
|
||||
8d65e885b059 电视剧|已完结|首字母YZ
|
||||
d2dfa32647f6 音乐|书香音乐世纪典藏
|
||||
2b4978213b29 音乐|古典音乐精选合集
|
||||
651e5fa93057 音乐|大自然音乐系列合集
|
||||
12848381dce1 音乐|纯音乐合集
|
||||
805d76a08063 音乐|车载无损环绕音效音乐合集
|
||||
d1a0b7046b20 音乐|震撼心灵的史诗音乐合集
|
||||
6b795218342d 动漫
|
||||
ece52d63b698 小品相声/2024德云社
|
||||
e827264ea453 小品相声/小品大合集
|
||||
d8b4a584fd1a 小品相声/小品纯享合集
|
||||
ece52d63b698 小品相声|2024德云社
|
||||
e827264ea453 小品相声|小品大合集
|
||||
d8b4a584fd1a 小品相声|小品纯享合集
|
||||
885fd4ba2d92 每日短剧更新
|
||||
432b5cd3a225 短剧162g
|
||||
c54a8e47f82f 短剧114g
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"thunder_username":"",
|
||||
"thunder_password":"",
|
||||
"thunder_captchatoken":"",
|
||||
"yd_auth":"cGM6MTg3NzQ5NzMzNjM6YWdkYlRhWGR8MXxSQ1N8MTc0NDM3NDUxNjIxOHxkRnRScENBOFpZdm9EemFmVFNWZVdndlBWa0tSZjdkU3pBdnlkR0s4anZ2VFBlenl6OWVJX1VfNl94V2o1ZUZOSzdtOUtENXIuRHVPOG43RWdmV2lWc1J5YnZiSmF3NjhSMnhuMHlrSzVMd19Vcm0zZTQyOExUblFfTW1lMVRNNjIxdWRIa2U1NUJTdC5yMk1NbTc5RkxQZDAubHluMjFvVkNwa1FDTWNtYVkt",
|
||||
"yd_auth":"",
|
||||
"yd_thread_limit":4,
|
||||
"yd_flags":"auto|4kz",
|
||||
"yd_danmu":true,
|
||||
|
|
|
@ -1 +1 @@
|
|||
64a103fcb252b9eb0f3176c870f084bc
|
||||
afda4f34509f1b5fe74c07241a5c4f58
|
|
@ -24,7 +24,7 @@
|
|||
{"key":"csp_Ikanbot","name":"👾Ikanbot","type":3,"api":"csp_Ikanbot","searchable":1,"quickSearch":1,"filterable":1},
|
||||
{"key":"csp_Jianpian","name":"🧲荐片","type":3,"api":"csp_Jianpian","searchable":1,"quickSearch":1,"filterable":1,"ext":"./json/jianpian.json"},
|
||||
{"key":"csp_xlys","name":"🧲修罗","type":3,"api":"csp_xlys","searchable":1,"quickSearch":1,"filterable":1,"ext":"https://v.xlys.ltd.ua"},
|
||||
{"key":"csp_Mp4Mov","name":"🧲Mp4电影","type":3,"api":"csp_Mp4Mov","searchable":1,"quickSearch":1,"filterable":1,"ext":"https://www.momp4.cc"},
|
||||
{"key":"csp_Mp4Mov","name":"🧲Mp4电影","type":3,"api":"csp_Mp4Mov","searchable":1,"quickSearch":1,"filterable":1,"ext":"https://www.xlmp4.com"},
|
||||
{"key":"csp_New6v","name":"🧲新6V","type":3,"api":"csp_New6v","searchable":1,"quickSearch":1,"filterable":1},
|
||||
{"key":"csp_DyGod","name":"🧲电影天堂","type":3,"api":"csp_DyGod","searchable":1,"quickSearch":1,"filterable":1},
|
||||
{"key":"csp_QnMp4","name":"🧲七妹","type":3,"api":"csp_QnMp4","searchable":1,"quickSearch":1,"filterable":1},
|
||||
|
@ -56,7 +56,6 @@
|
|||
{"key":"星剧社","name":"⭐️星剧社","type":3,"api":"csp_Star2","searchable":1,"filterable":0,"switchable":0,"ext":{"siteUrl":"https://star.banye.tech:7086/","commonConfig":"./json/peizhi.json"}},
|
||||
{"key":"csp_PanSearch","name":"📀盘搜索","type":3,"api":"csp_PanSearch","searchable":1,"changeable":0,"ext":{"commonConfig":"./json/peizhi.json"}},
|
||||
{"key":"木偶","name":"🧸木偶","type":3,"api":"csp_kongbai","searchable":1,"changeable":0,"ext":{"commonConfig":"./json/peizhi.json","siteUrl":"http://123.666291.xyz//","filter":"./json/wogg.json"}},
|
||||
{"key":"MIUC","name":"💌MIUC","type":3,"api":"csp_kongbai","searchable":1,"changeable":0,"ext":{"commonConfig":"./json/peizhi.json","siteUrl":"https://mucpan.cc/","filter":"./json/wogg.json"}},
|
||||
{"key":"闪电","name":"⚡闪电","type":3,"api":"csp_kongbai","searchable":1,"changeable":0,"ext":{"commonConfig":"./json/peizhi.json","siteUrl":"http://1.95.79.193","filter":"./json/wogg.json"}},
|
||||
{"key":"盘Ta","name":"🍥盘Ta","type":3,"api":"csp_PanTa","searchable":1,"filterable":0,"switchable":0,"ext":{"siteUrl":"https://www.91panta.cn/","commonConfig":"./json/peizhi.json"}},
|
||||
{"key":"易搜","name":"🆎易搜","type":3,"api":"csp_YiSo","searchable":1,"filterable":0,"switchable":0,"ext":{"cookie":"satoken=0eedba28-be8a-4f01-81af-2d8d44808ecf","commonConfig":"./json/peizhi.json"}},
|
||||
|
|
198
南风/live.txt
198
南风/live.txt
|
@ -1,13 +1,9 @@
|
|||
央视,#genre#
|
||||
CCTV1,http://home.kuaidi521.com:35455/gaoma/cctv1.m3u8
|
||||
CCTV1,http://xiaoya.crccxw.top:35455/gaoma/cctv1.m3u8
|
||||
CCTV1,http://58.220.219.14:9901/tsfile/live/0001_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV1,http://175.31.21.146:4480/hls/1/index.m3u8
|
||||
CCTV1,http://58.220.211.90:352/tsfile/live/0001_1.m3u8?key=txiptv&playlive=1&authid$LR•IPV4『线路274』
|
||||
CCTV1,http://58.220.211.90:352/tsfile/live/0001_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路275』
|
||||
CCTV1,http://3501776.xyz:35455/gaoma/cctv1.m3u8
|
||||
CCTV1,http://112.81.218.254:35455/gaoma/cctv1.m3u8
|
||||
CCTV1,http://183.184.228.183:9003//hls/1/index.m3u8
|
||||
CCTV1,http://113.140.12.230:8888/newlive/live/hls/2/live.m3u8
|
||||
CCTV1,http://222.219.183.103:8089/hls/1/index.m3u8
|
||||
CCTV1,http://58.210.168.86:10800/newlive/live/hls/1/live.m3u8
|
||||
|
@ -15,124 +11,72 @@ CCTV2,http://222.169.85.8:9901/tsfile/live/0002_1.m3u8?key=txiptv&playlive=1&aut
|
|||
CCTV2,http://39.164.160.249:9901/tsfile/live/0002_1.m3u8
|
||||
CCTV2,http://175.31.21.146:4480/hls/2/index.m3u8
|
||||
CCTV2,http://116.128.243.121:85/tsfile/live/0002_1.m3u8?key=txiptv&playlive=0&authid=0
|
||||
CCTV2,http://3501776.xyz:35455/gaoma/cctv2.m3u8
|
||||
CCTV2,http://222.134.245.16:9901/tsfile/live/0002_1.m3u8
|
||||
CCTV2,http://183.184.228.183:9003//hls/2/index.m3u8
|
||||
CCTV2,http://113.140.12.230:8888/newlive/live/hls/3/live.m3u8
|
||||
CCTV2,http://60.223.224.176:8888/newlive/live/hls/3/live.m3u8
|
||||
CCTV3,http://222.134.19.31:352/tsfile/live/0003_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路247』
|
||||
CCTV3,http://222.134.19.31:352/tsfile/live/0003_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV3,http://60.223.224.176:8888/newlive/live/hls/4/live.m3u8
|
||||
CCTV3,http://113.140.12.230:8888/newlive/live/hls/4/live.m3u8
|
||||
CCTV3,http://222.134.245.16:9901/tsfile/live/0003_1.m3u8
|
||||
CCTV3,http://222.169.85.8:9901/tsfile/live/0003_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV3,http://222.169.85.8:9901/tsfile/live/0003_1.m3u8
|
||||
CCTV3,http://112.46.85.60:8009/hls/3/index.m3u8
|
||||
CCTV3,http://3501776.xyz:35455/gaoma/cctv3.m3u8
|
||||
CCTV3,http://183.184.228.183:9003//hls/3/index.m3u8
|
||||
CCTV3,http://218.29.168.146:352/tsfile/live/0003_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV3,http://58.220.219.14:9901/tsfile/live/0003_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV4,http://183.66.15.146:60901/tsfile/live/0004_1.m3u8?key=txiptv$LR•IPV4『线路190』
|
||||
CCTV4,http://183.184.228.183:9003//hls/4/index.m3u8
|
||||
CCTV4,http://113.140.12.230:8888/newlive/live/hls/5/live.m3u8
|
||||
CCTV4,http://60.223.224.176:8888/newlive/live/hls/5/live.m3u8?
|
||||
CCTV4,http://222.219.183.103:8089/hls/4/index.m3u8
|
||||
CCTV5,http://42.225.117.174:11199/tsfile/live/0005_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV5,http://112.81.218.254:35455/gaoma/cctv5.m3u8
|
||||
CCTV5,http://222.134.19.31:352/tsfile/live/0005_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV5,http://60.223.224.176:8888/newlive/live/hls/6/live.m3u8
|
||||
CCTV5,http://113.140.12.230:8888/newlive/live/hls/6/live.m3u8
|
||||
CCTV5,http://116.9.204.242:9901/tsfile/live/0005_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路177』
|
||||
CCTV5,http://61.133.10.250:352/tsfile/live/0005_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路269』
|
||||
CCTV5,http://home.kuaidi521.com:35455/gaoma/cctv5.m3u8
|
||||
CCTV5,http://222.134.245.16:9901/tsfile/live/0005_1.m3u8
|
||||
CCTV5,http://116.9.204.242:9901/tsfile/live/0005_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV5,http://116.9.204.242:9901/tsfile/live/0005_1.m3u8
|
||||
CCTV5,http://183.184.228.183:9003//hls/5/index.m3u8
|
||||
CCTV5,http://xiaoya.crccxw.top:35455/gaoma/cctv5.m3u8
|
||||
CCTV5+,http://home.kuaidi521.com:35455/gaoma/cctv5p.m3u8
|
||||
CCTV5+,http://xiaoya.crccxw.top:35455/gaoma/cctv5p.m3u8
|
||||
CCTV5+,http://112.81.218.254:35455/gaoma/cctv5p.m3u8
|
||||
CCTV5+,http://222.219.183.103:8089/hls/19/index.m3u8
|
||||
CCTV5+,http://183.184.228.183:9003//hls/6/index.m3u8
|
||||
CCTV5+,http://182.37.169.94:352/tsfile/live/0016_1.m3u8
|
||||
CCTV6,http://222.134.19.31:352/tsfile/live/0006_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV6,http://39.170.52.236:808/hls/6/index.m3u8
|
||||
CCTV6,http://113.140.12.230:8888/newlive/live/hls/7/live.m3u8
|
||||
CCTV6,http://222.169.85.8:9901/tsfile/live/0006_1.m3u8?key=txiptv
|
||||
CCTV6,http://zzssw01.55555.io:9901/tsfile/live/0006_1.m3u8
|
||||
CCTV6,http://101.19.84.8:9901/tsfile/live/0006_1.m3u8
|
||||
CCTV6,http://183.184.228.183:9003//hls/7/index.m3u8
|
||||
CCTV7,http://8.138.7.223/tv/cctv7.m3u8
|
||||
CCTV7,http://60.223.224.176:8888/newlive/live/hls/9/live.m3u8
|
||||
CCTV7,https://live.junhao.mil.cn/rmt9502/3e6e7c5477314ec38f5e58e2a5c70024.m3u8?txSecret=57978fafb9c19880afa5c8687e8241d8&txTime=7A42BAFF
|
||||
CCTV7,http://live.junhao.mil.cn/rmt9502/3e6e7c5477314ec38f5e58e2a5c70024.m3u8?txSecret=57978fafb9c19880afa5c8687e8241d8&txTime=7A42BAFF
|
||||
CCTV7,http://xiaoya.crccxw.top:35455/gaoma/cctv7.m3u8
|
||||
CCTV7,http://home.kuaidi521.com:35455/gaoma/cctv7.m3u8
|
||||
CCTV7,http://101.19.84.8:9901/tsfile/live/0007_1.m3u8
|
||||
CCTV7,http://183.184.228.183:9003//hls/8/index.m3u8
|
||||
CCTV7,http://112.81.218.254:35455/gaoma/cctv7.m3u8
|
||||
CCTV7,http://222.219.183.103:8089/hls/7/index.m3u8
|
||||
CCTV8,http://112.81.218.254:35455/gaoma/cctv8.m3u8
|
||||
CCTV8,http://222.134.19.31:352/tsfile/live/0008_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV8,http://3501776.xyz:35455/gaoma/cctv8.m3u8
|
||||
CCTV8,http://home.kuaidi521.com:35455/gaoma/cctv8.m3u8
|
||||
CCTV8,http://112.46.85.60:8009/hls/8/index.m3u8
|
||||
CCTV8,http://101.19.84.8:9901/tsfile/live/0008_1.m3u8
|
||||
CCTV8,http://183.184.228.183:9003//hls/9/index.m3u8
|
||||
CCTV8,http://113.140.12.230:8888/newlive/live/hls/9/live.m3u8
|
||||
CCTV8,http://xiaoya.crccxw.top:35455/gaoma/cctv8.m3u8
|
||||
CCTV8,http://60.223.224.176:8888/newlive/live/hls/10/live.m3u8?
|
||||
CCTV8,http://61.133.10.250:352/tsfile/live/0008_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV9,http://112.81.218.254:35455/gaoma/cctv9.m3u8
|
||||
CCTV9,http://42.225.117.174:11199/tsfile/live/0009_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV9,http://180.213.174.225:9901/tsfile/live/0009_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV9,http://3501776.xyz:35455/gaoma/cctv9.m3u8
|
||||
CCTV9,http://xiaoya.crccxw.top:35455/gaoma/cctv9.m3u8
|
||||
CCTV9,http://home.kuaidi521.com:35455/gaoma/cctv9.m3u8
|
||||
CCTV9,http://183.184.228.183:9003//hls/10/index.m3u8
|
||||
CCTV9,http://60.223.224.176:8888/newlive/live/hls/11/live.m3u8?
|
||||
CCTV9,http://222.219.183.103:8089/hls/9/index.m3u8
|
||||
CCTV10,http://42.225.117.174:11199/tsfile/live/0010_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV10,http://112.81.218.254:35455/gaoma/cctv10.m3u8
|
||||
CCTV10,http://39.164.160.249:9901/tsfile/live/0010_1.m3u8
|
||||
CCTV10,http://3501776.xyz:35455/gaoma/cctv10.m3u8
|
||||
CCTV10,http://xiaoya.crccxw.top:35455/gaoma/cctv10.m3u8
|
||||
CCTV10,http://113.140.12.230:8888/newlive/live/hls/11/live.m3u8
|
||||
CCTV10,http://222.169.85.8:9901/tsfile/live/0010_1.m3u8
|
||||
CCTV10,http://222.219.183.103:8089/hls/10/index.m3u8
|
||||
CCTV10,http://183.184.228.183:9003//hls/11/index.m3u8
|
||||
CCTV10,http://60.223.224.176:8888/newlive/live/hls/12/live.m3u8
|
||||
CCTV10,http://182.37.169.94:352/tsfile/live/0010_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV11,http://112.81.218.254:35455/gaoma/cctv11.m3u8
|
||||
CCTV11,http://39.164.160.249:9901/tsfile/live/0011_1.m3u8
|
||||
CCTV11,http://home.kuaidi521.com:35455/gaoma/cctv11.m3u8
|
||||
CCTV12,http://112.81.218.254:35455/gaoma/cctv12.m3u8
|
||||
CCTV12,http://home.kuaidi521.com:35455/gaoma/cctv12.m3u8
|
||||
CCTV12,http://39.164.160.249:9901/tsfile/live/0012_1.m3u8
|
||||
CCTV12,http://xiaoya.crccxw.top:35455/gaoma/cctv12.m3u8
|
||||
CCTV12,http://183.184.228.183:9003//hls/13/index.m3u8
|
||||
CCTV13,http://61.163.181.78:9901/tsfile/live/0013_1.m3u8
|
||||
CCTV13,https://event.pull.hebtv.com/jishi/cp1.m3u8
|
||||
CCTV13,http://ali-m-l.cztv.com/channels/lantian/channel21/1080p.m3u8
|
||||
CCTV13,http://183.215.134.239:19901/tsfile/live/0013_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV13,http://39.164.160.249:9901/tsfile/live/0013_1.m3u8
|
||||
CCTV13,http://112.81.218.254:35455/gaoma/cctv13.m3u8
|
||||
CCTV13,http://183.184.228.183:9003//hls/14/index.m3u8
|
||||
CCTV14,http://112.81.218.254:35455/gaoma/cctv14.m3u8
|
||||
CCTV14,https://event.pull.hebtv.com/jishi/cp2.m3u8
|
||||
CCTV14,http://42.225.117.174:11199/tsfile/live/0014_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV14,http://3501776.xyz:35455/gaoma/cctv14.m3u8
|
||||
CCTV14,http://39.164.160.249:9901/tsfile/live/0014_1.m3u8
|
||||
CCTV14,http://58.17.48.228:808/hls/14/index.m3u8
|
||||
CCTV14,http://222.173.108.238:352/tsfile/live/0014_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
CCTV14,http://183.184.228.183:9003//hls/15/index.m3u8
|
||||
CCTV15,http://39.164.160.249:9901/tsfile/live/0015_1.m3u8
|
||||
CCTV15,http://home.kuaidi521.com:35455/gaoma/cctv15.m3u8
|
||||
CCTV16,http://xiaoya.crccxw.top:35455/gaoma/cctv16.m3u8
|
||||
CCTV16,http://112.81.218.254:35455/gaoma/cctv16.m3u8
|
||||
CCTV16,http://183.184.228.183:9003//hls/17/index.m3u8
|
||||
CCTV17,http://112.81.218.254:35455/gaoma/cctv17.m3u8
|
||||
CCTV17,http://xiaoya.crccxw.top:35455/gaoma/cctv17.m3u8
|
||||
CCTV风云剧场,http://dassby.qqff.top:99/live/风云剧场/index.m3u8
|
||||
CCTV20241,https://p2.bdstatic.com/rtmp.liveshow.lss-user.baidubce.com/live/stream_bduid_6488563992_8982723413/merged_1707497046297_88536_25144_41936.m3u8
|
||||
|
@ -142,15 +86,8 @@ CCTV15,http://113.57.20.158:9901/tsfile/live/1034_1.m3u8?key=txiptv&playlive=1&a
|
|||
CCTV16,http://58.221.214.82:9901/tsfile/live/0002_2.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路88』
|
||||
CCTV17,http://58.221.214.82:9901/tsfile/live/0003_2.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路130』
|
||||
CCTV17,http://183.223.157.33:9901/tsfile/live/0016_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路132』
|
||||
CCTV1,http://60.7.56.33:4000/rtp/239.253.92.83:8012$1920x1080
|
||||
CCTV2,http://60.7.56.33:4000/rtp/239.253.92.190:6065$1920x1080
|
||||
CCTV4,http://60.7.56.33:4000/rtp/239.253.93.192:6370$1920x1080
|
||||
CCTV5,http://60.7.56.33:4000/rtp/239.253.92.181:6046$1920x1080
|
||||
CCTV5+,http://60.7.56.33:4000/rtp/239.253.92.82:8013$1920x1080
|
||||
CCTV6,http://60.7.56.33:4000/rtp/239.253.92.193:6058$1920x1080
|
||||
CCTV7,http://111.160.17.2:59901/tsfile/live/0001_8.m3u8
|
||||
CCTV11,http://61.136.172.236:9901/tsfile/live/0011_1.m3u8
|
||||
CCTV12,http://60.7.56.33:4000/rtp/239.253.92.197:6062$1920x1080
|
||||
CCTV13,http://61.136.172.236:9901/tsfile/live/0013_1.m3u8
|
||||
CCTV13,http://123.129.70.178:9901/tsfile/live/0013_1.m3u8
|
||||
CCTV15,http://61.136.172.236:9901/tsfile/live/0015_1.m3u8
|
||||
|
@ -161,10 +98,8 @@ CCTV15,http://61.156.228.12:8154/tsfile/live/0015_1.m3u8
|
|||
安多卫视,https://liveout.xntv.tv/a65jur/96iln2.m3u8
|
||||
安多卫视,https://livecdn.dmqhyadmin.com/hls/xjmenyuan.m3u8
|
||||
安徽卫视,http://115.149.139.141:10000/tsfile/live/1028_1.m3u8?key=txiptv&playlive=0&authid=0
|
||||
安徽卫视,http://39.164.160.249:9901/tsfile/live/0130_1.m3u8
|
||||
北京卫视,http://183.215.134.239:19901/tsfile/live/0122_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
北京卫视,http://115.149.139.141:10000/tsfile/live/1022_1.m3u8?key=txiptv&playlive=0&authid=0
|
||||
北京卫视,http://42.225.117.174:11199/tsfile/live/0122_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
北京卫视,http://58.220.219.14:9901/tsfile/live/0122_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
兵团卫视,http://liveout.btzx.com.cn/62ds9e/yil08g.m3u8
|
||||
兵团卫视,https://liveout.btzx.com.cn/62ds9e/yil08g.m3u8
|
||||
|
@ -175,40 +110,29 @@ CCTV15,http://61.156.228.12:8154/tsfile/live/0015_1.m3u8
|
|||
重庆卫视,http://222.173.108.238:352/tsfile/live/1016_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
大湾区卫视,http://222.128.55.152:9080/live/dwq.m3u8
|
||||
东方卫视,http://183.215.134.239:19901/tsfile/live/0107_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
东方卫视,http://39.164.160.249:9901/tsfile/live/0107_1.m3u8
|
||||
东南卫视,http://120.76.248.139/live/bfgd/4200000483.m3u8
|
||||
东南卫视,http://115.149.139.141:10001/tsfile/live/1035_1.m3u8?blog.ntnas.top
|
||||
东南卫视,http://220.164.192.48:50085/tsfile/live/0120_1.m3u8
|
||||
甘肃卫视,http://live.zohi.tv/video/s10001-fztv-3/index.m3u8
|
||||
广东卫视,http://183.215.134.239:19901/tsfile/live/0125_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
广东卫视,http://115.149.139.141:10001/tsfile/live/1029_1.m3u8?blog.ntnas.top
|
||||
广东卫视,http://222.173.108.238:352/tsfile/live/0125_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
广东卫视,http://39.164.160.249:9901/tsfile/live/0125_1.m3u8
|
||||
广西卫视,http://live.cztv.cc:85/live/ggpd.m3u8
|
||||
广西卫视,http://42.225.117.174:11199/tsfile/live/0113_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
广西卫视,http://115.149.139.141:10000/tsfile/live/1037_1.m3u8?key=txiptv&playlive=0&authid=0
|
||||
广西卫视,http://220.164.192.48:50085/tsfile/live/0112_1.m3u8
|
||||
广西卫视,http://115.149.139.141:10001/tsfile/live/1037_1.m3u8?blog.ntnas.top
|
||||
广西卫视,http://116.9.204.242:9901/tsfile/live/0113_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
广西卫视,http://116.9.204.242:9901/tsfile/live/0113_1.m3u8
|
||||
贵州卫视,http://39.164.160.249:9901/tsfile/live/0120_1.m3u8
|
||||
河北卫视,http://116.131.190.210:352/tsfile/live/0117_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
河北卫视,http://60.8.49.38:352/tsfile/live/0117_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
河南卫视,http://42.225.117.174:11199/tsfile/live/0139_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
河南卫视,http://39.164.160.249:9901/tsfile/live/0139_1.m3u8
|
||||
黑龙江卫视,http://115.149.139.141:10000/tsfile/live/1030_1.m3u8?key=txiptv&playlive=0&authid=0
|
||||
黑龙江卫视,http://39.164.160.249:9901/tsfile/live/0143_1.m3u8
|
||||
湖北卫视,http://115.149.139.141:10001/tsfile/live/1027_1.m3u8
|
||||
湖南卫视,http://183.215.134.239:19901/tsfile/live/0128_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
湖南卫视,http://39.164.160.249:9901/tsfile/live/0128_1.m3u8
|
||||
湖南卫视,http://60.223.224.176:8888/newlive/live/hls/22/live.m3u8
|
||||
吉林卫视,http://220.164.192.48:50085/tsfile/live/0118_1.m3u8
|
||||
江苏卫视,http://42.225.117.174:11199/tsfile/live/0127_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
江西卫视,http://120.76.248.139/live/bfgd/4200000098.m3u8
|
||||
江西卫视,http://183.215.134.239:19901/tsfile/live/0138_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
江西卫视,http://222.173.108.238:352/tsfile/live/1010_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
辽宁卫视,http://222.173.108.238:352/tsfile/live/1008_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
辽宁卫视,http://39.164.160.249:9901/tsfile/live/0121_1.m3u8
|
||||
辽宁卫视,http://115.149.139.141:10001/tsfile/live/1028_1.m3u8
|
||||
辽宁卫视,http://115.149.139.141:10001/tsfile/live/1028_1.m3u8?blog.ntnas.top
|
||||
内蒙古蒙语卫视,https://livestream-bt.nmtv.cn/nmtv/2315general.m3u8?txSecret=4971666599ef9411629213c9a300bf66&txTime=771EF880
|
||||
|
@ -218,9 +142,7 @@ CCTV15,http://61.156.228.12:8154/tsfile/live/0015_1.m3u8
|
|||
厦门卫视,http://220.161.87.62:8090/hls/0/index.m3u8?zfud
|
||||
山东卫视,http://120.76.248.139/live/bfgd/4200000099.m3u8
|
||||
山西卫视,http://m3u8.channel.wsrtv.com.cn/cms/videos/nmip-media/channellive/channel7/playlist.m3u8
|
||||
山西卫视,http://42.225.117.174:11199/tsfile/live/0118_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
山西卫视,http://60.223.224.176:8888/newlive/live/hls/43/live.m3u8?
|
||||
陕西卫视,http://42.225.117.174:11199/tsfile/live/0136_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
深圳卫视,http://120.76.248.139/live/bfgd/4200000100.m3u8
|
||||
深圳卫视,http://115.149.139.141:10000/tsfile/live/1032_1.m3u8?key=txiptv&playlive=0&authid=0
|
||||
深圳卫视,http://183.215.134.239:19901/tsfile/live/0126_1.m3u8?key=txiptv&playlive=1&authid=0
|
||||
|
@ -231,7 +153,6 @@ CCTV15,http://61.156.228.12:8154/tsfile/live/0015_1.m3u8
|
|||
亚洲卫视,https://p2hs.vzan.com/slowlive/821481626725612419/live.m3u8
|
||||
延边卫视,http://l.cztvcloud.com/channels/lantian/SXxinchang2/720p.m3u8
|
||||
延边卫视,http://l.cztvcloud.com/channels/lantian/SXxinchang2/720p.m3u8$LR•IPV4『线路20』
|
||||
云南卫视,http://39.164.160.249:9901/tsfile/live/0119_1.m3u8
|
||||
浙江卫视,https://ali-m-l.cztv.com/channels/lantian/channel001/1080p.m3u8?
|
||||
浙江卫视,http://ali-m-l.cztv.com:80/channels/lantian/channel001/1080p.m3u8
|
||||
浙江卫视,https://ali-m-l.cztv.com/channels/lantian/channel001/1080p.m3u8
|
||||
|
@ -243,7 +164,6 @@ CCTV15,http://61.156.228.12:8154/tsfile/live/0015_1.m3u8
|
|||
浙江卫视,http://wouu.net:9977/udp/239.93.0.124:5140$LR•IPV4『线路157』
|
||||
北京卫视,http://61.156.228.12:8154/tsfile/live/0122_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路83』
|
||||
北京卫视,http://123.129.70.178:9901/tsfile/live/0122_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路88』
|
||||
江苏卫视,http://124.128.73.58:9901/tsfile/live/0127_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路95』
|
||||
安徽卫视,http://123.129.70.178:9901/tsfile/live/0130_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路73』
|
||||
安徽卫视,http://61.136.172.236:9901/tsfile/live/0130_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路75』
|
||||
安徽卫视,http://61.156.228.12:8154/tsfile/live/0130_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路76』
|
||||
|
@ -252,7 +172,6 @@ CCTV15,http://61.156.228.12:8154/tsfile/live/0015_1.m3u8
|
|||
深圳卫视,http://123.129.70.178:9901/tsfile/live/0126_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路68』
|
||||
广东卫视,http://123.129.70.178:9901/tsfile/live/0125_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路88』
|
||||
广西卫视,http://61.136.172.236:9901/tsfile/live/0113_1.m3u8?key=txiptv&playlive=1&authid=0$LR•IPV4『线路54』
|
||||
天津卫视,http://60.7.56.33:4000/rtp/239.253.92.91:8021$1920x1080
|
||||
青海卫视,http://stream.qhbtv.com/qhws/sd/live.m3u8
|
||||
三沙卫视,https://pullsstv90080111.ssws.tv/live/SSTV20220729.m3u8
|
||||
安多卫视,http://stream.qhbtv.com/adws/sd/live.m3u8
|
||||
|
@ -270,87 +189,52 @@ CCTV15,http://61.156.228.12:8154/tsfile/live/0015_1.m3u8
|
|||
|
||||
|
||||
IPV6,#genre#
|
||||
CCTV-1,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226895/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EI0Rkc6neBYgfpoJ1yud8Fw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPpqgHe3PQ5GNQoO-yUgA8C%2CEND
|
||||
CCTV-3,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226456/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E_6GNVcVOz9Xub8CclyMRUg%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOIR_8g_qYRqpV5wTQqRILi%2CEND
|
||||
CCTV-4,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226470/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E0wP1dRMt9qCzHdvA65wh1w%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMcuN2HH7RLPyPHWOUWhSMk%2CEND
|
||||
CCTV5,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226454/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7ErKwB8Qqtvssoy-K7GEgesQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOIR_8g_qYRqpV5wTQqRILi%2CEND
|
||||
CCTV5+,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226458/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Em70vyfVI_MkrcLYjHWnqOA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNlS0O1LA8iGydXPYujpRue%2CEND
|
||||
CCTV6,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226453/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ex56LEwufYqPdJkUNYhbNCw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOH2PzEhAK60LI_FWtVxfVS%2CEND
|
||||
CCTV7,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226234/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EutDC7HLJc_gC0YdIDr7oig%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPOHuulzlCcw92vP3vgYa4n%2CEND
|
||||
CCTV8,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226451/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EO_1NY-UghfdG_S28Bf_FPw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNO1anuaDcpMt0_BMig72trX%2CEND
|
||||
CCTV10,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226449/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EzhRgoBfyoaW0eC2lnTJYAQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOxqyo6ss4VuHKCaIhF4e3B%2CEND
|
||||
CCTV11,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226334/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E0RcQQbNseiHvFO8XWf466A%7EtP4-l0lmSfjwLWEfK_el1vH_mv-s1zo4AQJwdedaVwG9xkuFTDg8J26cwOrNJzn20BErrHdLhuZ9EzLUCD3PMW-OMx4MGteHV2vLeW6BqoY%2CEND
|
||||
CCTV11,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226448/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Eqfhzy1ZrFZrYrATDOB991A%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOu522yjh6D1Z_dApuOt9eE%2CEND
|
||||
CCTV12,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226228/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E2knJCFLHz_HqfBZXNGeA1A%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMIlZ5z7o_ym15iMooogSvj%2CEND
|
||||
CCTV13,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226316/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EqHPe9pEEWJ00hz1ArnRZVA%7EtP4-l0lmSfjwLWEfK_el1vH_mv-s1zo4AQJwdedaVwG9xkuFTDg8J26cwOrNJzn20BErrHdLhuZ9EzLUCD3PMW-OMx4MGteHV2vLeW6BqoY%2CEND
|
||||
CCTV13,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226446/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EU-IJJyzlYeEElWsacI4JKw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMT7DWkynQtRPzNDJCOY_C_%2CEND
|
||||
CCTV14,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226229/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ey_UgKg-_uoDiTW1MNHptPg%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNLabf3bHEXv4444iiOs_Px%2CEND
|
||||
CCTV15,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226444/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EFQ8BWVFffGkwLTLNv7CwFQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNM7I2coCeiP5K0pSIMZqcUB%2CEND
|
||||
CCTV16,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221227002/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EX9goLRw26BM_r54des2PAw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPt5W7-RovMDpE-7B-0PhHw%2CEND
|
||||
CCTV17,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226442/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EtihRNVe_x2y1Lgi_XWYeNw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOl8OnsD1vPD0mhNmo98J3J%2CEND
|
||||
CGTN,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226443/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ebu8iDniP_aAtg-APxKXKAA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOeLGc8fhipDF_paLm6VUd-%2CEND
|
||||
CCTV1,http://iptv.huuc.edu.cn/hls/cctv1hd.m3u8
|
||||
CCTV2,http://iptv.huuc.edu.cn/hls/cctv2hd.m3u8
|
||||
CCTV3,http://iptv.huuc.edu.cn/hls/cctv3hd.m3u8
|
||||
CCTV4,http://iptv.huuc.edu.cn/hls/cctv4hd.m3u8
|
||||
CCTV5,http://iptv.huuc.edu.cn/hls/cctv5hd.m3u8
|
||||
CCTV6,http://iptv.huuc.edu.cn/hls/cctv6hd.m3u8
|
||||
CCTV7,http://iptv.huuc.edu.cn/hls/cctv7hd.m3u8
|
||||
CCTV8,http://iptv.huuc.edu.cn/hls/cctv8hd.m3u8
|
||||
CCTV9,http://iptv.huuc.edu.cn/hls/cctv9hd.m3u8
|
||||
CCTV10,http://iptv.huuc.edu.cn/hls/cctv10hd.m3u8
|
||||
CCTV11,http://iptv.huuc.edu.cn/hls/cctv11hd.m3u8
|
||||
CCTV12,http://iptv.huuc.edu.cn/hls/cctv12hd.m3u8
|
||||
CCTV13,http://iptv.huuc.edu.cn/hls/cctv13hd.m3u8
|
||||
CCTV14,http://iptv.huuc.edu.cn/hls/cctv14hd.m3u8
|
||||
CGTN,http://iptv.huuc.edu.cn/hls/cgtnhd.m3u8
|
||||
CGTN英语,https://0472.org/hls/cgtn.m3u8
|
||||
CGTN记录,https://0472.org/hls/cgtnd.m3u8
|
||||
CGTN俄语,https://0472.org/hls/cgtne.m3u8
|
||||
CGTN法语,https://0472.org/hls/cgtnf.m3u8
|
||||
CGTN西语,https://0472.org/hls/cgtnx.m3u8
|
||||
CGTN阿语,https://0472.org/hls/cgtna.m3u8
|
||||
北京卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226900/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EcYPi33WFyhvd6SjmqUKhJg%7EtP4-l0lmSfjwLWEfK_el1vH_mv-s1zo4AQJwdedaVwG9xkuFTDg8J26cwOrNJzn20BErrHdLhuZ9EzLUCD3PMW-OMx4MGteHV2vLeW6BqoY%2CEND
|
||||
北京卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226436/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7ElMQ3ov45VmhzipweN5VstQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPg_yZ8DZHTaSU92MIl_o3b%2CEND
|
||||
深圳卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226245/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EFvxuZ6Kfg6J67sArVd0LuA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNO9YxM-C8gPFvQRk47-h2ok%2CEND
|
||||
湖北卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226240/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7ExfU_RR0RQok0w_xd7h22CQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPVnDV2fEBphgm3TP7hAHBx%2CEND
|
||||
东方卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226237/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EuOKqNaOUqqiJjXIfPoRPMQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNeqgYr1eA9ESriCOsl_DTz%2CEND
|
||||
浙江卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226247/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Eo6BokfP3WkB3SIXSrgvRBA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNP3w4GkbU9L7iRQ8H2vgzhF%2CEND
|
||||
吉林卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226533/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EicY_6znuOTlmMeE15TFEig%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNNUZpDp9cPVsM_M_ftJRVM%2CEND
|
||||
江苏卫视,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226242/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EJT6eqtJpcKnNhyUS90EOgw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNN1SxXwCt0S69Lq27ZMJpfR%2CEND
|
||||
山东卫视,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226244/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EycMz-PML_dQW8iLcNBkw7g%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMYCYLC04QAM6EBli1wTuET%2CEND
|
||||
黑龙江卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226239/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EEHwpSHKc5p-bHJfhpIWFig%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNM5Y8rTELLykZJHp-bmY2YW%2CEND
|
||||
东南卫视,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226496/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EkZUfG47p98m2PZiCsgkhyQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNM5EcQIH6BiwZavlhPLb4oJ%2CEND
|
||||
江西卫视,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226243/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EfPpe3gkzCutYMoqOQQZNzA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMVuW7agCgULnvgy9rhLyCH%2CEND
|
||||
云南卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226543/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EzQy9f4DIExLCs810r0Q6Kw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNO_hnHaWpTsMQwR98VJGduo%2CEND
|
||||
辽宁卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226488/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E0dsu8dOBmGQQO7fSrvySew%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNN4l9PIxeExdzsncIMJiPZb%2CEND
|
||||
重庆卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226518/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ey-ITbF7am-eD_R60rK2QcQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMWkDi37K3eowQvLymiiLyV%2CEND
|
||||
山西卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226531/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EokFa56wMKUpB1vaIjEe92A%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPoj5DNJHruOghC7vAQxinJ%2CEND
|
||||
海南卫视,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226574/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EZOP0PLu1-XG8_Ae0lTe9HQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNODcjESMU4f6yMuMuOuQbie%2CEND
|
||||
安徽卫视,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226490/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EcN5s_AlHugvAv9Pda6f9fA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOtRTFrO5eKiKNV40gMGHaS%2CEND
|
||||
甘肃卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226545/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EPxObabIs3mLyPmSf2HHtqQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNBE3K16ZfzYGIqbP6z6cGJ%2CEND
|
||||
青海卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226529/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ege4qzvU2ax15UdL3NFQ7AQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNdiWnhjH1amCOGECUhABr9%2CEND
|
||||
山东教育卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226526/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EEtk94qghXphElKOQlUC-Yw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOpyxkKQ6N6FjQz-LrJwo0o%2CEND
|
||||
宁夏卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226528/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E9-jWxE6tfiz7aO7MvbCY7Q%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMi3qn27U9rBeXpVrJ8eLy7%2CEND
|
||||
内蒙古卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226530/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EHHMwHAFmEx4xxtZRlWhCrg%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMZe-zTYLW-Yz0RcFLVr37n%2CEND
|
||||
陕西卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226532/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E6sNSqmLCqLFl_AJPBXp1qA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNO6b4uKEI14SNy0LDiw52LH%2CEND
|
||||
广西卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226534/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EpjsBggKPaCw3f-xlBWZWaQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMJYhPE64lykNkIsypBRZqO%2CEND
|
||||
厦门卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226542/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E0HuqirkTe1cAUljwazjNGw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMvSOYesmmWPPy5i3xS4Rsb%2CEND
|
||||
三沙卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226544/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Eb2dn60YQRxhB5rAyOnrv0g%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNO_hnHaWpTsMQwR98VJGduo%2CEND
|
||||
新疆卫视,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226546/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7ETtoZKRqwsL9SQjr1A0iH5g%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMREPnBLSH3b8pR7cnmo9am%2CEND
|
||||
西藏卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226527/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EmHuqUIe0F51C4h6xZanhig%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMi3qn27U9rBeXpVrJ8eLy7%2CEND
|
||||
兵团卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226541/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7ESv-rH0nF41q6pxKZKeRnNA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNN-56c_rnHTXQA4R-D0Dlau%2CEND
|
||||
延边卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221227045/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Eq0D3NdTUN7FuRzr8eJsbQA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNONS2RAhxb5u6NYaMGGM23S%2CEND
|
||||
康巴卫视,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221227027/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EkHMvBpWz4rccMxNvSRekpQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPtFfVFX0AVycM8b4Xmbcl4%2CEND
|
||||
嘉佳卡通,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226539/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EQDRyt1jaDU7f52NwPN526A%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOLcRNi6C1PMX5tGrYl_SiR%2CEND
|
||||
茶频道,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226548/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ec1XXmbKOEhI6pFYCxtVG9A%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOD3hCDGl7mDB_HDsnRfhB2%2CEND
|
||||
快乐垂钓,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226549/1.m3u8?GuardEncType=2&accountinfo=~~V2.0~RHz0NOpqUZZN1Iz6lVLkkg~_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNSiF8rKF1Pn2LepKMJ2cEG%2CEND
|
||||
超级电影,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226233/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EfPRR4mbRWhkCFuUCVm9THg%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNM4kysjLk_woYMRnu35KtBV%2CEND
|
||||
超级综艺,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226231/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ejm-KqHfTZezbm9C-325YiA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNnfpAUC20DSCXUyGpDggnK%2CEND
|
||||
超级体育,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226232/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Eg-EQHTrpbCOxNSgnFRbr4w%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMNhcQPODGVtsSVKlB7CbAh%2CEND
|
||||
金牌综艺,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221227004/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EkcfszuSJNo6WZ8h7xrIswA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMWi_zfgUXV5YnB6haFF-C2%2CEND
|
||||
北京IPTV 4K超清,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226550/1.m3u8?GuardEncType=2&accountinfo=~~V2.0~e2qS8h6u-xp3gd50vNr1sw~_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPPFD3HVWEytEVyliOxehfe%2CEND
|
||||
北京国际,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226510/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EIfgL7tTUNqHAIdgvKuwj8A%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPr9j5nfyiWS_jEXD6m401A%2CEND
|
||||
北京新闻,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226437/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EncK5uEAdYwWMsf8WJWI1mQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNO_LSIQh_h2P54Cz-MqgJqC%2CEND
|
||||
北京文艺,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226440/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EWrJcgMpdGPvZavpf4dmmrQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNhmwDsUZnvQgU5E5wiGA2g%2CEND
|
||||
北京体育休闲,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226438/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EeVAybrHg955d_IRT9e_uHQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMLCKqkSfuGOusJwBMwlCbz%2CEND
|
||||
北京影视,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226433/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EygquRbh9L0wUPRY53fsZWw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNO62IynDcU1yYDL1b4Xte8T%2CEND
|
||||
北京生活,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226514/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Es-PVNcPJsjr_oBdcXGT40g%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNMWvZ0r6eMXcXJOGrCpJiq1%2CEND
|
||||
北京财经,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226516/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Eh9_SEkmWeMdS1TMnIILZgg%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPIiicEW7OIvk1s-X-PXHqO%2CEND
|
||||
北京纪实科教,http://[2409:8087:1:20:20::29]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226434/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ejj3PtVjzl6ZzFdM-Vi1dmQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNPJa61jREJv4ZfZigyrxX0U%2CEND
|
||||
北京IPTV 淘电影,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226552/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EXOsrWMA-UCdUl1hQSR9EKw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNg3bzRax0E9tLmO9xgXVx8%2CEND
|
||||
北京IPTV 淘剧场,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226553/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EQaJ92NID2SpQlY6_VJVogg%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOuQYJeiYEeFWTkFfE86Vq-%2CEND
|
||||
北京IPTV 淘娱乐,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226551/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7Ex0efg9fpenP8E8lWJUb5Lg%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNg3bzRax0E9tLmO9xgXVx8%2CEND
|
||||
北京IPTV 淘BABY,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226554/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EN0sbBMpQv4sLsW5foy3YfA%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNg3bzRax0E9tLmO9xgXVx8%2CEND
|
||||
北京IPTV 萌宠TV,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226555/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E_PpxWPtvSZRFtu_Ged_-vQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNO0istnBuoA2R9ODSCqyIyS%2CEND
|
||||
中国教育1台,http://[2409:8087:1:20:20::2a]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226494/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EB8MrpAzJ_Bw12HHVBcZO6g%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNONWWecbSKZXNjh_5hExtTC%2CEND
|
||||
中国教育2台,http://[2409:8087:1:20:20::2c]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226537/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7E7AxXs4eTU2oiWrhopr9sHw%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNNxsM0Bor098BJglrhfEQTl%2CEND
|
||||
中国教育4台,http://[2409:8087:1:20:20::26]/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226557/1.m3u8?GuardEncType=2&accountinfo=%7E%7EV2.0%7EBzZToIaOOoaa_jAUfhUQHQ%7E_eNUbgU9sJGUcVVduOMKhafLvQUgE_zlz_7pvDimJNOD9BEmVSNbqSQpqXZxnxbk%2CEND
|
||||
北京卫视,http://iptv.huuc.edu.cn/hls/btv1hd.m3u8
|
||||
北京文艺,http://iptv.huuc.edu.cn/hls/btv2hd.m3u8
|
||||
北京体育,http://iptv.huuc.edu.cn/hls/btv6hd.m3u8
|
||||
北京影视,http://iptv.huuc.edu.cn/hls/btv4hd.m3u8
|
||||
北京新闻,http://iptv.huuc.edu.cn/hls/btv9hd.m3u8
|
||||
北京纪实,http://iptv.huuc.edu.cn/hls/btv11hd.m3u8
|
||||
湖南卫视,http://iptv.huuc.edu.cn/hls/hunanhd.m3u8
|
||||
浙江卫视,http://iptv.huuc.edu.cn/hls/zjhd.m3u8
|
||||
江苏卫视,http://iptv.huuc.edu.cn/hls/jshd.m3u8
|
||||
东方卫视,http://iptv.huuc.edu.cn/hls/dfhd.m3u8
|
||||
安徽卫视,http://iptv.huuc.edu.cn/hls/ahhd.m3u8
|
||||
黑龙江卫视,http://iptv.huuc.edu.cn/hls/hljhd.m3u8
|
||||
辽宁卫视,http://iptv.huuc.edu.cn/hls/lnhd.m3u8
|
||||
深圳卫视,http://iptv.huuc.edu.cn/hls/szhd.m3u8
|
||||
广东卫视,http://iptv.huuc.edu.cn/hls/gdhd.m3u8
|
||||
天津卫视,http://iptv.huuc.edu.cn/hls/tjhd.m3u8
|
||||
湖北卫视,http://iptv.huuc.edu.cn/hls/hbhd.m3u8
|
||||
山东卫视,http://iptv.huuc.edu.cn/hls/sdhd.m3u8
|
||||
重庆卫视,http://iptv.huuc.edu.cn/hls/cqhd.m3u8
|
||||
上海纪实,http://iptv.huuc.edu.cn/hls/docuchina.m3u8
|
||||
四川卫视,http://iptv.huuc.edu.cn/hls/schd.m3u8
|
||||
金鹰纪实,http://iptv.huuc.edu.cn/hls/gedocu.m3u8
|
||||
东南卫视,http://iptv.huuc.edu.cn/hls/dnhd.m3u8
|
||||
河北卫视,http://iptv.huuc.edu.cn/hls/hebhd.m3u8
|
||||
江西卫视,http://iptv.huuc.edu.cn/hls/jxhd.m3u8
|
||||
浙江新闻,https://ali-m-l.cztv.com/channels/lantian/channel007/1080p.m3u8
|
||||
浙江国际,https://ali-m-l.cztv.com/channels/lantian/channel010/1080p.m3u8
|
||||
浙江少儿,https://ali-m-l.cztv.com/channels/lantian/channel008/1080p.m3u8
|
||||
|
@ -377,7 +261,6 @@ CGTN阿语,https://0472.org/hls/cgtna.m3u8
|
|||
少儿频道,#genre#
|
||||
熊大熊二,https://newcntv.qcloudcdn.com/asp/hls/1200/0303000a/3/default/1733da751de64e6e910abda889d87a26/1200.m3u8
|
||||
福州少儿,http://live.zohi.tv/video/s10001-fztv-4/index.m3u8
|
||||
武汉少儿,http://stream.appwuhan.com/7tzb/sd/live.m3u8
|
||||
GOOD卡通,https://dqhxk7sbp7xog.cloudfront.net/osmflivech45.m3u8
|
||||
倒霉特熊,https://newcntv.qcloudcdn.com/asp/hls/1200/0303000a/3/default/87f87ba569c147e3805f80e4844d2de9/1200.m3u8
|
||||
雲朵妈妈,https://newcntv.qcloudcdn.com/asp/hls/1200/0303000a/3/default/d8ad434c6b08421a927557a4d98da65c/1200.m3u8
|
||||
|
@ -399,7 +282,6 @@ key=0b292c335e5837e947f9409c59228f3e6
|
|||
新昌休闲影视,http://l.cztvcloud.com/channels/lantian/SXxinchang2/720p.m3u8
|
||||
石河子影视文体,http://124.88.144.73:1935/live/jjsh/HasBahCa.m3u8
|
||||
烟台影视,http://live.yantaitv.cn/live/e9f1d9045d474c31884d13fa4ffbbd16/a4a9b3704d854756907845107cc56129-1.m3u8
|
||||
影视频道,http://112.30.194.221:20080/live/d18ff95cb1fb4bbcb56215e189fc12be/hls.m3u8
|
||||
美丽中国说,http://newcntv.qcloudcdn.com/asp/hls/4000/0303000a/3/default/8cdd688b04e4495ba1635e218419d6f9/4000.m3u8
|
||||
|
||||
|
||||
|
|
74
小米/api.json
74
小米/api.json
|
@ -1,17 +1,18 @@
|
|||
{
|
||||
|
||||
"spider": "./spider.jar",
|
||||
"wallpaper": "https://xn--11x805d.xn--4kq62z5rby2qupq9ub.xyz/",
|
||||
"wallpaper": "https://t.alcy.cc/fj",
|
||||
"sites": [
|
||||
{
|
||||
"key": "豆豆",
|
||||
"name": "🌈豆瓣┃请测试完删除处理 夸克app打开加入夸克资源群ID:594986235",
|
||||
"name": "🌈豆瓣┃请测试完删除处理 由于公益资金压力米UC已经合并至至臻",
|
||||
"type": 3,
|
||||
"api": "csp_DoubanGuard",
|
||||
"searchable": 0
|
||||
},
|
||||
{
|
||||
"key": "config",
|
||||
"name": "⚙云盘┃配置中心 0326 修复U C无需要配置UT 直接上车",
|
||||
"name": "⚙云盘┃配置中心 0414修复UC 存在起播慢的问题 ",
|
||||
"type": 3,
|
||||
"api": "csp_ConfigGuard",
|
||||
"searchable": 0
|
||||
|
@ -32,9 +33,9 @@
|
|||
"https://www.zhizhenpan.fun/"
|
||||
],
|
||||
"url_key": "Netfixtv",
|
||||
"token": "http://127.0.0.1:9978/file/TVBox/token.txt",
|
||||
"ucCookie": "http://127.0.0.1:9978/file/TVBox/uc.txt",
|
||||
"quarkCookie": "http://127.0.0.1:9978/file/TVBox/quark.txt",
|
||||
"token": "",
|
||||
"ucCookie": "",
|
||||
"quarkCookie": "",
|
||||
"threadinfo": {
|
||||
"chunksize": 400,
|
||||
"threads": 12
|
||||
|
@ -51,31 +52,6 @@
|
|||
"filterable": 1,
|
||||
"ext": "Yu2Y3Q8tqDTqZ+GCqfQZz8i/vsP/tl9O+/0ZjpgnBg9L+drzR5a6bo7DML9hTEHvIuMN0JxvcbUflFgvOz4etZ9cUsZ0b7NskUhkBZr0Id8jSF6uh2VLWSCg2CtmH5o1TtTNh7M3/ltwQq//Spr2kX7vyJVyHNYbVu/LbyQCphXA69Yz8WjqVrK0GsjL+Ik3h6CQSeUSxVsmsygbTWfjFq5Wq6CYigSEVi1MJIiKNCS5cp8Ghq15UINDOnFKRERcz89eu5dSsR9aQX6BVNMdZLwSzxdX+4hT32MaBORYsrm3FFWArSTQdgO0XpnwCxoXyrlOZZA6ewEqkwuIgoDjFOeQEB0B1XkA9COGXhBBN/U253mGVMtzwHTCzpHTSk5MFVpkfjoyaDWZG1SEKMnp7afikfGkM3rn+Vw7Rp3VaPow/4r9kBYdtOiANxRr3/xPWxJdwx8M3BYw8xIlENODkJxzIlYel5FzLMKsR7ZrsZA="
|
||||
},
|
||||
{
|
||||
"key": "csp_UC",
|
||||
"name": "🍚小米┃UC123",
|
||||
"type": 3,
|
||||
"changeable": "0",
|
||||
"quickSearch": 1,
|
||||
"api": "csp_DuopanGuard",
|
||||
"filterable": 1,
|
||||
"ext": {
|
||||
"site_urls": [
|
||||
"https://www.54271.fun/",
|
||||
"https://54271.fun/",
|
||||
"https://www.mucpan.cc/",
|
||||
"https://mucpan.cc/"
|
||||
],
|
||||
"url_key": "UC",
|
||||
"token": "http://127.0.0.1:9978/file/TVBox/token.txt",
|
||||
"ucCookie": "http://127.0.0.1:9978/file/TVBox/uc.txt",
|
||||
"quarkCookie": "http://127.0.0.1:9978/file/TVBox/quark.txt",
|
||||
"threadinfo": {
|
||||
"chunksize": 400,
|
||||
"threads": 12
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "csp_Bili",
|
||||
"name": "💯哔哩┃哔哩",
|
||||
|
@ -83,7 +59,7 @@
|
|||
"api": "csp_BiliGuard",
|
||||
"searchable": 1,
|
||||
"ext": {
|
||||
"json": "./json/bili.json",
|
||||
"json": "./json/1744612665263_bili.json",
|
||||
"cookie": ""
|
||||
},
|
||||
"style": {
|
||||
|
@ -268,12 +244,12 @@
|
|||
},
|
||||
{
|
||||
"key": "csp_MiSou",
|
||||
"name": "🔍米搜┃夸克",
|
||||
"name": "🔍米搜┃盘聚",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"changeable": "0",
|
||||
"api": "csp_MiSouGuard",
|
||||
"ext": "http://127.0.0.1:9978/file/TVBox/quark.txt"
|
||||
"api": "csp_XiaoYiGuard",
|
||||
"ext": ""
|
||||
},
|
||||
{
|
||||
"key": "听书",
|
||||
|
@ -300,7 +276,7 @@
|
|||
"type": 3,
|
||||
"api": "csp_PushGuard",
|
||||
"searchable": 0,
|
||||
"ext": "http://127.0.0.1:9978/file/TVBox/token.txt"
|
||||
"ext": ""
|
||||
}
|
||||
],
|
||||
"parses": [
|
||||
|
@ -315,9 +291,24 @@
|
|||
"url": "影视"
|
||||
},
|
||||
{
|
||||
"name": "自用",
|
||||
"name": "巧技三",
|
||||
"type": 1,
|
||||
"url": ""
|
||||
"url": "https://zy.qiaoji8.com/xiafan.php?url=",
|
||||
"ext": {
|
||||
"flag": [
|
||||
"QD4K",
|
||||
"iyf",
|
||||
"duanju",
|
||||
"gzcj",
|
||||
"GTV",
|
||||
"GZYS",
|
||||
"weggz",
|
||||
"Ace"
|
||||
],
|
||||
"header": {
|
||||
"User-Agent": "okhttp/4.9.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "8090g",
|
||||
|
@ -341,13 +332,16 @@
|
|||
"name": "V4聚合(卡顿请按左┃右键换线)",
|
||||
"type": 0,
|
||||
"url": "./lives/V4聚合(卡顿请按左┃右键换线).txt",
|
||||
"epg": ""
|
||||
"playerType":2,
|
||||
"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}",
|
||||
"logo":"https://epg.v1.mk/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "平台直播",
|
||||
"type": 0,
|
||||
"url": "./lives/平台直播.txt",
|
||||
"epg": ""
|
||||
"ua":"okhttp/3.15",
|
||||
"playerType":2
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"class": [
|
||||
{"type_name": "演唱会","type_id": "演唱会4K"},
|
||||
{"type_name": "歌曲","type_id": "热歌"},
|
||||
{"type_name": "音乐","type_id": "纯音乐"},
|
||||
{"type_name": "舞蹈","type_id": "舞蹈"},
|
||||
{"type_name": "体育","type_id": "体育"},
|
||||
{"type_name": "戏曲","type_id": "戏曲"},
|
||||
{"type_name": "旅游","type_id": "旅游"},
|
||||
{"type_name": "风景","type_id": "风景4K"},
|
||||
{"type_name": "美食","type_id": "美食超清"},
|
||||
{"type_name": "搞笑","type_id": "搞笑"},
|
||||
{"type_name": "儿童","type_id": "儿童"},
|
||||
{"type_name": "纪录","type_id": "纪录片超清"},
|
||||
{"type_name": "综艺","type_id": "综艺大全"},
|
||||
{"type_name": "广场舞","type_id": "广场舞"},
|
||||
{"type_name": "太极拳","type_id": "太极拳"},
|
||||
{"type_name": "白噪音","type_id": "白噪音超清"},
|
||||
{"type_name": "软件教程","type_id": "软件教程"},
|
||||
{"type_name": "动物自然","type_id": "动物世界超清"},
|
||||
{"type_name": "相声小品","type_id": "相声小品"},
|
||||
{"type_name": "旅行探险","type_id": "旅行探险"}
|
||||
],
|
||||
"filters": {
|
||||
"演唱会4K":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"演唱会4K"},{"n":"演唱会合集","v":"演唱会合集"},{"n":"红馆演唱会","v":"红馆演唱会"},{"n":"Beyond","v":"Beyond演唱会"},{"n":"张学友","v":"张学友演唱会"},{"n":"刘德华","v":"刘德华演唱会"},{"n":"谭咏麟","v":"谭咏麟演唱会"},{"n":"李克勤","v":"李克勤演唱会"},{"n":"陈百强","v":"陈百强演唱会"},{"n":"陈奕迅","v":"陈奕迅演唱会"},{"n":"伍佰","v":"伍佰演唱会"},{"n":"SHE","v":"SHE演唱会"},{"n":"陈小春","v":"陈小春演唱会"},{"n":"草蜢","v":"草蜢演唱会"},{"n":"陈慧娴","v":"陈慧娴演唱会"},{"n":"刀郎","v":"刀郎演唱会"},{"n":"邓紫棋","v":"邓紫棋演唱会"},{"n":"凤凰传奇","v":"凤凰传奇演唱会"},{"n":"林子祥","v":"林子祥演唱会"},{"n":"李宗盛","v":"李宗盛演唱会"},{"n":"罗大佑","v":"罗大佑演唱会"},{"n":"梅艳芳","v":"梅艳芳演唱会"},{"n":"迈克尔杰克逊","v":"迈克尔杰克逊演唱会"},{"n":"容祖儿","v":"容祖儿演唱会"},{"n":"任贤齐","v":"任贤齐演唱会"},{"n":"王心凌","v":"王心凌演唱会"},{"n":"张韶涵","v":"张韶涵演唱会"},{"n":"张国荣","v":"张国荣演唱会"},{"n":"周慧敏","v":"周慧敏演唱会"},{"n":"卓依婷","v":"卓依婷演唱会4K"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"热歌":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"经典无损音乐"},{"n": "内地","v": "内地歌曲"},{"n": "香港","v": "香港歌曲"},{"n": "台湾","v": "台湾歌曲"},{"n":"粤语","v":"粤语歌曲"},{"n":"国语","v":"国语歌曲"},{"n":"闽南","v":"闽南歌曲"},{"n":"老歌","v":"怀旧老歌"},{"n":"热榜","v":"2023年热们歌曲"},{"n":"经典","v":"经典老歌"},{"n":"古风","v":"古风歌曲"},{"n":"舞曲","v":"DJ歌曲"},{"n":"网络","v":"网红歌曲"},{"n":"抖音","v":"抖音热歌"},{"n":"快手","v":"快手热歌"},{"n":"对唱","v":"情歌对唱"},{"n":"迪斯科","v":"迪斯科"},{"n":"70年代","v":"70年代歌曲"},{"n":"80年代","v":"80年代歌曲"},{"n":"90年代","v":"90年代歌曲"},{"n":"超清MV","v":"超清MV"},{"n":"酒廊情歌","v":"酒廊情歌"},{"n":"山地情歌","v":"山地情歌"},{"n":"卓依婷","v":"卓依婷"},{"n":"新春","v":"新年歌曲"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"纯音乐":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"纯音乐"},{"n":"钢琴","v":"钢琴曲"},{"n":"小提琴","v":"小提音乐"},{"n":"手风琴","v":"手风音乐"},{"n":"二胡","v":"二胡音乐"},{"n":"古筝","v":"古筝音乐"},{"n":"笛子","v":"笛子音乐"},{"n":"琵琶","v":"琵琶音乐"},{"n":"古琴","v":"古琴音乐"},{"n":"编钟","v":"编钟音乐"},{"n":"协奏曲","v":"协奏曲"},{"n":"古风音乐","v":"古风纯音乐"},{"n":"背景音乐","v":"背景音乐"},{"n":"助眠音乐","v":"助眠音乐"},{"n":"胎教音乐","v":"胎教音乐"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"舞蹈":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"舞蹈"},{"n":"古典舞","v":"古典舞"},{"n":"芭蕾舞","v":"芭蕾舞"},{"n":"民族舞","v":"民族舞"},{"n":"现代舞","v":"现代舞"},{"n":"踢踏舞","v":"踢踏舞"},{"n":"爵士舞","v":"爵士舞"},{"n":"拉丁舞","v":"拉丁舞"},{"n":"摩登舞","v":"摩登舞"},{"n":"街舞","v":"街舞"},{"n":"广场舞","v":"广场舞"},{"n":"宅舞","v":"宅舞"},{"n":"肚皮舞","v":"肚皮舞"},{"n":"钢管舞","v":"钢管舞"},{"n":"英歌舞","v":"英歌舞"},{"n":"劲舞","v":"热舞劲舞"},{"n":"独舞","v":"独舞"},{"n":"群舞","v":"群舞"},{"n":"组舞","v":"组舞"},{"n":"舞剧","v":"舞剧"},{"n":"国风舞蹈","v":"国风舞蹈"},{"n":"女团热舞","v":"女团热舞"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"体育":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"体育赛事"},{"n":"NBA","v":"NBA"},{"n":"世界杯","v":"世界杯"},{"n":"足球","v":"足球赛"},{"n":"赛艇","v":"赛艇"},{"n":"马拉松","v":"马拉松"},{"n":"拳击","v":"拳击"},{"n":"柔道","v":"柔道"},{"n":"跆拳道","v":"跆拳道"},{"n":"摔跤","v":"摔跤"},{"n":"高尔夫","v":"高尔夫"},{"n":"WWE","v":"WWE"},{"n":"奥运会","v":"奥运会"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"戏曲":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"戏曲4K"},{"n":"B梆子腔","v":"梆子腔戏曲4K"},{"n":"C采茶戏","v":"采茶戏戏曲4K"},{"n":"C潮剧","v":"潮剧戏曲4K"},{"n":"C彩调","v":"彩调戏曲4K"},{"n":"C川剧","v":"川剧戏曲4K"},{"n":"D滇剧","v":"滇剧戏曲4K"},{"n":"D傣剧","v":"傣剧戏曲4K"},{"n":"E二人台","v":"二人台戏曲4K"},{"n":"G高腔","v":"高腔戏曲4K"},{"n":"G高甲戏","v":"高甲戏戏曲4K"},{"n":"G赣剧","v":"赣剧戏曲4K"},{"n":"G桂剧","v":"桂剧戏曲4K"},{"n":"H黄梅戏","v":"黄梅戏戏曲4K"},{"n":"H河北梆子","v":"河北梆子戏曲4K"},{"n":"H河南曲剧","v":"河南曲剧戏曲4K"},{"n":"H淮剧","v":"淮剧戏曲4K"},{"n":"H沪剧","v":"沪剧戏曲4K"},{"n":"H滑稽戏","v":"滑稽戏戏曲4K"},{"n":"H徽剧","v":"徽剧4K"},{"n":"H汉剧","v":"汉剧戏曲4K"},{"n":"H湖南花鼓戏","v":"湖南花鼓戏戏曲4K"},{"n":"J京剧","v":"京剧戏曲4K"},{"n":"J晋剧","v":"晋剧戏曲4K"},{"n":"J吉剧","v":"吉剧戏曲4K"},{"n":"K昆曲","v":"昆曲戏曲4K"},{"n":"L梨园戏","v":"梨园戏戏曲4K"},{"n":"L龙江剧","v":"龙江剧戏曲4K"},{"n":"M闽剧","v":"闽剧戏曲4K"},{"n":"P评剧","v":"评剧戏曲4K"},{"n":"P蒲剧","v":"蒲剧戏曲4K"},{"n":"P皮影戏","v":"皮影戏戏曲4K"},{"n":"P莆仙戏","v":"莆仙戏戏曲4K"},{"n":"Q黔剧","v":"黔剧戏曲4K"},{"n":"Q祁剧","v":"祁剧戏曲4K"},{"n":"Q秦腔","v":"秦腔戏曲4K"},{"n":"S上党梆子","v":"上党梆子戏曲4K"},{"n":"S山东梆子","v":"山东梆子戏曲4K"},{"n":"S绍剧","v":"绍剧戏曲4K"},{"n":"W武安平调","v":"武安平调戏曲4K"},{"n":"W婺剧","v":"婺剧戏曲4K"},{"n":"X湘剧","v":"湘剧戏曲4K"},{"n":"Y越剧","v":"越剧戏曲4K"},{"n":"Y豫剧","v":"豫剧戏曲4K"},{"n":"Y雁剧","v":"雁剧戏曲4K"},{"n":"Y越调","v":"越调戏曲4K"},{"n":"Y粤剧","v":"粤剧戏曲4K"},{"n":"Z壮剧","v":"壮剧戏曲4K"},{"n":"Z藏剧","v":"藏剧戏曲4K"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"旅游":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"旅游"},{"n":"A澳门","v":"澳门旅游"},{"n":"A安徽","v":"安徽旅游"},{"n":"B布达拉宫","v":"布达拉宫旅游"},{"n":"B北京","v":"北京旅游"},{"n":"C重庆","v":"重庆旅游"},{"n":"C草原","v":"草原旅游"},{"n":"D大海","v":"大海旅游"},{"n":"F福建","v":"福建旅游"},{"n":"G广东","v":"广东旅游"},{"n":"G广西","v":"广西旅游"},{"n":"G贵州","v":"贵州旅游"},{"n":"G甘肃","v":"甘肃旅游"},{"n":"H海南","v":"海南旅游"},{"n":"H河北","v":"河北旅游"},{"n":"H河南","v":"河南旅游"},{"n":"H湖北","v":"湖北旅游"},{"n":"H湖南","v":"湖南旅游"},{"n":"H黑龙江","v":"黑龙江旅游"},{"n":"J吉林","v":"吉林旅游"},{"n":"J江苏","v":"江苏旅游"},{"n":"J江西","v":"江西旅游"},{"n":"L辽宁","v":"辽宁旅游"},{"n":"M民宿","v":"民宿旅游"},{"n":"N内蒙古","v":"内蒙古旅游"},{"n":"N宁夏","v":"宁夏旅游"},{"n":"Q青海","v":"青海旅游"},{"n":"S上海","v":"上海旅游"},{"n":"S陕西","v":"陕西旅游"},{"n":"S四川","v":"四川旅游"},{"n":"S山西","v":"山西旅游"},{"n":"S山东","v":"山东旅游"},{"n":"T天津","v":"天津旅游"},{"n":"T台湾","v":"台湾旅游"},{"n":"T天空","v":"天空旅游"},{"n":"X西湖","v":"西湖旅游"},{"n":"X西藏","v":"西藏旅游"},{"n":"X新疆","v":"新疆旅游"},{"n":"X香港","v":"香港旅游"},{"n":"Y云南","v":"云南旅游"},{"n":"Z浙江","v":"浙江旅游"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"风景4K":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"风景4K"},{"n":"A澳门","v":"澳门风景4K"},{"n":"A安徽","v":"安徽风景4K"},{"n":"B布达拉宫","v":"布达拉宫风景4K"},{"n":"B北京","v":"北京风景4K"},{"n":"C重庆","v":"重庆风景4K"},{"n":"C草原","v":"草原风景4K"},{"n":"D大海","v":"大海风景4K"},{"n":"F福建","v":"福建风景4K"},{"n":"G广东","v":"广东风景4K"},{"n":"G广西","v":"广西风景4K"},{"n":"G贵州","v":"贵州风景4K"},{"n":"G甘肃","v":"甘肃风景4K"},{"n":"H海南","v":"海南风景4K"},{"n":"H河北","v":"河北风景4K"},{"n":"H河南","v":"河南风景4K"},{"n":"H湖北","v":"湖北风景4K"},{"n":"H湖南","v":"湖南风景4K"},{"n":"H黑龙江","v":"黑龙江风景4K"},{"n":"J吉林","v":"吉林风景4K"},{"n":"J江苏","v":"江苏风景4K"},{"n":"J江西","v":"江西风景4K"},{"n":"L辽宁","v":"辽宁风景4K"},{"n":"L洛阳","v":"洛阳风景4K"},{"n":"M民宿","v":"民宿风景4K"},{"n":"N南京","v":"南京风景4K"},{"n":"N内蒙古","v":"内蒙古风景4K"},{"n":"N宁夏","v":"宁夏风景4K"},{"n":"Q青海","v":"青海风景4K"},{"n":"S上海","v":"上海风景4K"},{"n":"S陕西","v":"陕西风景4K"},{"n":"S四川","v":"四川风景4K"},{"n":"S山西","v":"山西风景4K"},{"n":"S山东","v":"山东风景4K"},{"n":"S苏州","v":"苏州风景4K"},{"n":"T天津","v":"天津风景4K"},{"n":"T台湾","v":"台湾风景4K"},{"n":"T天空","v":"天空风景4K"},{"n":"X西安","v":"西安风景4K"},{"n":"X西湖","v":"西湖风景4K"},{"n":"X西藏","v":"西藏风景4K"},{"n":"X新疆","v":"新疆风景4K"},{"n":"X香港","v":"香港风景4K"},{"n":"Y云南","v":"云南风景4K"},{"n":"Z浙江","v":"浙江风景4K"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"美食超清":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"美食超清"},{"n":"舌尖上的中国","v":"舌尖上的中国超清"},{"n":"老字号","v":"老字号美食超清"},{"n":"家常菜","v":"家常菜美食超清"},{"n":"香港美食探店","v":"香港美食探店超清"},{"n":"澳门美食探店","v":"澳门美食探店超清"},{"n":"上海美食探店","v":"上海美食探店超清"},{"n":"北京美食探店","v":"北京美食探店超清"},{"n":"重庆美食探店","v":"重庆美食探店超清"},{"n":"南京美食探店","v":"南京美食探店超清"},{"n":"广州美食探店","v":"广州美食探店超清"},{"n":"杭州美食探店","v":"杭州美食探店超清"},{"n":"成都美食探店","v":"成都美食探店超清"},{"n":"苏州美食探店","v":"苏州美食探店超清"},{"n":"武汉美食探店","v":"武汉美食探店超清"},{"n":"台湾美食探店","v":"台湾美食探店超清"},{"n":"川菜","v":"川菜美食超清"},{"n":"豫菜","v":"豫菜美食超清"},{"n":"淮扬菜","v":"淮扬菜美食超清"},{"n":"湘菜","v":"湘菜美食超清"},{"n":"鲁菜","v":"鲁菜美食超清"},{"n":"粤菜","v":"粤菜美食超清"},{"n":"潮菜","v":"潮菜美食超清"},{"n":"浙菜","v":"浙菜美食超清"},{"n":"徽菜","v":"徽菜美食超清"},{"n":"闽菜","v":"闽菜美食超清"},{"n":"东北菜","v":"东北菜美食超清"},{"n":"客家菜","v":"客家菜美食超清"},{"n":"苏菜","v":"苏菜美食超清"},{"n":"火锅","v":"火锅"},{"n":"面食","v":"面食"},{"n":"炒菜","v":"炒菜"},{"n":"点心","v":"点心"},{"n":"日料","v":"日料"},{"n":"小吃","v":"小吃"},{"n":"素食","v":"素食"},{"n":"蒸菜","v":"蒸菜"},{"n":"凉菜","v":"凉菜"},{"n":"早餐","v":"早餐"},{"n":"披萨","v":"披萨"},{"n":"烤鱼","v":"烤鱼"},{"n":"海鲜","v":"海鲜美食超清"},{"n":"汉堡","v":"汉堡"},{"n":"韩国菜","v":"韩国菜"},{"n":"泰国菜","v":"泰国菜"},{"n":"穆斯林菜","v":"穆斯林菜"},{"n":"法国菜","v":"法国菜"},{"n":"意大利菜","v":"意大利菜"},{"n":"西班牙菜","v":"西班牙菜"},{"n":"土耳其菜","v":"土耳其菜系"},{"n":"阿拉伯菜","v":"阿拉伯菜"},{"n":"德国菜","v":"德国菜"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"搞笑":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"搞笑"},{"n":"搞笑配音","v":"搞笑配音"},{"n":"搞笑电影","v":"搞笑电影"},{"n":"搞笑综艺","v":"搞笑综艺"},{"n":"鬼畜电影","v":"鬼畜电影"},{"n":"搞笑动画","v":"搞笑动画"},{"n":"搞笑番","v":"搞笑番"},{"n":"十万个冷笑话","v":"十万个冷笑话"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"儿童":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"儿童"},{"n":"教育","v":"儿童早教"},{"n":"歌曲","v":"贝瓦儿歌"},{"n":"舞蹈","v":"儿童舞蹈"},{"n":"成语故事","v":"儿童成语故事"},{"n":"安全教育","v":"儿童安全教育"},{"n":"睡前故事","v":"儿童睡前故事"},{"n":"贝乐虎","v":"贝乐虎"},{"n":"宝宝巴士","v":"宝宝巴士"},{"n":"儿童好声音","v":"儿童好声音"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"纪录片超清":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"太极拳":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"太极拳"},{"n":"邱慧芳","v":"太极拳邱慧芳"},{"n":"陈氏","v":"太极拳陈氏"},{"n":"武当","v":"太极拳武当"},{"n":"二十四式","v":"太极拳二十四式"},{"n":"三十六式","v":"太极拳三十六式"},{"n":"五禽戏","v":"五禽戏"},{"n":"八段锦","v":"八段锦"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"综艺大全":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"综艺汇聚"},{"n":"诗词大会","v":"诗词大会"},{"n":"典籍里的中国","v":"典籍里的中国"},{"n":"我是歌手","v":"我是歌手"},{"n":"中国梦想秀","v":"中国梦想秀"},{"n":"非诚勿扰","v":"非诚勿扰"},{"n":"王牌对王牌","v":"王牌对王牌"},{"n":"极限挑战","v":"极限挑战"},{"n":"中国好声音","v":"中国好声音"},{"n":"中国新声代","v":"中国新声代"},{"n":"军情直播间","v":"军情直播间"},{"n":"军情观察室","v":"军情观察室"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"广场舞":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"白噪音超清":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"白噪音4K"},{"n":"窗白噪音","v":"窗白噪音4K"},{"n":"环境白噪音","v":"环境白噪音4K"},{"n":"自然白噪音","v":"自然白噪音4K"},{"n":"助眠白噪音","v":"助眠白噪音4K"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"软件教程":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"软件教程"},{"n":"Windows","v":"Windows"},{"n":"MT管理器","v":"MT管理器"},{"n":"NP管理器","v":"NP管理器"},{"n":"mixplorer","v":"mixplorer"},{"n":"脱壳","v":"脱壳"},{"n":"爬虫","v":"爬虫"},{"n":"json&jar","v":"json&jar"},{"n":"网盘挂载","v":"网盘挂载"},{"n":"alist+WebDav","v":"alist+WebDav"},{"n":"TVBox","v":"TVBox"},{"n":"EXCEL","v":"EXCEL教程"},{"n":"Git入门到精通","v":"Git入门到精通"},{"n":"java","v":"java教程"},{"n":"phyton","v":"phyton教程"},{"n":"xml","v":"xml教程"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"动物世界超清":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"地球自然"},{"n":"熊猫","v":"国宝熊猫"},{"n":"大自然","v":"大自然"},{"n":"地球自然","v":"地球自然"},{"n":"宇宙探索","v":"宇宙探索"},{"n":"探索发现","v":"探索发现"},{"n":"动物世界","v":"动物世界超清"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"相声小品":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"相声小品"},{"n":"C陈佩斯","v":"陈佩斯小品4K"},{"n":"C春晚小品","v":"春晚小品4K"},{"n":"C曹云金","v":"曹云金相声4K"},{"n":"D单口相声","v":"单口相声4K"},{"n":"D德云社","v":"德云社小品4K"},{"n":"E二人转","v":"二人转4K"},{"n":"F冯巩","v":"冯巩小品4K"},{"n":"G郭德纲","v":"郭德纲相声4K"},{"n":"G郭冬临","v":"郭冬临小品4K"},{"n":"G郭达","v":"郭达小品4K"},{"n":"K开心麻花","v":"开心麻花小品4K"},{"n":"P评书","v":"评书4K"},{"n":"P潘长江","v":"潘长江小品4K"},{"n":"Q青曲社","v":"青曲社相声4K"},{"n":"Q群口相声","v":"群口相声4K"},{"n":"S宋小宝","v":"宋小宝小品4K"},{"n":"W文松","v":"文松小品4K"},{"n":"X小曲","v":"小曲相声4K"},{"n":"X喜剧综艺","v":"喜剧综艺4K"},{"n":"Y严顺开","v":"严顺开小品4K"},{"n":"Y岳云鹏","v":"岳云鹏相声小品4K"},{"n":"Z赵本山","v":"赵本山小品4K"},{"n":"Z赵丽蓉","v":"赵丽蓉小品4K"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}],
|
||||
"旅行探险":[{"key":"order","name":"排序","value":[{"n":"综合排序","v":"0"},{"n":"最多点击","v":"click"},{"n":"最新发布","v":"pubdate"},{"n":"最多弹幕","v":"dm"},{"n":"最多收藏","v":"stow"}]},{"key":"tid","name":"分类","value":[{"n":"全部","v":"旅行探险"},{"n":"摩旅","v":"摩托车旅游"},{"n":"骑行","v":"骑行旅游"},{"n":"徒步旅游","v":"徒步旅游"},{"n":"自驾旅游","v":"自驾旅游"},{"n":"洞穴探险","v":"洞穴探险"},{"n":"荒野求生","v":"荒野求生"},{"n":"凶宅探险","v":"凶宅探险"},{"n":"灵异探险","v":"灵异探险"},{"n":"户外攀岩","v":"户外攀岩"},{"n":"高空攀爬","v":"高空攀爬"},{"n":"潜水探险","v":"潜水探险"},{"n":"翼装飞行","v":"翼装飞行"},{"n":"极限运动","v":"极限运动"},{"n":"速降","v":"速降"},{"n":"高空跑酷","v":"高空跑酷"},{"n":"冲浪","v":"冲浪"}]},{"key":"duration","name":"时长","value":[{"n":"全部","v":"0"},{"n":"60分钟以上","v":"4"},{"n":"30~60分钟","v":"3"},{"n":"10~30分钟","v":"2"},{"n":"10分钟以下","v":"1"}]}]
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
4068
小米/lives/平台直播.txt
4068
小米/lives/平台直播.txt
File diff suppressed because it is too large
Load Diff
BIN
小米/spider.jar
BIN
小米/spider.jar
Binary file not shown.
89
摸鱼儿/api.json
89
摸鱼儿/api.json
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
{
|
||||
"key": "config",
|
||||
"name": "🚀辅助┃配置┃网盘",
|
||||
"name": "🚀辅助┃配置┃中心",
|
||||
"type": 3,
|
||||
"api": "csp_Config",
|
||||
"jar": "./jars/config.jar",
|
||||
|
@ -216,38 +216,6 @@
|
|||
"type": 3,
|
||||
"api": "csp_Jpys"
|
||||
},
|
||||
{
|
||||
"key": "AppGG",
|
||||
"name": "🌙柳月┃蓝光┃无广",
|
||||
"type": 3,
|
||||
"api": "csp_AppGetApp",
|
||||
"jar": "./jars/config.jar",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0,
|
||||
"ext": "w7TCmsK8w5rDrcKYwoPCmcKkw57CmsK0wpnCoVpcUFfDjMOcw67DnsOPwqXCnFdqwpnCmsOiw63DrsKjal9fwqrCpMKrwqfCq2tgXmHCssKrwqjCrcKqbWFhYcKpwqLDm8Opw6NhwqDCmMKgwqDCn8KawqDDg8KhwpnCpMKHw6jDpcOewqDCtFNXwpnCnsOiw6fDkMKqwqtsV1xQwqDDp8Ojw6nCoW1QV8KL5Ye+6YWb5pCf5ZGcwqblhp/kvYflkKdq5b+q6Ki56La+5ryJ562TwpBXXFDCoMK0w5/DrMOFwpjCqVdqwpnCmsObw6zDocKWwqjCmMKaw6TDp8OtwqrCrGdlZ2PCoMKfwprCoMK7wpjCo3nCpsKgwq3CmsKgw5vCpsKXwpPCqMOhw53DpcOtw61kYmRlwrDCpsKhwqXCmlrCmMKVwpHDncOYw6zDrMKhbVDCq1fDrsOmw5/Dq8KnwpTCl8KVwp7DrcKawrTCmcKhwoDCn8KqwpnDpcOfw5vCqMKvYWBQWMOQw5zDqMOdw6nCqsKjUH7DjcKTwqvCqcKoY2tQwofDosOhwrDCrcK1U8KoZmTCosKTwrvDqcOqwp/ClcKHwpXDm8K+w6PDrcKpaGNnXsKswqnCmsKhw4V7woR9fMKlwpPDpsOiw6XCmFB3wpXDnMOew6nCosKadsKYwqLCn8Omw5jCqcKqwqtlXmBewqnCocKqwpnDjcKUwpbCkcKiw6LCosKvwqzCsWFjZlfCpcKTwqHDmsOmwp/Cn8Knc8Orw6LDrcOsw4rCpcKfwqTCn8Ocw6LDpsOLw5/Cl8KZwqLClcOcw6fDrcKgwrRTwoTCosKlw57DsMKmwpnCoXXCkcKewpvDh8OUw7DCoMK0U1fnnKTmk53CoMKfwprCoMOewpjCk8KiwqnDqcOnw4XDnsOzWmpQV8Oww6jDs8OiwrBpZlfCrQ=="
|
||||
},
|
||||
{
|
||||
"key": "nm",
|
||||
"name": "🌼农民┃蓝光┃纯净",
|
||||
"type": 3,
|
||||
"api": "csp_WebNM",
|
||||
"jar": "./jars/config.jar",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0,
|
||||
"ext": "w7TCmsONw6LDrsKYwoXCosKcwqDCrcKawqDDosKnwqTCoMKjwrPCosKpw7DDscKawqpewpPDp8KawqbCmcKhwqfCmcKgV8KzwpPCocOU5Ye/6YSb5o+V5ZCTXOWHpeS+iuWRscKz5b+r6Ke56LW05ruA56yJw5bCmsKmwpnCocKXwpXCk8Kiw7LDo8Ouw4TDn8KsV2pQwqDDqsOvw7LDo2lmZlfDtg=="
|
||||
},
|
||||
{
|
||||
"key": "rbj",
|
||||
"name": "🔥热剧┃蓝光┃无广",
|
||||
"type": 3,
|
||||
"api": "csp_AppRJ",
|
||||
"jar": "./jars/config.jar",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0
|
||||
},
|
||||
{
|
||||
"key": "nk",
|
||||
"name": "🫣耐看┃蓝光┃无广",
|
||||
|
@ -258,27 +226,6 @@
|
|||
"changeable": 0,
|
||||
"ext": "w7TCmsONw6LDrsKYwoXCosKcwqDCrcKawqDDosKnwqTCoMKjwrPCosKpw7DDscKqXsKewpvDncOpw57Cp8OnwphXXFDCoMOnw6PDqcKhbVBXwovlh77phZvmkJ/lkZzCpuWGn+S9h+WQp2rlv6roqLnotr7mvInnrZPCkFdcUMKgw5fDn8Ocw6zCrMKgwqR7w57DrMKhwrPCmlrCp8KlwqnDosKpwrDCr8KhwrA="
|
||||
},
|
||||
{
|
||||
"key": "lk",
|
||||
"name": "🫣来看┃蓝光┃无广",
|
||||
"type": 3,
|
||||
"api": "csp_WebLK",
|
||||
"jar": "./jars/config.jar",
|
||||
"searchable": 0,
|
||||
"changeable": 0,
|
||||
"ext": "w7TCmsONw6LDrsKYwoXCosKcwqDCrcKawqDDosKnwqTCoMKjwrPCosKpw6XDpcKpwp/ClF7DpsOYwqHCpcKaWsKkwpnCoMKgwq3CmsKgw5XlhrjphJjmj5XlkJPCpeWHn+S+keWRsMK05b6k6Ke26LW05ruA562Sw5DCocKlwppawpTClcKTw6vDrMOqw63DhcKYwqlXasKZwprDscOuw7PCnGZmZsKgw7A="
|
||||
},
|
||||
{
|
||||
"key": "AppHD",
|
||||
"name": "🤞一起┃蓝光┃无广",
|
||||
"type": 3,
|
||||
"api": "csp_AppFree4K",
|
||||
"jar": "./jars/config.jar",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0,
|
||||
"ext": "w7TCmsONw6LDrsKYwoXCosKcwqDCrcKawqDDosKnwqTCoMKjwrPCosKpw5rDqsKjwpPCncKjwqfDmcOsw57Dn8KbwpRewqbDosOjwqHCpcKaWnvClcKpwqDCrcKawqDDnMKYZWNkwrHDl8Ogw5vCqsKWY8KTYsKxwqbCocKlwppaecKmV8KzwpPCocKuw6BoZGRpw53Dl8Krwq3CrWRjYmHCsMKawqbCmcKhdcKRwp7Cm8OHw5TDsMKgwrRTV+ecpOaTncKgwp/CmsKgw4rClMKiwqPClcOOw6XDpsKgwrRTV8KYwqTDrcOjw63Cs8KpYsKRwqDCoMOvwqTCqMOfw6zCmMKVwpjClMKnw6nDo8OpwqnCncKjwp/CnsKnw6PDosOpwrnCqMKiwpxtwqDCn8KawqDCvsKUwp59wqXDjsOlw6bCoMK0U1fCmMKkw63Do8OtwrPCqWLClMKdXsOvw5zDnsOzwqjClMKjwpnCkcKow5fDp8Okw69ib8KRwpPCtsOXw6fCn8OuwqLCm8KVwp7CtsOEw4PDhcK8dnh6dsOMwr/DkcOPw4B4e8KCVsOuw6XDpsK2wqFfUFfClMOew5bDrMOyw6rCp3vClcKpwqDCrcKawqDDscKowqnCmWbCr8KpwqHDtg=="
|
||||
},
|
||||
{
|
||||
"key": "guazi",
|
||||
"name": "🍉瓜子┃网页┃无广",
|
||||
|
@ -289,40 +236,6 @@
|
|||
"quickSearch": 0,
|
||||
"filterable": 0
|
||||
},
|
||||
{
|
||||
"key": "Appyouyou",
|
||||
"name": "☁️悠悠┃蓝光┃无广",
|
||||
"type": 3,
|
||||
"api": "csp_AppGetApp",
|
||||
"jar": "./jars/config.jar",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0,
|
||||
"ext": "w7TCmsK8w5rDrcKYwoPCmcKkw57CmsK0wpnCoVpcUFfDgsOhw6PDrcORwqLCosKUV8KzwpPCocOiw6jCnMKkwoZhwqrCrMKhwqXCmlrCpMKZwqDCoMKtwprCoMOV5Ya46YSY5o+V5ZCTwqXlh5/kvpHlkbDCtOW+pOintui1tOa7gOetksOQwqHCpcKaWnHClcKjw4TDmMOzwqDCtFNXdMKow7DCvMOtw63DrMKXwofCksKJw6nDlcOmw7DDqFpcUFfCusOYw63DgsOwWmpQV8K9w6vDscOCw63Cp8KiwpTCh8Obw4zDqsObw6bCqsKeV1zCmcKaw43DosOuwpjChcKiwpzCoMKtwprCoMOiwqfCpMKgasKowqLCq8KuwrBhYmJlwqfCpsKqwqfCsGhqZWXCr8KpwqnDmsOqwpxewqDCmMOpwprCpsKZwqF1wpHCnsKbw4fDlMOwwqDCtFNX55yk5pOdwqDCn8KawqDDnsKYwpPCosKpw6nDp8OFw57Ds1pqUFfDsMOow7PDosKwaWZXwq0="
|
||||
},
|
||||
{
|
||||
"key": "AppYunD",
|
||||
"name": "📻️云播┃蓝光┃无广",
|
||||
"type": 3,
|
||||
"api": "csp_AppGetApp",
|
||||
"jar": "./jars/config.jar",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0,
|
||||
"ext": "w7TCmsK8w5rDrcKYwoPCmcKkw57CmsK0wpnCocKbwqTCpMKgw6zCrcKpwqjDs8KXwqnCo8KUw7LDocObw6bDo8KWwpTCn8Kdw5rDnMOow6fDm8KgwpVeZsKxwqHDocOywrRkYGZnwrHCosOdwrLDp2XCmsKjYsKywqvDssKxwqzCm2ZfwpzCssOgwrLDm8OyZWPCmmLDqMKlw6rCssOrYsKUwqnCnsOaw6DDo8Ocw57CosKdwpHCmcOnw6HDm8Omw59hwqTCqMKkwqDCn8KawqDDjcKcwqTClcKFw6vDn8KhwrPCmlpXXFDCoMK8w6jDosOuworCn8KiwpTCoMKtwprCoMOjwqHCmcKkwobCqsKkwrPCoMKmU1fCpMKZw6nCmsK0wpnCocKO5Ya16YSY5o+V5ZGcwp/lh6bkvpDlkbFt5b6h6Ke26LW05ryJ562Mw5fCoMKmU1dxwpXDrMK+w5/DssKhbVBXwpvCssOiwq3DqcKswpZowpJnw6bCpsO0wqnDqWtXXFDCoMK0w5/DrMODwqlXalDCoMOewrPDqMKtwqNiwpNow5vCqsOnwqzDtGPCn2hXwqXCk8Khw53Dn8KWwqLCqcKgw63CvsOfw7LCoW1QV8Knw67DrMOjwq/CsGlXwq0="
|
||||
},
|
||||
{
|
||||
"key": "cz",
|
||||
"name": "🏭️厂长┃蓝光┃无广",
|
||||
"type": 3,
|
||||
"api": "csp_WebCzApp",
|
||||
"jar": "./jars/config.jar",
|
||||
"searchable": 0,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0,
|
||||
"timeout": 30,
|
||||
"ext": "w7TCmsONw6LDrsKYwoXCosKcwqDCrcKawqDDscKqwqdewpPDs8KjwqvCp8OwwpzCoFdcwpnCmsONw57Dm8KlwpPCmMKFw6vDn8KhwrPCmlrCmMKkwqTDqcOmwrTCqMKpwpbCqsKqwqnCp8Onw6nDqcKpwpfCkcKfwqnDqMOhw6HDo8OjwpjCm8KfwqPDocOcw5zDrsOtwpvCmcKpwp/DrsOVw6PDp8OhWlxQV8OMw5zDrsOew4/CpcKccsKRw6TCmsK0wpnCocKbwqTCpMKgw6zCrcKpwqjDscKqwqdewpPDs8Otw7PDr8OjwpfClcKfXsOcw6LDp8KgwqZTV8KkwpnDqcKawrTCmcKhwo7lhrXphJjmj5XlkZzCn+WHpuS+kOWRsW3lvqHop7botbTmvInnrYzDl8KgwqZTV8KUwpXDnMOlw7PDqcOufsKVwqlXwrPCk8Khw7DDr8KswplmZsKvwprDtw=="
|
||||
},
|
||||
{
|
||||
"key": "贱贱",
|
||||
"name": "🐭荐片┃速览┃纯净",
|
||||
|
|
Binary file not shown.
BIN
摸鱼儿/spider.jar
BIN
摸鱼儿/spider.jar
Binary file not shown.
454
欧歌/api.json
454
欧歌/api.json
|
@ -4,56 +4,127 @@
|
|||
"spider": "./spider.jar",
|
||||
"lives": [
|
||||
{
|
||||
"name": "【公众号欧歌APP网络收集】如有收费,直接找退款",
|
||||
"name": "【公众号光歌软件分享】永久免费,请勿演示贩卖",
|
||||
"type": 0,
|
||||
"url": "./lives/【公众号欧歌APP网络收集】如有收费,直接找退款.txt",
|
||||
"epg": "http://cdn.1678520.xyz/epg/?ch={name}&date={date}"
|
||||
"url": "./lives/【公众号光歌软件分享】永久免费,请勿演示贩卖.txt",
|
||||
"epg": "http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
|
||||
"logo":"https://live.fanmingming.cn/tv/{name}.png",
|
||||
"playerType":2,
|
||||
"timeout":10
|
||||
},
|
||||
{
|
||||
"name": "胖羊直播",
|
||||
"type": 3,
|
||||
"api":"csp_Feiyang",
|
||||
"url": "./lives/胖羊直播.txt",
|
||||
"epg": ""
|
||||
"timeout":10,
|
||||
"ua":"okhttp/3.15",
|
||||
"catchup":{"type":"append","source":"?livemode=4&starttime=${(b)yyyyMMdd'T'HHmm}00.00Z&endtime=${(e)yyyyMMdd'T'HHmm}00.00Z"}
|
||||
},
|
||||
{
|
||||
"name": "AI直播",
|
||||
"type": 0,
|
||||
"url": "./lives/AI直播.txt",
|
||||
"epg": "http://cdn.1678520.xyz/epg/?ch={name}&date={date}"
|
||||
"epg":"http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
|
||||
"logo":"https://live.fanmingming.cn/tv/{name}.png",
|
||||
"playerType":2,
|
||||
"timeout":10
|
||||
},
|
||||
{
|
||||
"name": "Live直播",
|
||||
"type": 0,
|
||||
"url": "http://127.0.0.1:9978/proxy?do=live&u=Gather",
|
||||
"epg": ""
|
||||
"playerType":2,
|
||||
"timeout":10
|
||||
}
|
||||
],
|
||||
"sites": [
|
||||
{
|
||||
"key": "豆瓣2",
|
||||
"name": "📢【公众号欧歌APP网络收集】如有收费,直接找退款",
|
||||
"name": "📢【公众号光歌软件分享】永久免费,请勿演示贩卖",
|
||||
"type": 3,
|
||||
"api": "csp_Douban",
|
||||
"searchable": 0
|
||||
},
|
||||
{
|
||||
"key": "豆瓣1",
|
||||
"name": "📢【公众号欧歌APP网络收集】如有收费,直接找退款公告❤更新:4/10❤",
|
||||
"name": "📢【公众号光歌软件分享】永久免费,请勿演示贩卖公告❤更新:4/17❤",
|
||||
"type": 3,
|
||||
"api": "csp_Notice",
|
||||
"searchable": 0,
|
||||
"changeable": 0,
|
||||
"jar": "./jars/豆瓣1.jar",
|
||||
"ext": "https://欧歌.yy.nxog.top/公告.php?b=【公众号欧歌APP网络收集】如有收费,直接找退款"
|
||||
"ext": "https://xn--dkw0c.v.nxog.top/m//公告.php?b=【公众号光歌软件分享】永久免费,请勿演示贩卖"
|
||||
},
|
||||
{
|
||||
"key": "csp_woog",
|
||||
"name": "🐲玩欧|4K弹幕",
|
||||
"type": 3,
|
||||
"changeable": "0",
|
||||
"api": "csp_DuopanGuard",
|
||||
"filterable": 1,
|
||||
"jar": "./jars/csp_woog.jar",
|
||||
"ext": {
|
||||
"site_urls": [
|
||||
"https://woog.nxog.eu.org",
|
||||
"https://woog.xn--dkw.xn--6qq986b3xl"
|
||||
],
|
||||
"url_key": "woog",
|
||||
"threadinfo": {
|
||||
"chunksize": 300,
|
||||
"threads": 10
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "config",
|
||||
"name": "🐲玩欧┃配置中心",
|
||||
"name": "🐲玩欧┃配置",
|
||||
"type": 3,
|
||||
"jar": "./jars/config.jar",
|
||||
"api": "csp_Config",
|
||||
"searchable": 0
|
||||
},
|
||||
{
|
||||
"key": "csp_woogkk",
|
||||
"name": "🐲夸快┃非会员4K",
|
||||
"type": 3,
|
||||
"changeable": "0",
|
||||
"api": "csp_woog",
|
||||
"filterable": 1,
|
||||
"jar": "./jars/csp_woogkk.jar",
|
||||
"ext": {
|
||||
"site_urls": [
|
||||
"hhttps://ogkk.nxog.eu.org",
|
||||
"https://ogkk.xn--dkw.xn--6qq986b3xl"
|
||||
],
|
||||
"url_key": "woogkk",
|
||||
"threadinfo": {
|
||||
"chunksize": 282,
|
||||
"threads": 60
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "csp_欧歌123",
|
||||
"name": "🐲夸快┃配置",
|
||||
"type": 3,
|
||||
"api": "csp_Config",
|
||||
"searchable": 0,
|
||||
"quickSearch": 0,
|
||||
"filterable": 1,
|
||||
"jar": "./jars/csp_欧歌123.jar"
|
||||
},
|
||||
{
|
||||
"key": "欧哥",
|
||||
"name": "❤欧歌|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/og.json?"
|
||||
},
|
||||
{
|
||||
"key": "配置中心",
|
||||
"name": "❤配置|中心",
|
||||
|
@ -67,33 +138,6 @@
|
|||
"ratio": 1.597
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "csp_Netfixtv",
|
||||
"name": "🐲玩欧|4K弹幕",
|
||||
"type": 3,
|
||||
"changeable": "0",
|
||||
"api": "csp_DuopanGuard",
|
||||
"filterable": 1,
|
||||
"jar": "./jars/csp_Netfixtv.jar",
|
||||
"ext": {
|
||||
"site_urls": [
|
||||
"https://woog.nxog.eu.org",
|
||||
"https://woog.xn--dkw.xn--6qq986b3xl"
|
||||
],
|
||||
"url_key": "Netfixtv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "欧哥",
|
||||
"name": "❤欧歌|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/og.json?"
|
||||
},
|
||||
{
|
||||
"key": "荐片",
|
||||
"name": "💡荐片|影视",
|
||||
|
@ -102,6 +146,14 @@
|
|||
"playerType": 1,
|
||||
"ext": "http://api2.rinhome.com"
|
||||
},
|
||||
{
|
||||
"key": "巧技",
|
||||
"name": "💡巧巧|影视",
|
||||
"type": 3,
|
||||
"api": "csp_qiao2",
|
||||
"playerType": 2,
|
||||
"ext": "./txt/cksp.txt"
|
||||
},
|
||||
{
|
||||
"key": "移动",
|
||||
"name": "💡移动|影视",
|
||||
|
@ -222,50 +274,6 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1
|
||||
},
|
||||
{
|
||||
"key": "猎手影视",
|
||||
"name": "💡猎手|影视",
|
||||
"type": 3,
|
||||
"api": "./api/猎手影视.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "火车影视",
|
||||
"name": "💡火车|影视",
|
||||
"type": 3,
|
||||
"api": "./api/火车影视.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "美帕影视",
|
||||
"name": "💡美帕|影视",
|
||||
"type": 3,
|
||||
"api": "./api/美帕影视.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "嗨皮影视",
|
||||
"name": "💡嗨皮|影视",
|
||||
"type": 3,
|
||||
"api": "./api/嗨皮影视.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "厂长影视",
|
||||
"name": "💡厂长|影视",
|
||||
|
@ -338,17 +346,9 @@
|
|||
"playerType": 2,
|
||||
"ext": "https://shdy5.us"
|
||||
},
|
||||
{
|
||||
"key": "光速",
|
||||
"name": "💡光速|影视",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cDovLzU5LjE1My4xNjcuMTM3Ojg4OTl8NGQ4M2I4N2M0YzVlYTExMXw0ZDgzYjg3YzRjNWVhMTExfDQ2Mg=="
|
||||
},
|
||||
{
|
||||
"key": "现代",
|
||||
"name": "💡现代|APP",
|
||||
"name": "💡现代|影视",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
|
@ -393,7 +393,9 @@
|
|||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 0,
|
||||
"ext": "sHR2rlsfjI4L3t4RXQMkn9mmg6Ofmy66+wcs9waIyn4hKqT9jG9s4kO6qzcu2OSqWS1/T+wfkqe+UwoipekwvcM11PTDrQqKYI8lmMXUc1vBHxp/2uWIw5HUoscBNWEb"
|
||||
"ext": {
|
||||
"url": "http://v.rbotv.cn"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "天天影视",
|
||||
|
@ -403,7 +405,9 @@
|
|||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 0,
|
||||
"ext": "sHR2rlsfjI4L3t4RXQMknxhunFUlA4159TKiKvIPpfcM1xianxebcSLajBbwFymqC+z9WoGzQYbh7FSvh8KdiC0BKF0CalaPaCEMOZm+ClGEeNzXAaR0FnrV04SiB2NK"
|
||||
"ext": {
|
||||
"url": "http://tt.ysdqjs.cn"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "浪酷影视",
|
||||
|
@ -413,7 +417,9 @@
|
|||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 0,
|
||||
"ext": "sHR2rlsfjI4L3t4RXQMkn9NPgTvCXvJVoUvXJHT6PqBNTg88Q5I4mc95m2RizprWhdAIQNMU/HShly4WRNzUsfhvqzHXHhHD57G7QagNV0Cx+WDSBgm0uZMAbZVHmzjM"
|
||||
"ext": {
|
||||
"url": "http://v.lkuys.cn"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "菲儿影视",
|
||||
|
@ -422,9 +428,75 @@
|
|||
"api": "csp_AppFerr",
|
||||
"ext": "sHR2rlsfjI4L3t4RXQMkn/M3t4AXAKTrZj3tfhm1t/gMT3dOrHqIzUNqLUEOIDMvllTbX6e1hMhB2mfpOaCmHNOL1yBB3SmxNyqXlai90EIpdnwOOgCR9Z+YwCTj6ySjzJ2VBiH3eXeOGcavcNeVRA=="
|
||||
},
|
||||
{
|
||||
"key": "猎手影视",
|
||||
"name": "🧡猎手|PY影视",
|
||||
"type": 3,
|
||||
"api": "./api/猎手影视.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "火车影视",
|
||||
"name": "🧡火车|PY影视",
|
||||
"type": 3,
|
||||
"api": "./api/火车影视.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "嗨皮影视",
|
||||
"name": "🧡嗨皮|PY影视",
|
||||
"type": 3,
|
||||
"api": "./api/嗨皮影视.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "边缘",
|
||||
"name": "🧡边缘|PY影视",
|
||||
"type": 3,
|
||||
"api": "./api/边缘影视APP.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "若惜",
|
||||
"name": "🧡若惜|PY影视",
|
||||
"type": 3,
|
||||
"api": "./api/若惜追剧APP.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "悠悠",
|
||||
"name": "🧡悠悠|PY影视",
|
||||
"type": 3,
|
||||
"api": "./api/悠悠APP.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "csp_XYQHiker_农民影视",
|
||||
"name": "🧿农民|影视",
|
||||
"name": "🧿农民|XBPQ",
|
||||
"type": 3,
|
||||
"api": "csp_XYQHiker",
|
||||
"searchable": 1,
|
||||
|
@ -434,7 +506,7 @@
|
|||
},
|
||||
{
|
||||
"key": "嫖嫖嫖",
|
||||
"name": "🧿嫖嫖┃影视",
|
||||
"name": "🧿嫖嫖┃XBPQ",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"ext": {
|
||||
|
@ -464,7 +536,7 @@
|
|||
},
|
||||
{
|
||||
"key": "白嫖者",
|
||||
"name": "🧿白嫖┃影视",
|
||||
"name": "🧿白嫖┃XBPQ",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"ext": {
|
||||
|
@ -476,7 +548,7 @@
|
|||
},
|
||||
{
|
||||
"key": "656",
|
||||
"name": "🧿梦想┃影视",
|
||||
"name": "🧿梦想┃XBPQ",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"searchable": 1,
|
||||
|
@ -516,7 +588,7 @@
|
|||
},
|
||||
{
|
||||
"key": "8号影院",
|
||||
"name": "🧿8号┃影视",
|
||||
"name": "🧿8号┃XBPQ",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"searchable": 1,
|
||||
|
@ -534,7 +606,7 @@
|
|||
},
|
||||
{
|
||||
"key": "csp_红狐狸影视",
|
||||
"name": "🧿狐狸┃影视",
|
||||
"name": "🧿狐狸┃XBPQ",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"ext": {
|
||||
|
@ -544,7 +616,7 @@
|
|||
},
|
||||
{
|
||||
"key": "大师兄",
|
||||
"name": "🧿大师┃影视",
|
||||
"name": "🧿大师┃XBPQ",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"ext": {
|
||||
|
@ -554,7 +626,7 @@
|
|||
},
|
||||
{
|
||||
"key": "疯狗",
|
||||
"name": "🧿疯狗┃影视",
|
||||
"name": "🧿疯狗┃XBPQ",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"ext": {
|
||||
|
@ -995,6 +1067,184 @@
|
|||
"ratio": 1.433
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "木偶",
|
||||
"name": "❤木偶|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "./json/mogg.json?"
|
||||
},
|
||||
{
|
||||
"key": "蜡笔",
|
||||
"name": "❤蜡笔|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/lb.json?"
|
||||
},
|
||||
{
|
||||
"key": "小米",
|
||||
"name": "❤小米|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/xm.json?"
|
||||
},
|
||||
{
|
||||
"key": "至臻",
|
||||
"name": "❤至臻|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/zz.json?"
|
||||
},
|
||||
{
|
||||
"key": "多多",
|
||||
"name": "❤多多|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/yyds.json?"
|
||||
},
|
||||
{
|
||||
"key": "二小",
|
||||
"name": "❤二小|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/ex.json?"
|
||||
},
|
||||
{
|
||||
"key": "概念",
|
||||
"name": "❤海绵|4K",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShareCloudHM",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"style": {
|
||||
"type": "rect",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/hm.json?"
|
||||
},
|
||||
{
|
||||
"key": "Pan1",
|
||||
"name": "❤Pan1|4K",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShareCloudHM",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"style": {
|
||||
"type": "rect",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/pan1.json?"
|
||||
},
|
||||
{
|
||||
"key": "趣盘",
|
||||
"name": "❤趣盘|4K",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebQu",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"style": {
|
||||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "w7TCmsONw6LDrsKYwoXCosKcwqDCrcKawqDDosKnwqTCoMKjwrPCosKpw7DDscKqXsKhwqXDqcOUw6jDrMOiwphewpPCn8OmwprCpsKZwqHCp8KZwqBXwrPCk8Khw5Tlh7/phJvmj5XlkJNc5Yel5L6K5ZGxwrPlv6vop7notbTmu4DnrInDlsKawqbCmcKhwpfClcKTwqLDssOjw67DhMOfwqxXalDCoMOqw6/DssOjaWZmV8O2"
|
||||
},
|
||||
{
|
||||
"key": "聚搜",
|
||||
"name": "❤聚搜|4K",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebSearch",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"style": {
|
||||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/aliyunpansearch.json"
|
||||
},
|
||||
{
|
||||
"key": "阿里云盘",
|
||||
"name": "❤我的|阿里",
|
||||
"type": 3,
|
||||
"api": "csp_PanAli",
|
||||
"searchable": 0,
|
||||
"filterable": 0,
|
||||
"changeable": 0,
|
||||
"style": {
|
||||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/aliShare.json"
|
||||
},
|
||||
{
|
||||
"key": "夸克云盘",
|
||||
"name": "❤我的|夸克",
|
||||
"type": 3,
|
||||
"api": "csp_PanQuark",
|
||||
"searchable": 0,
|
||||
"filterable": 0,
|
||||
"changeable": 0,
|
||||
"style": {
|
||||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/quarkShare.json"
|
||||
},
|
||||
{
|
||||
"key": "UC",
|
||||
"name": "❤我的|UC",
|
||||
"type": 3,
|
||||
"api": "csp_PanUc",
|
||||
"searchable": 0,
|
||||
"filterable": 0,
|
||||
"changeable": 0,
|
||||
"style": {
|
||||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/ucShare.json"
|
||||
},
|
||||
{
|
||||
"key": "百度云盘",
|
||||
"name": "❤我的|百度",
|
||||
"type": 3,
|
||||
"api": "csp_PanBaiDu",
|
||||
"searchable": 0,
|
||||
"filterable": 0,
|
||||
"changeable": 0,
|
||||
"style": {
|
||||
"type": "list",
|
||||
"ratio": 1.433
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "push_agent",
|
||||
"name": "📢手机|推送",
|
||||
|
@ -1018,7 +1268,7 @@
|
|||
"api": "csp_Market",
|
||||
"searchable": 0,
|
||||
"changeable": 0,
|
||||
"ext": "http://123.yy.xn--dkw.xn--6qq986b3xl/sd.php"
|
||||
"ext": "http://123.yy.xn--dkw.xn--6qq986b3xl/zm/sd.php"
|
||||
},
|
||||
{
|
||||
"key": "豆瓣3",
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import re
|
||||
import sys
|
||||
from Crypto.Hash import MD5
|
||||
sys.path.append("..")
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import pad, unpad
|
||||
from urllib.parse import quote, urlparse
|
||||
from base64 import b64encode, b64decode
|
||||
import json
|
||||
import time
|
||||
from base.spider import Spider
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
self.host = self.gethost()
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def action(self, action):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
def homeContent(self, filter):
|
||||
data = self.getdata("/api.php/getappapi.index/initV119")
|
||||
dy = {"class": "类型", "area": "地区", "lang": "语言", "year": "年份", "letter": "字母", "by": "排序",
|
||||
"sort": "排序"}
|
||||
filters = {}
|
||||
classes = []
|
||||
json_data = data["type_list"]
|
||||
homedata = data["banner_list"][8:]
|
||||
for item in json_data:
|
||||
if item["type_name"] == "全部":
|
||||
continue
|
||||
has_non_empty_field = False
|
||||
jsontype_extend = json.loads(item["type_extend"])
|
||||
homedata.extend(item["recommend_list"])
|
||||
jsontype_extend["sort"] = "最新,最热,最赞"
|
||||
classes.append({"type_name": item["type_name"], "type_id": item["type_id"]})
|
||||
for key in dy:
|
||||
if key in jsontype_extend and jsontype_extend[key].strip() != "":
|
||||
has_non_empty_field = True
|
||||
break
|
||||
if has_non_empty_field:
|
||||
filters[str(item["type_id"])] = []
|
||||
for dkey in jsontype_extend:
|
||||
if dkey in dy and jsontype_extend[dkey].strip() != "":
|
||||
values = jsontype_extend[dkey].split(",")
|
||||
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
|
||||
value.strip() != ""]
|
||||
filters[str(item["type_id"])].append({"key": dkey, "name": dy[dkey], "value": value_array})
|
||||
result = {}
|
||||
result["class"] = classes
|
||||
result["filters"] = filters
|
||||
result["list"] = homedata[1:]
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
pass
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
body = {"area": extend.get('area', '全部'), "year": extend.get('year', '全部'), "type_id": tid, "page": pg,
|
||||
"sort": extend.get('sort', '最新'), "lang": extend.get('lang', '全部'),
|
||||
"class": extend.get('class', '全部')}
|
||||
result = {}
|
||||
data = self.getdata("/api.php/getappapi.index/typeFilterVodList", body)
|
||||
result["list"] = data["recommend_list"]
|
||||
result["page"] = pg
|
||||
result["pagecount"] = 9999
|
||||
result["limit"] = 90
|
||||
result["total"] = 999999
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
body = f"vod_id={ids[0]}"
|
||||
data = self.getdata("/api.php/getappapi.index/vodDetail", body)
|
||||
vod = data["vod"]
|
||||
play = []
|
||||
names = []
|
||||
for itt in data["vod_play_list"]:
|
||||
a = []
|
||||
names.append(itt["player_info"]["show"])
|
||||
for it in itt['urls']:
|
||||
it['user_agent']=itt["player_info"].get("user_agent")
|
||||
it["parse"]=itt["player_info"].get("parse")
|
||||
a.append(f"{it['name']}${self.e64(json.dumps(it))}")
|
||||
play.append("#".join(a))
|
||||
vod["vod_play_from"] = "$$$".join(names)
|
||||
vod["vod_play_url"] = "$$$".join(play)
|
||||
result = {"list": [vod]}
|
||||
return result
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
body = f"keywords={key}&type_id=0&page={pg}"
|
||||
data = self.getdata("/api.php/getappapi.index/searchList", body)
|
||||
result = {"list": data["search_list"], "page": pg}
|
||||
return result
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
ids = json.loads(self.d64(id))
|
||||
h = {"User-Agent": (ids['user_agent'] or "okhttp/3.14.9")}
|
||||
try:
|
||||
if re.search(r'url=', ids['parse_api_url']):
|
||||
data = self.fetch(ids['parse_api_url'], headers=h, timeout=10).json()
|
||||
url = data.get('url') or data['data'].get('url')
|
||||
else:
|
||||
body = f"parse_api={ids.get('parse') or ids['parse_api_url'].replace(ids['url'], '')}&url={quote(self.aes(ids['url'], True))}&token={ids.get('token')}"
|
||||
b = self.getdata("/api.php/getappapi.index/vodParse", body)['json']
|
||||
url = json.loads(b)['url']
|
||||
if 'error' in url: raise ValueError(f"解析失败: {url}")
|
||||
p = 0
|
||||
except Exception as e:
|
||||
print('错误信息:', e)
|
||||
url, p = ids['url'], 1
|
||||
|
||||
if re.search(r'\.jpg|\.png|\.jpeg', url):
|
||||
url = self.Mproxy(url)
|
||||
result = {}
|
||||
result["parse"] = p
|
||||
result["url"] = url
|
||||
result["header"] = h
|
||||
return result
|
||||
|
||||
def localProxy(self, param):
|
||||
return self.Mlocal(param)
|
||||
|
||||
def gethost(self):
|
||||
headers = {
|
||||
'User-Agent': 'okhttp/3.14.9'
|
||||
}
|
||||
host = self.fetch('http://host.yyys.news/250123.txt', headers=headers).text
|
||||
return host.strip()
|
||||
|
||||
phend = {
|
||||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 11; M2012K10C Build/RP1A.200720.011)',
|
||||
'allowCrossProtocolRedirects': 'true'
|
||||
}
|
||||
|
||||
def aes(self, text,b=None):
|
||||
key = b"RuN9LRvwTRgpQnpK"
|
||||
cipher = AES.new(key, AES.MODE_CBC, key)
|
||||
if b:
|
||||
ct_bytes = cipher.encrypt(pad(text.encode("utf-8"), AES.block_size))
|
||||
ct = b64encode(ct_bytes).decode("utf-8")
|
||||
return ct
|
||||
else :
|
||||
pt = unpad(cipher.decrypt(b64decode(text)), AES.block_size)
|
||||
return pt.decode("utf-8")
|
||||
|
||||
def header(self):
|
||||
t = str(int(time.time()))
|
||||
header = {"Referer":self.host,
|
||||
"User-Agent": "okhttp/3.14.9", "app-version-code": "547", "app-ui-mode": "light",
|
||||
"app-api-verify-time": t, "app-user-device-id": self.md5(t),
|
||||
"app-api-verify-sign": self.aes(t,True),
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
|
||||
return header
|
||||
|
||||
def getdata(self, path, data=None):
|
||||
vdata = self.post(f"{self.host}{path}", headers=self.header(), data=data, timeout=10).json()['data']
|
||||
data1 = self.aes(vdata)
|
||||
return json.loads(data1)
|
||||
|
||||
def Mproxy(self, url):
|
||||
return f"{self.getProxyUrl()}&url={self.e64(url)}&type=m3u8"
|
||||
|
||||
def Mlocal(self, param,header=None):
|
||||
url = self.d64(param["url"])
|
||||
ydata = self.fetch(url, headers=header, allow_redirects=False)
|
||||
data = ydata.content.decode('utf-8')
|
||||
if ydata.headers.get('Location'):
|
||||
url = ydata.headers['Location']
|
||||
data = self.fetch(url, headers=header).content.decode('utf-8')
|
||||
parsed_url = urlparse(url)
|
||||
durl = parsed_url.scheme + "://" + parsed_url.netloc
|
||||
lines = data.strip().split('\n')
|
||||
for index, string in enumerate(lines):
|
||||
if '#EXT' not in string and 'http' not in string:
|
||||
last_slash_index = string.rfind('/')
|
||||
lpath = string[:last_slash_index + 1]
|
||||
lines[index] = durl + ('' if lpath.startswith('/') else '/') + lpath
|
||||
data = '\n'.join(lines)
|
||||
return [200, "application/vnd.apple.mpegur", data]
|
||||
|
||||
def e64(self, text):
|
||||
try:
|
||||
text_bytes = text.encode('utf-8')
|
||||
encoded_bytes = b64encode(text_bytes)
|
||||
return encoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64编码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def d64(self,encoded_text):
|
||||
try:
|
||||
encoded_bytes = encoded_text.encode('utf-8')
|
||||
decoded_bytes = b64decode(encoded_bytes)
|
||||
return decoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64解码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def md5(self, text):
|
||||
h = MD5.new()
|
||||
h.update(text.encode('utf-8'))
|
||||
return h.hexdigest()
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import sys
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
|
||||
|
||||
class Spider(Spider):
|
||||
def getName(self):
|
||||
return "mp"
|
||||
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
host = 'https://g.c494.com'
|
||||
|
||||
header = {
|
||||
'User-Agent': 'Dart/2.10 (dart:io)',
|
||||
'platform_version': 'RP1A.200720.011',
|
||||
'version': '2.2.3',
|
||||
'copyright': 'xiaogui',
|
||||
'platform': 'android',
|
||||
'client_name': '576O5p+P5b2x6KeG',
|
||||
}
|
||||
|
||||
def homeContent(self, filter):
|
||||
data = self.fetch(f'{self.host}/api.php/app/nav?token=', headers=self.header).json()
|
||||
dy = {"class": "类型", "area": "地区", "lang": "语言", "year": "年份", "letter": "字母", "by": "排序",
|
||||
"sort": "排序"}
|
||||
filters = {}
|
||||
classes = []
|
||||
json_data = data["list"]
|
||||
for item in json_data:
|
||||
has_non_empty_field = False
|
||||
jsontype_extend = item["type_extend"]
|
||||
classes.append({"type_name": item["type_name"], "type_id": str(item["type_id"])})
|
||||
for key in dy:
|
||||
if key in jsontype_extend and jsontype_extend[key].strip() != "":
|
||||
has_non_empty_field = True
|
||||
break
|
||||
if has_non_empty_field:
|
||||
filters[str(item["type_id"])] = []
|
||||
for dkey in jsontype_extend:
|
||||
if dkey in dy and jsontype_extend[dkey].strip() != "":
|
||||
values = jsontype_extend[dkey].split(",")
|
||||
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
|
||||
value.strip() != ""]
|
||||
filters[str(item["type_id"])].append({"key": dkey, "name": dy[dkey], "value": value_array})
|
||||
result = {}
|
||||
result["class"] = classes
|
||||
result["filters"] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
rsp = self.fetch(f"{self.host}/api.php/app/index_video?token=", headers=self.header)
|
||||
root = rsp.json()['list']
|
||||
videos = [item for vodd in root for item in vodd['vlist']]
|
||||
return {'list': videos}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
parms = {"pg": pg, "tid": tid, "class": extend.get("class", ""), "area": extend.get("area", ""),
|
||||
"lang": extend.get("lang", ""), "year": extend.get("year", ""), "token": ""}
|
||||
data = self.fetch(f'{self.host}/api.php/app/video', params=parms, headers=self.header).json()
|
||||
return data
|
||||
|
||||
def detailContent(self, ids):
|
||||
parms = {"id": ids[0], "token": ""}
|
||||
data = self.fetch(f'{self.host}/api.php/app/video_detail', params=parms, headers=self.header).json()
|
||||
vod = data['data']
|
||||
vod.pop('pause_advert_list', None)
|
||||
vod.pop('init_advert_list', None)
|
||||
vod.pop('vod_url_with_player', None)
|
||||
return {"list": [vod]}
|
||||
|
||||
def searchContent(self, key, quick, pg='1'):
|
||||
parms = {'pg': pg, 'text': key, 'token': ''}
|
||||
data = self.fetch(f'{self.host}/api.php/app/search', params=parms, headers=self.header).json()
|
||||
return data
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
return {"parse": 0, "url": id, "header": {'User-Agent': 'User-Agent: Lavf/58.12.100'}}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
|
@ -0,0 +1,255 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import re
|
||||
import sys
|
||||
from Crypto.Hash import MD5
|
||||
sys.path.append("..")
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import pad, unpad
|
||||
from urllib.parse import quote, urlparse
|
||||
from base64 import b64encode, b64decode
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import json
|
||||
import time
|
||||
from base.spider import Spider
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
'''
|
||||
sites照常配置,
|
||||
lives配置:
|
||||
{
|
||||
"name": "xxxx",
|
||||
"type": 3,
|
||||
"api": "路径/若惜追剧APP.py",
|
||||
"ext": ""
|
||||
}
|
||||
'''
|
||||
|
||||
def init(self, extend=""):
|
||||
self.host = self.gethost()
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def action(self, action):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
def homeContent(self, filter):
|
||||
data = self.getdata("/api.php/getappapi.index/initV119")
|
||||
dy = {"class": "类型", "area": "地区", "lang": "语言", "year": "年份", "letter": "字母", "by": "排序",
|
||||
"sort": "排序"}
|
||||
filters = {}
|
||||
classes = []
|
||||
json_data = data["type_list"]
|
||||
homedata = data["banner_list"][8:]
|
||||
for item in json_data:
|
||||
if item["type_name"] == "全部":
|
||||
continue
|
||||
has_non_empty_field = False
|
||||
jsontype_extend = json.loads(item["type_extend"])
|
||||
homedata.extend(item["recommend_list"])
|
||||
jsontype_extend["sort"] = "最新,最热,最赞"
|
||||
classes.append({"type_name": item["type_name"], "type_id": item["type_id"]})
|
||||
for key in dy:
|
||||
if key in jsontype_extend and jsontype_extend[key].strip() != "":
|
||||
has_non_empty_field = True
|
||||
break
|
||||
if has_non_empty_field:
|
||||
filters[str(item["type_id"])] = []
|
||||
for dkey in jsontype_extend:
|
||||
if dkey in dy and jsontype_extend[dkey].strip() != "":
|
||||
values = jsontype_extend[dkey].split(",")
|
||||
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
|
||||
value.strip() != ""]
|
||||
filters[str(item["type_id"])].append({"key": dkey, "name": dy[dkey], "value": value_array})
|
||||
result = {}
|
||||
result["class"] = classes
|
||||
result["filters"] = filters
|
||||
result["list"] = homedata[1:]
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
pass
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
body = {"area": extend.get('area', '全部'), "year": extend.get('year', '全部'), "type_id": tid, "page": pg,
|
||||
"sort": extend.get('sort', '最新'), "lang": extend.get('lang', '全部'),
|
||||
"class": extend.get('class', '全部')}
|
||||
result = {}
|
||||
data = self.getdata("/api.php/getappapi.index/typeFilterVodList", body)
|
||||
result["list"] = data["recommend_list"]
|
||||
result["page"] = pg
|
||||
result["pagecount"] = 9999
|
||||
result["limit"] = 90
|
||||
result["total"] = 999999
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
body = f"vod_id={ids[0]}"
|
||||
data = self.getdata("/api.php/getappapi.index/vodDetail", body)
|
||||
vod = data["vod"]
|
||||
play = []
|
||||
names = []
|
||||
for itt in data["vod_play_list"]:
|
||||
a = []
|
||||
names.append(itt["player_info"]["show"])
|
||||
for it in itt['urls']:
|
||||
it['user_agent']=itt["player_info"].get("user_agent")
|
||||
it["parse"]=itt["player_info"].get("parse")
|
||||
a.append(f"{it['name']}${self.e64(json.dumps(it))}")
|
||||
play.append("#".join(a))
|
||||
vod["vod_play_from"] = "$$$".join(names)
|
||||
vod["vod_play_url"] = "$$$".join(play)
|
||||
result = {"list": [vod]}
|
||||
return result
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
body = f"keywords={key}&type_id=0&page={pg}"
|
||||
data = self.getdata("/api.php/getappapi.index/searchList", body)
|
||||
result = {"list": data["search_list"], "page": pg}
|
||||
return result
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
ids = json.loads(self.d64(id))
|
||||
h={"User-Agent": (ids['user_agent'] or "okhttp/3.14.9")}
|
||||
try:
|
||||
if re.search(r'url=', ids['parse_api_url']):
|
||||
data=self.fetch(ids['parse_api_url'], headers=h, timeout=10).json()
|
||||
url=data.get('url') or data['data'].get('url')
|
||||
else:
|
||||
body = f"parse_api={ids.get('parse') or ids['parse_api_url'].replace(ids['url'], '')}&url={quote(self.aes(ids['url'],True))}&token={ids.get('token')}"
|
||||
b = self.getdata("/api.php/getappapi.index/vodParse", body)['json']
|
||||
url = json.loads(b)['url']
|
||||
if 'error' in url:raise ValueError(f"解析失败: {url}")
|
||||
p=0
|
||||
except Exception as e:
|
||||
print('错误信息:',e)
|
||||
url, p = ids['url'], 1
|
||||
|
||||
if re.search(r'\.jpg|\.png|\.jpeg', url):
|
||||
url = self.Mproxy(url)
|
||||
result = {}
|
||||
result["parse"] = p
|
||||
result["url"] = url
|
||||
result["header"] = h
|
||||
return result
|
||||
|
||||
def liveContent(self, url):
|
||||
id=self.homeContent(True)['class'][-1]['type_id']
|
||||
vlist=self.categoryContent(id,1,False,{})['list']
|
||||
results = []
|
||||
with ThreadPoolExecutor(max_workers=len(vlist)) as executor:
|
||||
futures = [executor.submit(self.livedetailContent, item['vod_name'], item['vod_id']) for item in vlist]
|
||||
for future in futures:
|
||||
try:
|
||||
detail = future.result()
|
||||
if detail:
|
||||
results.append(detail)
|
||||
except Exception as e:
|
||||
print(f"处理详情数据失败: {str(e)}")
|
||||
return '\n'.join(results)
|
||||
|
||||
def livedetailContent(self, name,id):
|
||||
try:
|
||||
print(f"获取直播源:{name}")
|
||||
body = f"vod_id={id}"
|
||||
data = self.getdata("/api.php/getappapi.index/vodDetail", body)
|
||||
play = [f"{name},#genre#"]
|
||||
for itt in data["vod_play_list"]:
|
||||
for it in itt['urls']:
|
||||
play.append(f"{it['name']}, {it['url']}")
|
||||
except Exception as e:
|
||||
print(f"获取直播源失败:{str(e)}")
|
||||
play=[]
|
||||
return '\n'.join(play)
|
||||
|
||||
def localProxy(self, param):
|
||||
return self.Mlocal(param)
|
||||
|
||||
def gethost(self):
|
||||
headers = {
|
||||
'User-Agent': 'okhttp/3.14.9'
|
||||
}
|
||||
host = self.fetch('https://rxysyyds.oss-cn-chengdu.aliyuncs.com/getapp.txt', headers=headers).text
|
||||
return host.strip()
|
||||
|
||||
def aes(self, text,b=None):
|
||||
key = b"ebad3f1a58b13933"
|
||||
cipher = AES.new(key, AES.MODE_CBC, key)
|
||||
if b:
|
||||
ct_bytes = cipher.encrypt(pad(text.encode("utf-8"), AES.block_size))
|
||||
ct = b64encode(ct_bytes).decode("utf-8")
|
||||
return ct
|
||||
else :
|
||||
pt = unpad(cipher.decrypt(b64decode(text)), AES.block_size)
|
||||
return pt.decode("utf-8")
|
||||
|
||||
def header(self):
|
||||
t = str(int(time.time()))
|
||||
header = {"Referer":self.host,
|
||||
"User-Agent": "okhttp/3.14.9", "app-version-code": "140", "app-ui-mode": "light",
|
||||
"app-api-verify-time": t, "app-user-device-id": self.md5(t),
|
||||
"app-api-verify-sign": self.aes(t,True),
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
|
||||
return header
|
||||
|
||||
def getdata(self, path, data=None):
|
||||
vdata = self.post(f"{self.host}{path}", headers=self.header(), data=data, timeout=10).json()['data']
|
||||
data1 = self.aes(vdata)
|
||||
return json.loads(data1)
|
||||
|
||||
def Mproxy(self, url):
|
||||
return f"{self.getProxyUrl()}&url={self.e64(url)}&type=m3u8"
|
||||
|
||||
def Mlocal(self, param,header=None):
|
||||
url = self.d64(param["url"])
|
||||
ydata = self.fetch(url, headers=header, allow_redirects=False)
|
||||
data = ydata.content.decode('utf-8')
|
||||
if ydata.headers.get('Location'):
|
||||
url = ydata.headers['Location']
|
||||
data = self.fetch(url, headers=header).content.decode('utf-8')
|
||||
parsed_url = urlparse(url)
|
||||
durl = parsed_url.scheme + "://" + parsed_url.netloc
|
||||
lines = data.strip().split('\n')
|
||||
for index, string in enumerate(lines):
|
||||
if '#EXT' not in string and 'http' not in string:
|
||||
last_slash_index = string.rfind('/')
|
||||
lpath = string[:last_slash_index + 1]
|
||||
lines[index] = durl + ('' if lpath.startswith('/') else '/') + lpath
|
||||
data = '\n'.join(lines)
|
||||
return [200, "application/vnd.apple.mpegur", data]
|
||||
|
||||
def e64(self, text):
|
||||
try:
|
||||
text_bytes = text.encode('utf-8')
|
||||
encoded_bytes = b64encode(text_bytes)
|
||||
return encoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64编码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def d64(self,encoded_text):
|
||||
try:
|
||||
encoded_bytes = encoded_text.encode('utf-8')
|
||||
decoded_bytes = b64decode(encoded_bytes)
|
||||
return decoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64解码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def md5(self, text):
|
||||
h = MD5.new()
|
||||
h.update(text.encode('utf-8'))
|
||||
return h.hexdigest()
|
|
@ -0,0 +1,340 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import binascii
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
from urllib.parse import urlparse
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
from base64 import b64encode, b64decode
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Cipher import AES, PKCS1_v1_5
|
||||
from Crypto.Util.Padding import unpad, pad
|
||||
from Crypto.Hash import MD5
|
||||
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
self.host = self.gethost()
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
headers = {
|
||||
'AppID': '534',
|
||||
'app_id': '534',
|
||||
'version': '1.0.3',
|
||||
'package': 'com.hjmore.wallpaper',
|
||||
'user_id': '3507f394e83d2424',
|
||||
'user-id': '3507f394e83d2424',
|
||||
'app_name': 'lanlan',
|
||||
'app-name': 'lanlan',
|
||||
'Content-Type': 'application/json; charset=utf-8;',
|
||||
'User-Agent': 'okhttp/4.9.0'
|
||||
}
|
||||
|
||||
def homeContent(self, filter):
|
||||
hdata=self.getdata('/api.php/provide/index',self.getbody({'tid':'0'}))
|
||||
vlist=hdata['data'].get('tj',[])
|
||||
result = {}
|
||||
classes = []
|
||||
filters = {}
|
||||
for i in hdata['data']['sub_data']:
|
||||
id=str(i['type_id'])
|
||||
classes.append({'type_id': id, 'type_name': i['type_name']})
|
||||
if len(i['data']):
|
||||
vlist.extend(i['data'])
|
||||
with ThreadPoolExecutor(max_workers=len(classes)) as executor:
|
||||
results = executor.map(self.getf, classes)
|
||||
for id, ft in results:
|
||||
if len(ft):filters[id] = ft
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
result['list'] = vlist
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
pass
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
body={
|
||||
"tid": tid,
|
||||
"type": extend.get('type'),
|
||||
"lang": extend.get('lang'),
|
||||
"area": extend.get('area'),
|
||||
"year": extend.get('year'),
|
||||
"pg": pg
|
||||
}
|
||||
body = {k: v for k, v in body.items() if v is not None and v != ""}
|
||||
data=self.getdata('/api.php/provide/nav',self.getbody(body))
|
||||
result = {}
|
||||
result['list'] = data['data']['data']
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 9999
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
return result
|
||||
pass
|
||||
|
||||
def detailContent(self, ids):
|
||||
data=self.getdata('/api.php/provide/vod',self.getbody({'ids':ids[0]}))
|
||||
vod=data['data']
|
||||
plist=[]
|
||||
names=[]
|
||||
for i in vod['vod_play_url']:
|
||||
ulist=[]
|
||||
names.append(i['name'].split(' ')[0])
|
||||
jdata={'parse':''}
|
||||
if i.get('parse') and isinstance(i['parse'], list) and len(i['parse']):
|
||||
jdata['parse']=self.e64(json.dumps(i['parse']))
|
||||
for j in i['data']:
|
||||
jdata['url']=j['url']
|
||||
ulist.append(f'{j["name"]}${self.e64(json.dumps(jdata))}')
|
||||
plist.append('#'.join(ulist))
|
||||
vod['vod_play_from']='$$$'.join(names)
|
||||
vod['vod_play_url']='$$$'.join(plist)
|
||||
vod.pop('cover_list', None)
|
||||
return {'list':[vod]}
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
body={"wd":key,"tid":"0","pg":pg}
|
||||
data=self.getdata('/api.php/provide/search',self.getbody(body))
|
||||
vlist=[]
|
||||
for i in data['data']:
|
||||
i.pop('vod_play_from', None)
|
||||
vlist.append(i)
|
||||
return {'list':vlist,'page':pg}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
data=json.loads(self.d64(id))
|
||||
parse=data.get('parse')
|
||||
url,p,head = data.get('url'),1,''
|
||||
if parse:
|
||||
parse=json.loads(self.d64(parse))
|
||||
if not re.search(r'\.m3u8|.mp4|\.flv', url) and parse:
|
||||
for p in parse:
|
||||
try:
|
||||
data=self.fetch(f'{p}{url}',self.headers).json()
|
||||
url=data.get('data',{}).get('url') or data.get('url')
|
||||
head=data.get('data',{}).get('header') or data.get('header')
|
||||
p=0
|
||||
break
|
||||
except:
|
||||
p,url=1,data.get('url')
|
||||
head = {'User-Agent': 'okhttp/4.9.0'}
|
||||
return {'parse': p, 'url': url, 'header': head}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def getf(self, map):
|
||||
ft,id =[], map['type_id']
|
||||
try:
|
||||
fdata = self.getdata('/api.php/provide/nav', self.getbody({'tid': id, 'pg': '1'}))
|
||||
dy = ['area', 'year', 'lang', 'type']
|
||||
fd = fdata['data']['type_extend']
|
||||
has_non_empty_field = False
|
||||
for key in dy:
|
||||
if key in fd and fd[key].strip() != "":
|
||||
has_non_empty_field = True
|
||||
break
|
||||
if has_non_empty_field:
|
||||
for dkey in fd:
|
||||
if dkey in dy and fd[dkey].strip() != "":
|
||||
values = fd[dkey].split(",")
|
||||
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
|
||||
value.strip() != ""]
|
||||
ft.append({"key": dkey, "name": dkey, "value": value_array})
|
||||
return (id, ft)
|
||||
except:
|
||||
return (id, ft)
|
||||
|
||||
def getskey(self):
|
||||
random_bytes = os.urandom(16)
|
||||
return binascii.hexlify(random_bytes).decode()
|
||||
|
||||
def getohost(self):
|
||||
url='https://bianyuan001.oss-cn-beijing.aliyuncs.com/huidu1.0.0.json'
|
||||
response = self.fetch(url, headers=self.headers).json()
|
||||
return response['servers'][0]
|
||||
|
||||
def gethost(self):
|
||||
body={
|
||||
"gr_rp_size": "1080*2272",
|
||||
"gr_app_list": "%E5%B1%8F%E5%B9%95%E5%BD%95%E5%88%B6%EF%BC%88com.miui.screenrecorder%29%0A%E5%A4%B8%E5%85%8B%EF%BC%88com.quark.browser%29%0A%E8%BE%B9%E7%BC%98%E8%A7%86%E9%A2%91%EF%BC%88com.hjmore.wallpaper%29%0A%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9%EF%BC%88tv.danmaku.bili%29%0A%E7%81%AB%E6%98%9F%E6%90%9C%E9%A2%98%EF%BC%88com.fenbi.android.souti%29%0A%E6%94%AF%E4%BB%98%E5%AE%9D%EF%BC%88com.eg.android.AlipayGphone%29%0AWPS%20Office%EF%BC%88cn.wps.moffice_eng%29",
|
||||
"gr_lal": "0.0%2C0.0",
|
||||
"gr_system_type": "android",
|
||||
"gr_device_imei": "3507f394e83d2424",
|
||||
"gr_app_version": "1.0.3",
|
||||
"gr_device_model": "Xiaomi%20M2012K10C%20%28Android%20%E7%89%88%E6%9C%AC%3A%2011%2C%20SDK%E7%89%88%E6%9C%AC%3A%2030%29",
|
||||
"gr_city": "%E8%B4%B5%E5%B7%9E%2C%E6%9C%AA%E7%9F%A5%2C%E6%9C%AA%E7%9F%A5",
|
||||
"requestId": self.uuid(),
|
||||
"timeStamp": str(int(time.time() * 1000)),
|
||||
"version": "1.0.3",
|
||||
"package": "com.hjmore.wallpaper",
|
||||
"userLoginToken": "",
|
||||
"app_id": "534",
|
||||
"appName": 2131951658,
|
||||
"device_id": "3507f394e83d2424",
|
||||
"device-id": "3507f394e83d2424",
|
||||
"oaid": "",
|
||||
"imei": "",
|
||||
"referer_shop": "边缘影视",
|
||||
"referer-shop": "边缘影视",
|
||||
"access_fine_location": 0,
|
||||
"access-fine-location": 0
|
||||
}
|
||||
ohost = self.getohost()
|
||||
data=self.getdata(f'/api.php/settings/grayscale_list',body,ohost)
|
||||
parsed_url = urlparse(data['data']['grayscale']['server_url'][0])
|
||||
domain = parsed_url.scheme + "://" + parsed_url.netloc
|
||||
return domain
|
||||
|
||||
def drsa(self, encrypted_data):
|
||||
private_key_pem = """-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDA5NWiAwRjH50/
|
||||
IJY1N0zLopa4jpuWE7kWMn1Qunu6SjBgTvNRmRUoPDHn54haLfbfXIa2X+/sIaMB
|
||||
/O3HhrpVsz55E5W2vpZ5fBYWh+M65bQERKTW+l72H7GR9x0yj3QPByzzfsj/QkyP
|
||||
81prpwR9i8yMe7yG9TFKqUQCPE+/GrhNU1Qf6nFmV+vMnlP9DantkwAt4fPOMZn3
|
||||
j4da65/1YQV+F5bYzaLenNVKbHf8U8fVYLZWIy4yk2Vpe4R2Z+JX/eHWsChE9hOu
|
||||
iFm02eTW5NJLZlWUxYrSE23VXi8oXSEdON3UEOrwSdAUh4SXxLZ9U7KpNVdTwWyR
|
||||
AS4GyzJ/AgMBAAECggEBAKzmcXefLLeNBu4mz30z7Go7es5DRcLoOudiqmFKRs1c
|
||||
4q/xFLj3drdx/WnZZ6ctvDPKRBYFOJF4NRz7Ekfew/c9i6oLnA8KFuceCs53T37j
|
||||
ltCclwT7t1L2ZbxovIsteuJdlDVOV+w2CVqez1Xfh27heKAT6ZEvBtfdkVBPr0uj
|
||||
oVwa2+XlJmYZw5dHeB7ySVeAQ+69zDuADB8OWxPWsv6Del+Fhf0kTHAw4WgqcYsd
|
||||
JUunCjgLdJUlDgXzH/M/Nj8NYVEuq6QpmhaktJ4fwn/F7u3lQllVCFKj5lr0Xb92
|
||||
y7lvQlGqMKX1oxf+P5c5/vie1kDx1Rj4S++flIcVlUECgYEA4BuxCZ1c8oOF98bs
|
||||
KTAONnnZniQ1BRt7rA+O9+++lDjxJhxkuthwjB9YzrnZtxHJtvIIie9Jv8MVfzHa
|
||||
p2woDtiEh3YYwmIlgNUFvTcGe++tTiEiLDcGc/xNhpvfbLaw9QB7/HQ+LT1QCMxJ
|
||||
ufdBrR98l0khIGjYqxDW3W5pV70CgYEA3Ff/9+GM2XI/EUSTYrpnwp5R5OsXz1DL
|
||||
3CFFgp1EPCNk/c3YNWnrUtTkfmKAlRqWIHfphvH/jS6jpGrfRxDggPwGMtBc134b
|
||||
brIM5i4KNj/EcE+w5g03HaKBf1ZihHDQ53c6wTn6IFOHJNSPRLqMNqRymfbclNyO
|
||||
lBMHQmB8yOsCgYBCdZPTwRnuRTi2WQRx1nFwkEQL1Lrwb80GInsIZc2DkTtaTPNG
|
||||
QadmtmkUrSK2Wo0SNsZ3eUHKn2TBmpw4KCfc9zKeJVSEWKy8fu+7xBSlLlebotHK
|
||||
gOrl/H1VHOZuC+OAVItwO1yw98zDPynh/0Q3ve2pw6MSRGV0nYLKmdKdlQKBgQCJ
|
||||
Ty1rw1qKhu9WS22tMIxIc3CFPxtvTeI8I1+1rVtAPq5Im2YIoyDKVXCucaO/RvoW
|
||||
8aLNPTELQe0oIJFTL+k3d9ZFBCNXBncB3GK9biNe+w3nD0IlmkamaQZZ2/M4pTUJ
|
||||
iPtMPlzomCS3ht5g7f9CbegcmgGLooYXMGRtsMMSUQKBgQCoj+3UciH2i+HyUla5
|
||||
1FxivjH3MqSTE4Q7OdzrELb6DoLYzjgWAbpG8HIuodD4uG5xz1oR5H7vkblf1itB
|
||||
hwOwDEiabyX76e/I3Q0ovwBV+9PMjM4UVU0kHoiu3Z2s90ckwNh58w3QH5fn9E0b
|
||||
fqMnB6uWze+xrXWijaOzVZhIZg==
|
||||
-----END RSA PRIVATE KEY-----"""
|
||||
private_key = RSA.import_key(private_key_pem)
|
||||
cipher = PKCS1_v1_5.new(private_key)
|
||||
decrypted_data = cipher.decrypt(b64decode(encrypted_data), None)
|
||||
return decrypted_data.decode('utf-8')
|
||||
|
||||
def ersa(self, data):
|
||||
public_key = """-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+0QMb3WDXjNBRovRhTLH
|
||||
g3d+CliZAva2tepWNNN0Pj6DgE3ZTnPR34iL/cjo9Jbd3dqAJs/YkKnFurGkDxz5
|
||||
TthIqvmz244wiFcHt+FGWoJsj5ZVvrH3pPwH85ggmI1DjxSJEUhB12Z9X6FGli8D
|
||||
drR9xeLe5y8vFekux8xCQ7pwH1mNQu4Wy32WVM8aLjmRjNzEWOvEMAWCRuwymEdS
|
||||
zlWoH53qk1dqd6DAmOJhWU2hH6Yt2ZY9LTaDGiHrS+g0DuwajAQzhbM8eonGYMph
|
||||
nP4q0UTHWEfaGR3HoILmeM32M+qF/UCGfgfR6tCMiXPoHwnD2zoxbZ2p+QlYuTZL
|
||||
vQIDAQAB
|
||||
-----END PUBLIC KEY-----"""
|
||||
key = RSA.importKey(public_key)
|
||||
cipher = PKCS1_v1_5.new(key)
|
||||
encrypted = cipher.encrypt(data.encode())
|
||||
return b64encode(encrypted).decode()
|
||||
|
||||
def eaes(self, data, key):
|
||||
key = key.encode('utf-8')
|
||||
cipher = AES.new(key, AES.MODE_ECB)
|
||||
padded = pad(data.encode('utf-8'), AES.block_size)
|
||||
encrypted = cipher.encrypt(padded)
|
||||
word = b64encode(encrypted).decode('utf-8')
|
||||
return word
|
||||
|
||||
def daes(self, encrypted_data, key):
|
||||
key = key.encode('utf-8')
|
||||
cipher = AES.new(key, AES.MODE_ECB)
|
||||
encrypted = b64decode(encrypted_data)
|
||||
decrypted = cipher.decrypt(encrypted)
|
||||
unpadded = unpad(decrypted, AES.block_size)
|
||||
return unpadded.decode('utf-8')
|
||||
|
||||
def getbody(self,params=None):
|
||||
body = {
|
||||
"requestId": self.uuid(),
|
||||
"timeStamp": str(int(time.time()*1000)),
|
||||
"version": "1.0.3",
|
||||
"package": "com.hjmore.wallpaper",
|
||||
"userLoginToken": "",
|
||||
"app_id": "534",
|
||||
"appName": 2131951658,
|
||||
"device_id": "3507f394e83d2424",
|
||||
"device-id": "3507f394e83d2424",
|
||||
"oaid": "",
|
||||
"imei": "",
|
||||
"referer_shop": "边缘影视",
|
||||
"referer-shop": "边缘影视",
|
||||
"access_fine_location": 0,
|
||||
"access-fine-location": 0
|
||||
}
|
||||
if params:
|
||||
body.update(params)
|
||||
return body
|
||||
|
||||
def getdata(self, path, body,host=None):
|
||||
jdata=json.dumps(body)
|
||||
msign = self.md5(jdata)
|
||||
skey = self.getskey()
|
||||
jsign={'key': skey,'sign': msign}
|
||||
Sign=self.ersa(json.dumps(jsign))
|
||||
header=self.headers.copy()
|
||||
header['Sign']=Sign
|
||||
dbody=self.eaes(jdata, skey)
|
||||
response = self.post(f'{host or self.host}{path}', headers=header, data=dbody)
|
||||
rdata=response.text
|
||||
if response.headers.get('Sign'):
|
||||
dkey=self.drsa(response.headers['Sign'])
|
||||
rdata=self.daes(rdata, dkey)
|
||||
return json.loads(rdata)
|
||||
|
||||
def e64(self, text):
|
||||
try:
|
||||
text_bytes = text.encode('utf-8')
|
||||
encoded_bytes = b64encode(text_bytes)
|
||||
return encoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64编码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def d64(self,encoded_text):
|
||||
try:
|
||||
encoded_bytes = encoded_text.encode('utf-8')
|
||||
decoded_bytes = b64decode(encoded_bytes)
|
||||
return decoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64解码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def md5(self,text):
|
||||
h = MD5.new()
|
||||
h.update(text.encode('utf-8'))
|
||||
return h.hexdigest()
|
||||
|
||||
def uuid(self):
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,199 @@
|
|||
{
|
||||
"classes": [
|
||||
{
|
||||
"type_name": "电影",
|
||||
"type_id": "dy"
|
||||
},
|
||||
{
|
||||
"type_name": "电视",
|
||||
"type_id": "ds"
|
||||
},
|
||||
{
|
||||
"type_name": "短剧",
|
||||
"type_id": "dj"
|
||||
},
|
||||
{
|
||||
"type_name": "综艺",
|
||||
"type_id": "zy"
|
||||
},
|
||||
{
|
||||
"type_name": "动漫",
|
||||
"type_id": "dm"
|
||||
},
|
||||
{
|
||||
"type_name": "音乐",
|
||||
"type_id": "yy"
|
||||
}
|
||||
],
|
||||
"filters": {
|
||||
"dy": [
|
||||
{
|
||||
"key": "root",
|
||||
"name": "来源",
|
||||
"value": [
|
||||
{
|
||||
"n": "全部",
|
||||
"v": "0"
|
||||
},
|
||||
{
|
||||
"n": "夸克",
|
||||
"v": "2"
|
||||
},
|
||||
{
|
||||
"n": "UC",
|
||||
"v": "5"
|
||||
},
|
||||
{
|
||||
"n": "阿里",
|
||||
"v": "1"
|
||||
},
|
||||
{
|
||||
"n": "百度",
|
||||
"v": "4"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"ds": [
|
||||
{
|
||||
"key": "root",
|
||||
"name": "来源",
|
||||
"value": [
|
||||
{
|
||||
"n": "全部",
|
||||
"v": "0"
|
||||
},
|
||||
{
|
||||
"n": "夸克",
|
||||
"v": "2"
|
||||
},
|
||||
{
|
||||
"n": "UC",
|
||||
"v": "5"
|
||||
},
|
||||
{
|
||||
"n": "阿里",
|
||||
"v": "1"
|
||||
},
|
||||
{
|
||||
"n": "百度",
|
||||
"v": "4"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dj": [
|
||||
{
|
||||
"key": "root",
|
||||
"name": "来源",
|
||||
"value": [
|
||||
{
|
||||
"n": "全部",
|
||||
"v": "0"
|
||||
},
|
||||
{
|
||||
"n": "夸克",
|
||||
"v": "2"
|
||||
},
|
||||
{
|
||||
"n": "UC",
|
||||
"v": "5"
|
||||
},
|
||||
{
|
||||
"n": "阿里",
|
||||
"v": "1"
|
||||
},
|
||||
{
|
||||
"n": "百度",
|
||||
"v": "4"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"zy": [
|
||||
{
|
||||
"key": "root",
|
||||
"name": "来源",
|
||||
"value": [
|
||||
{
|
||||
"n": "全部",
|
||||
"v": "0"
|
||||
},
|
||||
{
|
||||
"n": "夸克",
|
||||
"v": "2"
|
||||
},
|
||||
{
|
||||
"n": "UC",
|
||||
"v": "5"
|
||||
},
|
||||
{
|
||||
"n": "阿里",
|
||||
"v": "1"
|
||||
},
|
||||
{
|
||||
"n": "百度",
|
||||
"v": "4"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dm": [
|
||||
{
|
||||
"key": "root",
|
||||
"name": "来源",
|
||||
"value": [
|
||||
{
|
||||
"n": "全部",
|
||||
"v": "0"
|
||||
},
|
||||
{
|
||||
"n": "夸克",
|
||||
"v": "2"
|
||||
},
|
||||
{
|
||||
"n": "UC",
|
||||
"v": "5"
|
||||
},
|
||||
{
|
||||
"n": "阿里",
|
||||
"v": "1"
|
||||
},
|
||||
{
|
||||
"n": "百度",
|
||||
"v": "4"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"yy": [
|
||||
{
|
||||
"key": "root",
|
||||
"name": "来源",
|
||||
"value": [
|
||||
{
|
||||
"n": "全部",
|
||||
"v": "0"
|
||||
},
|
||||
{
|
||||
"n": "夸克",
|
||||
"v": "2"
|
||||
},
|
||||
{
|
||||
"n": "UC",
|
||||
"v": "5"
|
||||
},
|
||||
{
|
||||
"n": "阿里",
|
||||
"v": "1"
|
||||
},
|
||||
{
|
||||
"n": "百度",
|
||||
"v": "4"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"siteUrl": "https://ysapi.yingso.fun/v7/ali/all"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"SiteUrl": "https://www.hmxz.org",
|
||||
"Classes": [
|
||||
{
|
||||
"type_name": "电影",
|
||||
"type_id": "1"
|
||||
},
|
||||
{
|
||||
"type_name": "剧集",
|
||||
"type_id": "2"
|
||||
},
|
||||
{
|
||||
"type_name": "综艺",
|
||||
"type_id": "5"
|
||||
},
|
||||
{
|
||||
"type_name": "动漫",
|
||||
"type_id": "3"
|
||||
}
|
||||
],
|
||||
"Cookie": "bbs_sid=ducbgilqu67ff2oirbbh9aq7ol;bbs_token=KLC2C9dxzxxpvoGd4vV8VKgN_2FM1Fbe_2B_2BLShggfWjEmh1kmEA"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"SiteUrl": "https://pan1.me",
|
||||
"Classes": [
|
||||
{
|
||||
"type_name": "电影",
|
||||
"type_id": "2"
|
||||
},
|
||||
{
|
||||
"type_name": "剧集",
|
||||
"type_id": "48"
|
||||
},
|
||||
{
|
||||
"type_name": "4K原盘",
|
||||
"type_id": "56"
|
||||
},
|
||||
{
|
||||
"type_name": "综艺",
|
||||
"type_id": "52"
|
||||
},
|
||||
{
|
||||
"type_name": "动漫",
|
||||
"type_id": "37"
|
||||
}
|
||||
],
|
||||
"Cookie": "bbs_sid=rrru52bda4v655kl9u1c87f00m; bbs_token=dZRAvHbHcUZkuJ7oHALqWoUs00C1fGqqXDXH7I8LH6hMddXP"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2583
欧歌/lives/AI直播.txt
2583
欧歌/lives/AI直播.txt
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
BIN
欧歌/spider.jar
BIN
欧歌/spider.jar
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
aMpWZFkXFecm4hhqZ9yfzBd24WjHV7lEq0TzPXvh8brK9+zi6x5XIpulpwecy92meWuHIvZTeo5jkTch1cNoIHlBErZixB1hzpJ1I6ptPQgHxp+ZCoBpPPZ6UB/jpMssKHVA4QVqXt+zl01X/XSB1VCx0Bml5xCczSFbKCe2MEn0ucTkQtUs9f4dUYprXoFJCfGEIjUF1yOWCKQwUjTYWzMBoj7uWaxEcWfXnnvGvO0BhmEStZ4HOkEVKG7WeLB3Jw11tb61vHpyvDXduNSjYcRNxr8EO9YIgDQsWn4lTgqILnClSUFmjufNkI3IluT1qctR4IVWJPQ7Y7ANQ9kxKMIli2xJmwILFqIsK7kqKOXc3nezbMCS0I+epES9fHMPpczsQPcBfpQT1o485uRClN+dM83gcAn9z90ucIQOKUBbkfmQ+WnvKyApUyFe3aFBkTYj+rFSp1bleilRDoa+yIY05cpDyItqqccy8GBk+dgQ755CMY/VKN9vLlxdoUJMCWZB1FR8VhnW7RpbYc08DOpNChGqKJ6Cwy1qVM/jt61WR2x1VaKreS59j1IMuxDuEBdhlmt+QLsbSWD7blw0ji9AFHAZu3M31oN5D2feEgKZ5oPAiWjpKw7knBA/raonihUn1oE+0e1ILzgrm3uLwb0hpd6xeeRv0vYW2FDCoe3A=
|
BIN
潇洒/.版本.png
BIN
潇洒/.版本.png
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 4.2 KiB |
|
@ -111,21 +111,21 @@ class Spider(Spider):
|
|||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
ids = json.loads(self.d64(id))
|
||||
h={"User-Agent": (ids['user_agent'] or "okhttp/3.14.9")}
|
||||
url = ids['url']
|
||||
p=1
|
||||
h = {"User-Agent": (ids['user_agent'] or "okhttp/3.14.9")}
|
||||
try:
|
||||
if re.search(r'\?url=', ids['parse_api_url']):
|
||||
data=self.fetch(ids['parse_api_url'], headers=h, timeout=10).json()
|
||||
url=data.get('url') or data['data'].get('url')
|
||||
elif not re.search(r'\.m3u8|\.mp4', ids.get('url')):
|
||||
body = f"parse_api={ids.get('parse') or ids['parse_api_url'].replace(ids['url'], '')}&url={quote(self.aes('encrypt', ids['url']))}&token={ids.get('token')}"
|
||||
if re.search(r'url=', ids['parse_api_url']):
|
||||
data = self.fetch(ids['parse_api_url'], headers=h, timeout=10).json()
|
||||
url = data.get('url') or data['data'].get('url')
|
||||
else:
|
||||
body = f"parse_api={ids.get('parse') or ids['parse_api_url'].replace(ids['url'], '')}&url={quote(self.aes(ids['url'], True))}&token={ids.get('token')}"
|
||||
b = self.getdata("/api.php/getappapi.index/vodParse", body)['json']
|
||||
url = json.loads(b)['url']
|
||||
p=0
|
||||
if 'error' in url: raise ValueError(f"解析失败: {url}")
|
||||
p = 0
|
||||
except Exception as e:
|
||||
print('错误信息:',e)
|
||||
pass
|
||||
print('错误信息:', e)
|
||||
url, p = ids['url'], 1
|
||||
|
||||
if re.search(r'\.jpg|\.png|\.jpeg', url):
|
||||
url = self.Mproxy(url)
|
||||
result = {}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"主页url": "https://www.aiwodj.com",
|
||||
"数组": "lazy lazyloaded&&</a[替换:amp;>>]",
|
||||
"图片": "data-src=\"&&\"",
|
||||
"标题": "title=\"&&\"",
|
||||
"链接": "href=\"&&\"",
|
||||
"副标题": "+module-item-caption\">&&</div",
|
||||
"简介": "description\" content=\"&&,这里",
|
||||
"线路数组": "module-tab-item tab-item&&</div",
|
||||
"线路标题": "+span>&&</span",
|
||||
"播放数组": "module-blocklist&&</div>",
|
||||
"播放列表": "<a&&</a>",
|
||||
"播放标题": "span>&&</span>",
|
||||
"播放链接": "href=\"&&\"",
|
||||
"跳转播放链接": "urlDecode(var player_*\"url\":\"&&\")",
|
||||
"搜索url": "https://www.aiwodj.com/vodsearch/{wd}----------{pg}---.html",
|
||||
"搜索数组": "lazy lazyload&&</a[替换:amp;>>]",
|
||||
"搜索图片": "data-src=\"&&\"",
|
||||
"搜索标题": "+title=\"&&\"",
|
||||
"搜索链接": "href=\"&&\"",
|
||||
"分类url": "https://www.aiwodj.com/vodshow/{cateId}--{by}-{class}-{lang}----{catePg}---{year}.html",
|
||||
"分类": "穿越&战神&重生&爱情&萌娃&神医&古代&玄幻&言情",
|
||||
"分类值": "fenle&fenlei2&fenlei3&fenlei4&guda&shenyi&gudai&xuanhuan&yanqing"
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
{
|
||||
"规则名": "七新影视",
|
||||
"规则作者": "",
|
||||
"请求头参数": "手机",
|
||||
"网页编码格式": "UTF-8",
|
||||
"图片是否需要代理": "0",
|
||||
"是否开启获取首页数据": "1",
|
||||
"首页推荐链接": "http://www.7xdy.com",
|
||||
"首页列表数组规则": "body&&.stui-vodlist:has(h4)",
|
||||
"首页片单列表数组规则": "li",
|
||||
"首页片单是否Jsoup写法": "1",
|
||||
"分类起始页码": "1",
|
||||
"分类链接": "http://www.7xdy.com/{cateId}/index{catePg}.html[firstPage=http://www.7xdy.com/{cateId}/index.html]",
|
||||
"分类名称": "电影&电视剧&综艺&动漫",
|
||||
"分类名称替换词": "dianyingpian&dianshiju&zongyi&dongman",
|
||||
//"筛选数据": {},
|
||||
"筛选数据": "ext",
|
||||
//{cateId}
|
||||
"筛选子分类名称": "动作片&爱情片&科幻片&恐怖片&战争片&喜剧片&一直播&剧情片||国产剧&港台剧&欧美剧&日韩剧",
|
||||
"筛选子分类替换词": "dongzuopian&aiqingpian&kehuanpian&kongbupian&zhanzhengpian&xijupian&jilupian&juqingpian||guocanju&gangtaiju&oumeiju&rihanju",
|
||||
//{class}
|
||||
"筛选类型名称": "",
|
||||
"筛选类型替换词": "*",
|
||||
//{area}
|
||||
"筛选地区名称": "",
|
||||
"筛选地区替换词": "*",
|
||||
//{year}
|
||||
"筛选年份名称": "",
|
||||
"筛选年份替换词": "*",
|
||||
//{lang}
|
||||
"筛选语言名称": "",
|
||||
"筛选语言替换词": "*",
|
||||
//{by}
|
||||
"筛选排序名称": "时间&人气&评分",
|
||||
"筛选排序替换词": "time&hits&score",
|
||||
"分类截取模式": "1",
|
||||
"分类列表数组规则": ".stui-vodlist&&li",
|
||||
"分类片单是否Jsoup写法": "1",
|
||||
"分类片单标题": "h4&&a&&Text",
|
||||
"分类片单链接": "h4&&a&&href",
|
||||
"分类片单图片": ".lazyload&&data-original",
|
||||
"分类片单副标题": ".pic-text&&Text",
|
||||
"分类片单链接加前缀": "http://www.7xdy.com",
|
||||
"分类片单链接加后缀": "",
|
||||
"搜索请求头参数": "User-Agent$手机",
|
||||
"搜索链接": "http://www.7xdy.com/search.php?page=1&searchword={wd}&searchtype=",
|
||||
"POST请求数据": "searchword={wd}",
|
||||
"搜索截取模式": "1",
|
||||
"搜索列表数组规则": ".stui-vodlist__media&&li",
|
||||
"搜索片单是否Jsoup写法": "1",
|
||||
"搜索片单图片": ".lazyload&&data-original",
|
||||
"搜索片单标题": "h3&&a&&Text",
|
||||
"搜索片单链接": "h3&&a&&href",
|
||||
"搜索片单副标题": ".pic-text&&Text",
|
||||
"搜索片单链接加前缀": "http://www.7xdy.com",
|
||||
"搜索片单链接加后缀": "",
|
||||
"链接是否直接播放": "0",
|
||||
"直接播放链接加前缀": "",
|
||||
"直接播放链接加后缀": "",
|
||||
"直接播放直链视频请求头": "",
|
||||
"详情是否Jsoup写法": "0",
|
||||
"类型详情": "类型:</span>&&</a>",
|
||||
"年代详情": "年份:</span>&&</a>",
|
||||
"地区详情": "地区:</span>&&</a>",
|
||||
"演员详情": "主演:</span>&&</p>",
|
||||
"简介详情": "简介:</span>&&</p>",
|
||||
"线路列表数组规则": "body&&#playlist",
|
||||
"线路标题": "h3&&Text",
|
||||
"播放列表数组规则": "body&&.stui-content__playlist",
|
||||
"选集列表数组规则": "li",
|
||||
"选集标题链接是否Jsoup写法": "1",
|
||||
"选集标题": "a&&Text",
|
||||
"选集链接": "a&&href",
|
||||
"是否反转选集序列": "1",
|
||||
"选集链接加前缀": "http://www.7xdy.com",
|
||||
"选集链接加后缀": "",
|
||||
"分析MacPlayer": "0",
|
||||
"是否开启手动嗅探": "1",
|
||||
"手动嗅探视频链接关键词": ".mp4#.m3u8#.flv#video/tos#pt=m3u8#obj/tos-#video/tos#mime_type=video#x-oss-signature=",
|
||||
"手动嗅探视频链接过滤词": ".html#=http"
|
||||
}
|
244
潇洒/api.json
244
潇洒/api.json
|
@ -38,7 +38,7 @@
|
|||
},
|
||||
{
|
||||
"key": "热播影视",
|
||||
"name": "热播|弹幕",
|
||||
"name": "热播|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppRJ",
|
||||
"searchable": 1,
|
||||
|
@ -50,7 +50,7 @@
|
|||
},
|
||||
{
|
||||
"key": "天天影视",
|
||||
"name": "天天|弹幕",
|
||||
"name": "天天|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppRJ",
|
||||
"searchable": 1,
|
||||
|
@ -62,7 +62,7 @@
|
|||
},
|
||||
{
|
||||
"key": "浪酷影视",
|
||||
"name": "浪酷|弹幕",
|
||||
"name": "浪酷|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppRJ",
|
||||
"searchable": 1,
|
||||
|
@ -74,11 +74,53 @@
|
|||
},
|
||||
{
|
||||
"key": "菲儿影视",
|
||||
"name": "菲菲|弹幕",
|
||||
"name": "菲菲|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppFerr",
|
||||
"ext": "sHR2rlsfjI4L3t4RXQMkn/M3t4AXAKTrZj3tfhm1t/gMT3dOrHqIzUNqLUEOIDMvllTbX6e1hMhB2mfpOaCmHNOL1yBB3SmxNyqXlai90EIpdnwOOgCR9Z+YwCTj6ySjzJ2VBiH3eXeOGcavcNeVRA=="
|
||||
},
|
||||
{
|
||||
"key": "影探影视",
|
||||
"name": "影探|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppYsV2",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "http://cmsyt114.lyyytv.cn/api.php/app/"
|
||||
},
|
||||
{
|
||||
"key": "乐享影视",
|
||||
"name": "乐享|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppYsV2",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "http://114.66.55.28:8818/api.php/app/"
|
||||
},
|
||||
{
|
||||
"key": "金牌影视",
|
||||
"name": "金牌|影视",
|
||||
"type": 3,
|
||||
"api": "./py/金牌影视.py",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2,
|
||||
"ext": {
|
||||
"site": "https://www.hkybqufgh.com,https://www.sizhengxt.com,https://0996zp.com,https://9zhoukj.com/,https://www.sizhengxt.com,https://www.tjrongze.com,https://www.jiabaide.cn,https://cqzuoer.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "哔哩视频",
|
||||
"name": "哔哩|视频",
|
||||
"type": 3,
|
||||
"api": "./py/哔哩视频.py",
|
||||
"ext": {
|
||||
"json": "http://127.0.0.1:9978/file/TVBox/bili_cookie.txt"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "腾讯视频",
|
||||
"name": "腾讯|视频",
|
||||
|
@ -102,7 +144,7 @@
|
|||
},
|
||||
{
|
||||
"key": "爱奇艺",
|
||||
"name": "爱奇艺|视频",
|
||||
"name": "爱奇异|视频",
|
||||
"type": 3,
|
||||
"api": "./js/drpy2.min.js",
|
||||
"ext": "./js/爱奇艺.js"
|
||||
|
@ -153,7 +195,7 @@
|
|||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "./json/wogg.json?"
|
||||
"ext": "./json/wogg.json"
|
||||
},
|
||||
{
|
||||
"key": "木偶",
|
||||
|
@ -163,7 +205,7 @@
|
|||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "./json/mogg.json?"
|
||||
"ext": "./json/mogg.json"
|
||||
},
|
||||
{
|
||||
"key": "蜡笔",
|
||||
|
@ -174,18 +216,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/lb.json?"
|
||||
},
|
||||
{
|
||||
"key": "小米",
|
||||
"name": "小米|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/xm.json?"
|
||||
"ext": "./json/lb.json"
|
||||
},
|
||||
{
|
||||
"key": "至臻",
|
||||
|
@ -196,7 +227,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/zz.json?"
|
||||
"ext": "./json/zz.json"
|
||||
},
|
||||
{
|
||||
"key": "多多",
|
||||
|
@ -207,7 +238,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/yyds.json?"
|
||||
"ext": "./json/yyds.json"
|
||||
},
|
||||
{
|
||||
"key": "欧哥",
|
||||
|
@ -218,7 +249,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/og.json?"
|
||||
"ext": "./json/og.json"
|
||||
},
|
||||
{
|
||||
"key": "二小",
|
||||
|
@ -229,7 +260,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/ex.json?"
|
||||
"ext": "./json/ex.json"
|
||||
},
|
||||
{
|
||||
"key": "百家",
|
||||
|
@ -240,7 +271,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/bj.json?"
|
||||
"ext": "./json/bj.json"
|
||||
},
|
||||
{
|
||||
"key": "大玩",
|
||||
|
@ -251,7 +282,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/dawo.json?"
|
||||
"ext": "./json/dawo.json"
|
||||
},
|
||||
{
|
||||
"key": "虎斑",
|
||||
|
@ -262,7 +293,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/hb.json?"
|
||||
"ext": "./json/hb.json"
|
||||
},
|
||||
{
|
||||
"key": "闪电",
|
||||
|
@ -273,7 +304,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/sd.json?"
|
||||
"ext": "./json/sd.json"
|
||||
},
|
||||
{
|
||||
"key": "下饭",
|
||||
|
@ -284,7 +315,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/xf.json?"
|
||||
"ext": "./json/xf.json"
|
||||
},
|
||||
{
|
||||
"key": "团长",
|
||||
|
@ -309,7 +340,7 @@
|
|||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/lj.json?"
|
||||
"ext": "./json/lj.json"
|
||||
},
|
||||
{
|
||||
"key": "海绵",
|
||||
|
@ -324,7 +355,7 @@
|
|||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/hm.json?"
|
||||
"ext": "./json/hm.json"
|
||||
},
|
||||
{
|
||||
"key": "Pan1",
|
||||
|
@ -339,7 +370,7 @@
|
|||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/pan1.json?"
|
||||
"ext": "./json/pan1.json"
|
||||
},
|
||||
{
|
||||
"key": "趣盘",
|
||||
|
@ -396,10 +427,23 @@
|
|||
"key": "河马短剧",
|
||||
"name": "河马|短剧",
|
||||
"type": 3,
|
||||
"api": "csp_AppHMDJ",
|
||||
"api": "./py/河马短剧.py",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "偷乐短剧",
|
||||
"name": "偷乐|短剧",
|
||||
"type": 3,
|
||||
"api": "./py/偷乐短剧.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "爱看短剧",
|
||||
|
@ -412,16 +456,6 @@
|
|||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "爱我短剧",
|
||||
"name": "爱我|短剧",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "./XBPQ/爱我短剧.json"
|
||||
},
|
||||
{
|
||||
"key": "短剧网",
|
||||
"name": "短剧网|短剧",
|
||||
|
@ -787,12 +821,6 @@
|
|||
"playerType": 2,
|
||||
"ext": "https://shdy5.us"
|
||||
},
|
||||
{
|
||||
"key": "金牌影视",
|
||||
"name": "金牌|影视",
|
||||
"type": 3,
|
||||
"api": "csp_Jpys"
|
||||
},
|
||||
{
|
||||
"key": "尘落影视",
|
||||
"name": "尘落|影视",
|
||||
|
@ -1030,16 +1058,6 @@
|
|||
"filterable": 1,
|
||||
"ext": "./XYQHiker/看看影视.json"
|
||||
},
|
||||
{
|
||||
"key": "七新影视",
|
||||
"name": "七新|影视",
|
||||
"type": 3,
|
||||
"api": "csp_XYQHiker",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "./XYQHiker/七新影视.json"
|
||||
},
|
||||
{
|
||||
"key": "骚火影视",
|
||||
"name": "骚火|影视",
|
||||
|
@ -1176,40 +1194,6 @@
|
|||
"欧美动漫"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "快车资源",
|
||||
"name": "快车|采集",
|
||||
"type": 1,
|
||||
"api": "https://caiji.kczyapi.com/api.php/provide/vod/",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"categories": [
|
||||
"动作片",
|
||||
"喜剧片",
|
||||
"爱情片",
|
||||
"科幻片",
|
||||
"恐怖片",
|
||||
"战争片",
|
||||
"剧情片",
|
||||
"动画片",
|
||||
"纪录片",
|
||||
"国产剧",
|
||||
"香港剧",
|
||||
"台湾剧",
|
||||
"欧美剧",
|
||||
"韩国剧",
|
||||
"日本剧",
|
||||
"泰国剧",
|
||||
"海外剧",
|
||||
"国产动漫",
|
||||
"日本动漫",
|
||||
"欧美动漫",
|
||||
"大陆综艺",
|
||||
"日韩综艺",
|
||||
"港台综艺",
|
||||
"欧美综艺"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "索尼资源",
|
||||
"name": "索尼|采集",
|
||||
|
@ -1691,6 +1675,12 @@
|
|||
},
|
||||
"ext": "./json/alist.json"
|
||||
},
|
||||
{
|
||||
"key": "网络直播",
|
||||
"name": "网络|直播",
|
||||
"type": 3,
|
||||
"api": "./py/网络直播.py"
|
||||
},
|
||||
{
|
||||
"key": "88看球",
|
||||
"name": "88|看球",
|
||||
|
@ -1794,6 +1784,64 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "钓鱼",
|
||||
"type": "1",
|
||||
"url": "http://8.129.30.117:8117/diaoyu.php?url=",
|
||||
"ext": {
|
||||
"flag": [
|
||||
"qq",
|
||||
"腾讯",
|
||||
"qiyi",
|
||||
"爱奇艺",
|
||||
"奇艺",
|
||||
"youku",
|
||||
"优酷",
|
||||
"sohu",
|
||||
"搜狐",
|
||||
"letv",
|
||||
"乐视",
|
||||
"mgtv",
|
||||
"芒果",
|
||||
"tnmb",
|
||||
"seven",
|
||||
"bilibili",
|
||||
"1905"
|
||||
],
|
||||
"header": {
|
||||
"User-Agent": "okhttp/4.9.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "无上",
|
||||
"type": "1",
|
||||
"url": "https://mfjx.iwsyy.xyz/?url=",
|
||||
"ext": {
|
||||
"flag": [
|
||||
"qq",
|
||||
"腾讯",
|
||||
"qiyi",
|
||||
"爱奇艺",
|
||||
"奇艺",
|
||||
"youku",
|
||||
"优酷",
|
||||
"sohu",
|
||||
"搜狐",
|
||||
"letv",
|
||||
"乐视",
|
||||
"mgtv",
|
||||
"芒果",
|
||||
"tnmb",
|
||||
"seven",
|
||||
"bilibili",
|
||||
"1905"
|
||||
],
|
||||
"header": {
|
||||
"User-Agent": "okhttp/4.9.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "臻享",
|
||||
"type": "1",
|
||||
|
@ -2076,6 +2124,14 @@
|
|||
"playerType": 2,
|
||||
"timeout": 10
|
||||
},
|
||||
{
|
||||
"name": "Guovin",
|
||||
"type": 0,
|
||||
"url": "https://gitee.com/mytv-android/iptv-api/raw/master/output/result.m3u",
|
||||
"epg": "http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
|
||||
"playerType": 2,
|
||||
"timeout": 10
|
||||
},
|
||||
{
|
||||
"name": "虎牙一起看",
|
||||
"type": 3,
|
||||
|
|
|
@ -2132,14 +2132,14 @@ var rule = {
|
|||
parse: 0,
|
||||
url: bata.url,
|
||||
jx: 0,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
} else {
|
||||
input = {
|
||||
parse: 0,
|
||||
url: input.split("?")[0],
|
||||
jx: 1,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
|
@ -2147,7 +2147,7 @@ var rule = {
|
|||
parse: 0,
|
||||
url: input.split("?")[0],
|
||||
jx: 1,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -1354,14 +1354,14 @@ var rule = {
|
|||
parse: 0,
|
||||
url: bata.url,
|
||||
jx: 0,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
} else {
|
||||
input = {
|
||||
parse: 0,
|
||||
url: input.split("?")[0],
|
||||
jx: 1,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
|
@ -1369,7 +1369,7 @@ var rule = {
|
|||
parse: 0,
|
||||
url: input.split("?")[0],
|
||||
jx: 1,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -670,14 +670,14 @@ var rule = {
|
|||
parse: 0,
|
||||
url: bata.url,
|
||||
jx: 0,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
} else {
|
||||
input = {
|
||||
parse: 0,
|
||||
url: input.split("?")[0],
|
||||
jx: 1,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
|
@ -685,7 +685,7 @@ var rule = {
|
|||
parse: 0,
|
||||
url: input.split("?")[0],
|
||||
jx: 1,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -679,14 +679,14 @@ var rule = {
|
|||
parse: 0,
|
||||
url: bata.url,
|
||||
jx: 0,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
} else {
|
||||
input = {
|
||||
parse: 0,
|
||||
url: input.split("?")[0],
|
||||
jx: 1,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
|
@ -694,7 +694,7 @@ var rule = {
|
|||
parse: 0,
|
||||
url: input.split("?")[0],
|
||||
jx: 1,
|
||||
danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0]
|
||||
danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0]
|
||||
};
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"SiteUrl": "https://www.leijing1.com",
|
||||
"SiteUrl": "https://www.leijing.xyz",
|
||||
"Classes": [
|
||||
{
|
||||
"type_name": "电影",
|
||||
|
|
|
@ -0,0 +1,301 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from urllib.parse import quote
|
||||
from Crypto.Hash import MD5
|
||||
import requests
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(self.headers)
|
||||
self.session.cookies.update(self.cookie)
|
||||
self.get_ctoken()
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
host='https://www.youku.com'
|
||||
|
||||
shost='https://search.youku.com'
|
||||
|
||||
h5host='https://acs.youku.com'
|
||||
|
||||
ihost='https://v.youku.com'
|
||||
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (; Windows 10.0.26100.3194_64 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Electron/14.2.0 Safari/537.36 Node/14.17.0 YoukuDesktop/9.2.60 UOSYouku (2.0.1)-Electron(UTDID ZYmGMAAAACkDAMU8hbiMmYdd;CHANNEL official;ZREAL 0;BTYPE TM2013;BRAND TIMI;BUILDVER 9.2.60.1001)',
|
||||
'Referer': f'{host}/'
|
||||
}
|
||||
|
||||
cookie={
|
||||
"__ysuid": "17416134165380iB",
|
||||
"__aysid": "1741613416541WbD",
|
||||
"xlly_s": "1",
|
||||
"isI18n": "false",
|
||||
"cna": "bNdVIKmmsHgCAXW9W6yrQ1/s",
|
||||
"__ayft": "1741672162330",
|
||||
"__arpvid": "1741672162331FBKgrn-1741672162342",
|
||||
"__ayscnt": "1",
|
||||
"__aypstp": "1",
|
||||
"__ayspstp": "3",
|
||||
"tfstk": "gZbiib4JpG-6DqW-B98_2rwPuFrd1fTXQt3vHEp4YpJIBA3OgrWcwOi90RTOo9XVQ5tAM5NcK_CP6Ep97K2ce1XDc59v3KXAgGFLyzC11ET2n8U8yoyib67M3xL25e8gS8pbyzC1_ET4e8URWTsSnHv2uh8VTeJBgEuN3d-ELQAWuKWV36PHGpJ2uEWVTxvicLX1ewyUXYSekxMf-CxMEqpnoqVvshvP_pABOwvXjL5wKqeulm52np_zpkfCDGW9Ot4uKFIRwZtP7vP9_gfAr3KEpDWXSIfWRay-DHIc_Z-hAzkD1i5Ooi5LZ0O5YO_1mUc476YMI3R6xzucUnRlNe_zemKdm172xMwr2L7CTgIkbvndhFAVh3_YFV9Ng__52U4SQKIdZZjc4diE4EUxlFrfKmiXbBOHeP72v7sAahuTtWm78hRB1yV3tmg9bBOEhWVnq5KwOBL5."
|
||||
}
|
||||
|
||||
def homeContent(self, filter):
|
||||
result = {}
|
||||
categories = ["电视剧", "电影", "综艺", "动漫", "少儿", "纪录片", "文化", "亲子", "教育", "搞笑", "生活",
|
||||
"体育", "音乐", "游戏"]
|
||||
classes = [{'type_name': category, 'type_id': category} for category in categories]
|
||||
filters = {}
|
||||
self.typeid = {}
|
||||
with ThreadPoolExecutor(max_workers=len(categories)) as executor:
|
||||
tasks = {
|
||||
executor.submit(self.cf, {'type': category}, True): category
|
||||
for category in categories
|
||||
}
|
||||
|
||||
for future in as_completed(tasks):
|
||||
try:
|
||||
category = tasks[future]
|
||||
session, ft = future.result()
|
||||
filters[category] = ft
|
||||
self.typeid[category] = session
|
||||
except Exception as e:
|
||||
print(f"处理分类 {tasks[future]} 时出错: {str(e)}")
|
||||
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
try:
|
||||
vlist = []
|
||||
params={"ms_codes":"2019061000","params":"{\"debug\":0,\"gray\":0,\"pageNo\":1,\"utdid\":\"ZYmGMAAAACkDAMU8hbiMmYdd\",\"userId\":\"\",\"bizKey\":\"YOUKU_WEB\",\"appPackageKey\":\"com.youku.YouKu\",\"showNodeList\":0,\"reqSubNode\":0,\"nodeKey\":\"WEBHOME\",\"bizContext\":\"{\\\"spmA\\\":\\\"a2hja\\\"}\"}","system_info":"{\"device\":\"pcweb\",\"os\":\"pcweb\",\"ver\":\"1.0.0.0\",\"userAgent\":\"Mozilla/5.0 (; Windows 10.0.26100.3194_64 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Electron/14.2.0 Safari/537.36 Node/14.17.0 YoukuDesktop/9.2.60 UOSYouku (2.0.1)-Electron(UTDID ZYmGMAAAACkDAMU8hbiMmYdd;CHANNEL official;ZREAL 0;BTYPE TM2013;BRAND TIMI;BUILDVER 9.2.60.1001)\",\"guid\":\"1590141704165YXe\",\"appPackageKey\":\"com.youku.pcweb\",\"young\":0,\"brand\":\"\",\"network\":\"\",\"ouid\":\"\",\"idfa\":\"\",\"scale\":\"\",\"operator\":\"\",\"resolution\":\"\",\"pid\":\"\",\"childGender\":0,\"zx\":0}"}
|
||||
data=self.getdata(f'{self.h5host}/h5/mtop.youku.columbus.home.query/1.0/',params)
|
||||
okey=list(data['data'].keys())[0]
|
||||
for i in data['data'][okey]['data']['nodes'][0]['nodes'][-1]['nodes'][0]['nodes']:
|
||||
if i.get('nodes') and i['nodes'][0].get('data'):
|
||||
i=i['nodes'][0]['data']
|
||||
if i.get('assignId'):
|
||||
vlist.append({
|
||||
'vod_id': i['assignId'],
|
||||
'vod_name': i.get('title'),
|
||||
'vod_pic': i.get('vImg') or i.get('img'),
|
||||
'vod_year': i.get('mark',{}).get('data',{}).get('text'),
|
||||
'vod_remarks': i.get('summary')
|
||||
})
|
||||
return {'list': vlist}
|
||||
except Exception as e:
|
||||
print(f"处理主页视频数据时出错: {str(e)}")
|
||||
return {'list': []}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
result = {}
|
||||
vlist = []
|
||||
result['page'] = pg
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
pagecount = 9999
|
||||
params = {'type': tid}
|
||||
id = self.typeid[tid]
|
||||
params.update(extend)
|
||||
if pg == '1':
|
||||
id=self.cf(params)
|
||||
data=self.session.get(f'{self.host}/category/data?session={id}¶ms={quote(json.dumps(params))}&pageNo={pg}').json()
|
||||
try:
|
||||
data=data['data']['filterData']
|
||||
for i in data['listData']:
|
||||
if i.get('videoLink') and 's=' in i['videoLink']:
|
||||
vlist.append({
|
||||
'vod_id': i.get('videoLink').split('s=')[-1],
|
||||
'vod_name': i.get('title'),
|
||||
'vod_pic': i.get('img'),
|
||||
'vod_year': i.get('rightTagText'),
|
||||
'vod_remarks': i.get('summary')
|
||||
})
|
||||
self.typeid[tid]=quote(json.dumps(data['session']))
|
||||
except:
|
||||
pagecount=pg
|
||||
result['list'] = vlist
|
||||
result['pagecount'] = pagecount
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
try:
|
||||
data=self.session.get(f'{self.ihost}/v_getvideo_info/?showId={ids[0]}').json()
|
||||
v=data['data']
|
||||
vod = {
|
||||
'type_name': v.get('showVideotype'),
|
||||
'vod_year': v.get('lastUpdate'),
|
||||
'vod_remarks': v.get('rc_title'),
|
||||
'vod_actor': v.get('_personNameStr'),
|
||||
'vod_content': v.get('showdesc'),
|
||||
'vod_play_from': '优酷',
|
||||
'vod_play_url': ''
|
||||
}
|
||||
params={"biz":"new_detail_web2","videoId":v.get('vid'),"scene":"web_page","componentVersion":"3","ip":data.get('ip'),"debug":0,"utdid":"ZYmGMAAAACkDAMU8hbiMmYdd","userId":0,"platform":"pc","nextSession":"","gray":0,"source":"pcNoPrev","showId":ids[0]}
|
||||
sdata,index=self.getinfo(params)
|
||||
pdata=sdata['nodes']
|
||||
if index > len(pdata):
|
||||
batch_size = len(pdata)
|
||||
total_batches = ((index + batch_size - 1) // batch_size) - 1
|
||||
ssj = json.loads(sdata['data']['session'])
|
||||
with ThreadPoolExecutor(max_workers=total_batches) as executor:
|
||||
futures = []
|
||||
for batch in range(total_batches):
|
||||
start = batch_size + 1 + (batch * batch_size)
|
||||
end = start + batch_size - 1
|
||||
next_session = ssj.copy()
|
||||
next_session.update({
|
||||
"itemStartStage": start,
|
||||
"itemEndStage": min(end, index)
|
||||
})
|
||||
current_params = params.copy()
|
||||
current_params['nextSession'] = json.dumps(next_session)
|
||||
futures.append((start, executor.submit(self.getvinfo, current_params)))
|
||||
futures.sort(key=lambda x: x[0])
|
||||
|
||||
for _, future in futures:
|
||||
try:
|
||||
result = future.result()
|
||||
pdata.extend(result['nodes'])
|
||||
except Exception as e:
|
||||
print(f"Error fetching data: {str(e)}")
|
||||
vod['vod_play_url'] = '#'.join([f"{i['data'].get('title')}${i['data']['action'].get('value')}" for i in pdata])
|
||||
return {'list': [vod]}
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return {'list': [{'vod_play_from': '哎呀翻车啦', 'vod_play_url': f'呜呜呜${self.host}'}]}
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
data=self.session.get(f'{self.shost}/api/search?pg={pg}&keyword={key}').json()
|
||||
vlist = []
|
||||
for i in data['pageComponentList']:
|
||||
if i.get('commonData') and (i['commonData'].get('showId') or i['commonData'].get('realShowId')):
|
||||
i=i['commonData']
|
||||
vlist.append({
|
||||
'vod_id': i.get('showId') or i.get('realShowId'),
|
||||
'vod_name': i['titleDTO'].get('displayName'),
|
||||
'vod_pic': i['posterDTO'].get('vThumbUrl'),
|
||||
'vod_year': i.get('feature'),
|
||||
'vod_remarks': i.get('updateNotice')
|
||||
})
|
||||
return {'list': vlist, 'page': pg}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
return {'jx':1,'parse': 1, 'url': f"{self.ihost}/video?vid={id}", 'header': ''}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def cf(self,params,b=False):
|
||||
response = self.session.get(f'{self.host}/category/data?params={quote(json.dumps(params))}&optionRefresh=1&pageNo=1').json()
|
||||
data=response['data']['filterData']
|
||||
session=quote(json.dumps(data['session']))
|
||||
if b:
|
||||
return session,self.get_filter_data(data['filter']['filterData'][1:])
|
||||
return session
|
||||
|
||||
def process_key(self, key):
|
||||
if '_' not in key:
|
||||
return key
|
||||
parts = key.split('_')
|
||||
result = parts[0]
|
||||
for part in parts[1:]:
|
||||
if part:
|
||||
result += part[0].upper() + part[1:]
|
||||
return result
|
||||
|
||||
def get_filter_data(self, data):
|
||||
result = []
|
||||
try:
|
||||
for item in data:
|
||||
if not item.get('subFilter'):
|
||||
continue
|
||||
first_sub = item['subFilter'][0]
|
||||
if not first_sub.get('filterType'):
|
||||
continue
|
||||
filter_item = {
|
||||
'key': self.process_key(first_sub['filterType']),
|
||||
'name': first_sub['title'],
|
||||
'value': []
|
||||
}
|
||||
for sub in item['subFilter']:
|
||||
if 'value' in sub:
|
||||
filter_item['value'].append({
|
||||
'n': sub['title'],
|
||||
'v': sub['value']
|
||||
})
|
||||
if filter_item['value']:
|
||||
result.append(filter_item)
|
||||
|
||||
except Exception as e:
|
||||
print(f"处理筛选数据时出错: {str(e)}")
|
||||
|
||||
return result
|
||||
|
||||
def get_ctoken(self):
|
||||
data=self.session.get(f'{self.h5host}/h5/mtop.ykrec.recommendservice.recommend/1.0/?jsv=2.6.1&appKey=24679788')
|
||||
|
||||
def md5(self,t,text):
|
||||
h = MD5.new()
|
||||
token=self.session.cookies.get('_m_h5_tk').split('_')[0]
|
||||
data=f"{token}&{t}&24679788&{text}"
|
||||
h.update(data.encode('utf-8'))
|
||||
return h.hexdigest()
|
||||
|
||||
def getdata(self, url, params, recursion_count=0, max_recursion=3):
|
||||
data = json.dumps(params)
|
||||
t = int(time.time() * 1000)
|
||||
jsdata = {
|
||||
'appKey': '24679788',
|
||||
't': t,
|
||||
'sign': self.md5(t, data),
|
||||
'data': data
|
||||
}
|
||||
response = self.session.get(url, params=jsdata)
|
||||
if '令牌过期' in response.text:
|
||||
if recursion_count >= max_recursion:
|
||||
raise Exception("达到最大递归次数,无法继续请求")
|
||||
self.get_ctoken()
|
||||
return self.getdata(url, params, recursion_count + 1, max_recursion)
|
||||
else:
|
||||
return response.json()
|
||||
|
||||
def getvinfo(self,params):
|
||||
body = {
|
||||
"ms_codes": "2019030100",
|
||||
"params": json.dumps(params),
|
||||
"system_info": "{\"os\":\"iku\",\"device\":\"iku\",\"ver\":\"9.2.9\",\"appPackageKey\":\"com.youku.iku\",\"appPackageId\":\"pcweb\"}"
|
||||
}
|
||||
data = self.getdata(f'{self.h5host}/h5/mtop.youku.columbus.gateway.new.execute/1.0/', body)
|
||||
okey = list(data['data'].keys())[0]
|
||||
i = data['data'][okey]['data']
|
||||
return i
|
||||
|
||||
def getinfo(self,params):
|
||||
i = self.getvinfo(params)
|
||||
jdata=i['nodes'][0]['nodes'][3]
|
||||
info=i['data']['extra']['episodeTotal']
|
||||
if i['data']['extra']['showCategory'] in ['电影','游戏']:
|
||||
jdata = i['nodes'][0]['nodes'][4]
|
||||
return jdata,info
|
||||
|
|
@ -0,0 +1,790 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# 偷乐短剧爬虫
|
||||
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
import urllib.parse
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
# 导入基础类
|
||||
sys.path.append('../../')
|
||||
try:
|
||||
from base.spider import Spider
|
||||
except ImportError:
|
||||
# 本地调试时的替代实现
|
||||
class Spider:
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
class Spider(Spider):
|
||||
def __init__(self):
|
||||
# 网站主URL
|
||||
self.siteUrl = "https://www.toule.top"
|
||||
|
||||
# 根据网站实际结构,分类链接格式为: /index.php/vod/show/class/分类名/id/1.html
|
||||
# 分类ID映射 - 从网站中提取的分类
|
||||
self.cateManual = {
|
||||
"男频": "/index.php/vod/show/class/%E7%94%B7%E9%A2%91/id/1.html",
|
||||
"女频": "/index.php/vod/show/class/%E5%A5%B3%E9%A2%91/id/1.html",
|
||||
"都市": "/index.php/vod/show/class/%E9%83%BD%E5%B8%82/id/1.html",
|
||||
"赘婿": "/index.php/vod/show/class/%E8%B5%98%E5%A9%BF/id/1.html",
|
||||
"战神": "/index.php/vod/show/class/%E6%88%98%E7%A5%9E/id/1.html",
|
||||
"古代言情": "/index.php/vod/show/class/%E5%8F%A4%E4%BB%A3%E8%A8%80%E6%83%85/id/1.html",
|
||||
"现代言情": "/index.php/vod/show/class/%E7%8E%B0%E4%BB%A3%E8%A8%80%E6%83%85/id/1.html",
|
||||
"历史": "/index.php/vod/show/class/%E5%8E%86%E5%8F%B2/id/1.html",
|
||||
"玄幻": "/index.php/vod/show/class/%E7%8E%84%E5%B9%BB/id/1.html",
|
||||
"搞笑": "/index.php/vod/show/class/%E6%90%9E%E7%AC%91/id/1.html",
|
||||
"甜宠": "/index.php/vod/show/class/%E7%94%9C%E5%AE%A0/id/1.html",
|
||||
"励志": "/index.php/vod/show/class/%E5%8A%B1%E5%BF%97/id/1.html",
|
||||
"逆袭": "/index.php/vod/show/class/%E9%80%86%E8%A2%AD/id/1.html",
|
||||
"穿越": "/index.php/vod/show/class/%E7%A9%BF%E8%B6%8A/id/1.html",
|
||||
"古装": "/index.php/vod/show/class/%E5%8F%A4%E8%A3%85/id/1.html"
|
||||
}
|
||||
|
||||
# 请求头
|
||||
self.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",
|
||||
"Referer": "https://www.toule.top/",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
||||
"Accept-Encoding": "gzip, deflate, br",
|
||||
"Connection": "keep-alive",
|
||||
}
|
||||
|
||||
|
||||
# 缓存
|
||||
self.cache = {}
|
||||
self.cache_timeout = {}
|
||||
|
||||
def getName(self):
|
||||
return "偷乐短剧"
|
||||
|
||||
def init(self, extend=""):
|
||||
# 初始化方法,可以留空
|
||||
return
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
"""判断是否为视频格式"""
|
||||
video_formats = ['.mp4', '.m3u8', '.ts', '.flv', '.avi', '.mkv', '.mov', '.rmvb', '.3gp']
|
||||
for format in video_formats:
|
||||
if format in url.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def manualVideoCheck(self):
|
||||
"""是否需要手动检查视频"""
|
||||
return False
|
||||
|
||||
# 工具方法 - 网络请求
|
||||
def fetch(self, url, headers=None, data=None, method="GET"):
|
||||
"""统一的网络请求方法"""
|
||||
try:
|
||||
if headers is None:
|
||||
headers = self.headers.copy()
|
||||
|
||||
if method.upper() == "GET":
|
||||
response = requests.get(url, headers=headers, params=data, timeout=10,verify=False)
|
||||
else: # POST
|
||||
response = requests.post(url, headers=headers, data=data, timeout=10,verify=False)
|
||||
|
||||
response.raise_for_status()
|
||||
response.encoding = response.apparent_encoding or 'utf-8'
|
||||
return response
|
||||
except Exception as e:
|
||||
self.log(f"请求失败: {url}, 错误: {str(e)}", "ERROR")
|
||||
return None
|
||||
|
||||
# 缓存方法
|
||||
def getCache(self, key, timeout=3600):
|
||||
"""获取缓存数据"""
|
||||
if key in self.cache and key in self.cache_timeout:
|
||||
if time.time() < self.cache_timeout[key]:
|
||||
return self.cache[key]
|
||||
else:
|
||||
del self.cache[key]
|
||||
del self.cache_timeout[key]
|
||||
return None
|
||||
|
||||
def setCache(self, key, value, timeout=3600):
|
||||
"""设置缓存数据"""
|
||||
self.cache[key] = value
|
||||
self.cache_timeout[key] = time.time() + timeout
|
||||
|
||||
# 日志方法
|
||||
def log(self, msg, level='INFO'):
|
||||
"""记录日志"""
|
||||
levels = {
|
||||
'DEBUG': 0,
|
||||
'INFO': 1,
|
||||
'WARNING': 2,
|
||||
'ERROR': 3
|
||||
}
|
||||
|
||||
current_level = 'INFO' # 可以设置为DEBUG以获取更多信息
|
||||
|
||||
if levels.get(level, 4) >= levels.get(current_level, 1):
|
||||
print(f"[{level}] {time.strftime('%Y-%m-%d %H:%M:%S')} - {msg}")
|
||||
|
||||
# 辅助方法 - 从URL中提取视频ID
|
||||
def extractVodId(self, url):
|
||||
"""从URL中提取视频ID"""
|
||||
# 路径格式: /index.php/vod/play/id/9024/sid/1/nid/1.html
|
||||
match = re.search(r'/id/(\d+)/', url)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return ""
|
||||
|
||||
# 辅助方法 - 从网页内容中提取分类
|
||||
def extractCategories(self, text):
|
||||
"""从网页内容中提取分类标签"""
|
||||
cats = []
|
||||
# 匹配标签字符串,例如: "男频,逆袭,亲情,短剧"
|
||||
if "," in text:
|
||||
parts = text.split(",")
|
||||
for part in parts:
|
||||
part = part.strip()
|
||||
if part and part != "短剧":
|
||||
cats.append(part)
|
||||
return cats
|
||||
|
||||
# 主要接口实现
|
||||
def homeContent(self, filter):
|
||||
"""获取首页分类及内容"""
|
||||
result = {}
|
||||
classes = []
|
||||
|
||||
# 从缓存获取
|
||||
cache_key = 'home_classes'
|
||||
cached_classes = self.getCache(cache_key)
|
||||
if cached_classes:
|
||||
classes = cached_classes
|
||||
else:
|
||||
# 使用预定义的分类
|
||||
for k, v in self.cateManual.items():
|
||||
classes.append({
|
||||
'type_id': v, # 使用完整URL路径作为type_id
|
||||
'type_name': k
|
||||
})
|
||||
|
||||
# 保存到缓存
|
||||
self.setCache(cache_key, classes, 24*3600) # 缓存24小时
|
||||
|
||||
result['class'] = classes
|
||||
|
||||
# 获取首页推荐视频
|
||||
videos = self.homeVideoContent().get('list', [])
|
||||
result['list'] = videos
|
||||
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
"""获取首页推荐视频内容"""
|
||||
result = {'list': []}
|
||||
videos = []
|
||||
|
||||
# 从缓存获取
|
||||
cache_key = 'home_videos'
|
||||
cached_videos = self.getCache(cache_key)
|
||||
if cached_videos:
|
||||
return {'list': cached_videos}
|
||||
|
||||
try:
|
||||
response = self.fetch(self.siteUrl)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找最新更新区域
|
||||
latest_section = soup.find('h2', text=lambda t: t and '最新更新' in t)
|
||||
if latest_section:
|
||||
container = latest_section.parent # 获取容器
|
||||
if container:
|
||||
# 查找所有 li.item 元素
|
||||
items = container.find_all('li', class_='item')
|
||||
|
||||
for item in items:
|
||||
try:
|
||||
# 获取链接和标题
|
||||
title_link = item.find('h3')
|
||||
if not title_link:
|
||||
continue
|
||||
|
||||
title = title_link.text.strip()
|
||||
|
||||
# 获取第一个链接作为详情页链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理视频项时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
|
||||
# 保存到缓存
|
||||
self.setCache(cache_key, videos, 3600) # 缓存1小时
|
||||
except Exception as e:
|
||||
self.log(f"获取首页视频内容发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
return result
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
"""获取分类内容"""
|
||||
result = {}
|
||||
videos = []
|
||||
|
||||
# 处理页码
|
||||
if pg is None:
|
||||
pg = 1
|
||||
else:
|
||||
pg = int(pg)
|
||||
|
||||
# 构建分类URL - tid是完整的URL路径
|
||||
if tid.startswith("/"):
|
||||
# 替换页码,URL格式可能像: /index.php/vod/show/class/男频/id/1.html
|
||||
if pg > 1:
|
||||
if "html" in tid:
|
||||
category_url = tid.replace(".html", f"/page/{pg}.html")
|
||||
else:
|
||||
category_url = f"{tid}/page/{pg}.html"
|
||||
else:
|
||||
category_url = tid
|
||||
|
||||
full_url = urllib.parse.urljoin(self.siteUrl, category_url)
|
||||
else:
|
||||
# 如果tid不是URL路径,可能是旧版分类ID,尝试查找对应URL
|
||||
category_url = ""
|
||||
for name, url in self.cateManual.items():
|
||||
if name == tid:
|
||||
category_url = url
|
||||
break
|
||||
|
||||
if not category_url:
|
||||
self.log(f"未找到分类ID对应的URL: {tid}", "ERROR")
|
||||
result['list'] = []
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 1
|
||||
result['limit'] = 0
|
||||
result['total'] = 0
|
||||
return result
|
||||
|
||||
# 处理页码
|
||||
if pg > 1:
|
||||
if "html" in category_url:
|
||||
category_url = category_url.replace(".html", f"/page/{pg}.html")
|
||||
else:
|
||||
category_url = f"{category_url}/page/{pg}.html"
|
||||
|
||||
full_url = urllib.parse.urljoin(self.siteUrl, category_url)
|
||||
|
||||
# 请求分类页
|
||||
try:
|
||||
response = self.fetch(full_url)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找视频项,根据实际HTML结构调整
|
||||
items = soup.find_all('li', class_='item')
|
||||
|
||||
for item in items:
|
||||
try:
|
||||
# 获取链接和标题
|
||||
title_tag = item.find('h3')
|
||||
if not title_tag:
|
||||
continue
|
||||
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 获取链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理分类视频项时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
|
||||
# 查找分页信息
|
||||
# 默认值
|
||||
total = len(videos)
|
||||
pagecount = 1
|
||||
limit = 20
|
||||
|
||||
# 尝试查找分页元素
|
||||
pagination = soup.find('ul', class_='page')
|
||||
if pagination:
|
||||
# 查找最后一页的链接
|
||||
last_page_links = pagination.find_all('a')
|
||||
for link in last_page_links:
|
||||
page_text = link.text.strip()
|
||||
if page_text.isdigit():
|
||||
pagecount = max(pagecount, int(page_text))
|
||||
except Exception as e:
|
||||
self.log(f"获取分类内容发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
result['page'] = pg
|
||||
result['pagecount'] = pagecount
|
||||
result['limit'] = limit
|
||||
result['total'] = total
|
||||
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
"""获取详情内容"""
|
||||
result = {}
|
||||
|
||||
if not ids or len(ids) == 0:
|
||||
return result
|
||||
|
||||
# 视频ID
|
||||
vid = ids[0]
|
||||
|
||||
# 构建播放页URL
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/1.html"
|
||||
|
||||
try:
|
||||
response = self.fetch(play_url)
|
||||
if not response or response.status_code != 200:
|
||||
return result
|
||||
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 提取视频基本信息
|
||||
# 标题
|
||||
title = ""
|
||||
title_tag = soup.find('h1', class_='items-title')
|
||||
if title_tag:
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 图片
|
||||
pic = ""
|
||||
pic_tag = soup.find('img', class_='thumb')
|
||||
if pic_tag:
|
||||
pic = pic_tag.get('src', '')
|
||||
if pic and not pic.startswith('http'):
|
||||
pic = urllib.parse.urljoin(self.siteUrl, pic)
|
||||
|
||||
# 简介
|
||||
desc = ""
|
||||
desc_tag = soup.find('div', class_='text-content')
|
||||
if desc_tag:
|
||||
desc = desc_tag.text.strip()
|
||||
|
||||
# 标签/分类
|
||||
tags = []
|
||||
tags_container = soup.find('span', class_='items-tags')
|
||||
if tags_container:
|
||||
tag_links = tags_container.find_all('a')
|
||||
for tag in tag_links:
|
||||
tag_text = tag.text.strip()
|
||||
if tag_text:
|
||||
tags.append(tag_text)
|
||||
|
||||
# 提取播放列表
|
||||
play_from = "偷乐短剧"
|
||||
play_list = []
|
||||
|
||||
# 查找播放列表区域
|
||||
play_area = soup.find('div', class_='swiper-wrapper')
|
||||
if play_area:
|
||||
# 查找所有剧集链接
|
||||
episode_links = play_area.find_all('a')
|
||||
for ep in episode_links:
|
||||
ep_title = ep.text.strip()
|
||||
ep_url = ep.get('href', '')
|
||||
|
||||
if ep_url:
|
||||
# 直接使用URL作为ID
|
||||
if not ep_url.startswith('http'):
|
||||
ep_url = urllib.parse.urljoin(self.siteUrl, ep_url)
|
||||
|
||||
# 提取集数信息
|
||||
ep_num = ep_title
|
||||
if ep_num.isdigit():
|
||||
ep_num = f"第{ep_num}集"
|
||||
|
||||
play_list.append(f"{ep_num}${ep_url}")
|
||||
|
||||
# 如果没有找到播放列表,查找播放按钮
|
||||
if not play_list:
|
||||
play_btn = soup.find('a', class_='btn-play')
|
||||
if play_btn:
|
||||
play_url = play_btn.get('href', '')
|
||||
if play_url:
|
||||
if not play_url.startswith('http'):
|
||||
play_url = urllib.parse.urljoin(self.siteUrl, play_url)
|
||||
|
||||
play_list.append(f"播放${play_url}")
|
||||
|
||||
# 如果仍然没有找到播放链接,使用播放页URL
|
||||
if not play_list:
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/1.html"
|
||||
play_list.append(f"播放${play_url}")
|
||||
|
||||
# 提取更多信息(导演、演员等)
|
||||
director = ""
|
||||
actor = ""
|
||||
year = ""
|
||||
area = ""
|
||||
remarks = ""
|
||||
|
||||
# 查找备注信息
|
||||
meta_items = soup.find_all('div', class_='meta-item')
|
||||
for item in meta_items:
|
||||
item_title = item.find('span', class_='item-title')
|
||||
item_content = item.find('span', class_='item-content')
|
||||
|
||||
if item_title and item_content:
|
||||
title_text = item_title.text.strip()
|
||||
content_text = item_content.text.strip()
|
||||
|
||||
if "导演" in title_text:
|
||||
director = content_text
|
||||
elif "主演" in title_text:
|
||||
actor = content_text
|
||||
elif "年份" in title_text:
|
||||
year = content_text
|
||||
elif "地区" in title_text:
|
||||
area = content_text
|
||||
elif "简介" in title_text:
|
||||
if not desc:
|
||||
desc = content_text
|
||||
elif "状态" in title_text:
|
||||
remarks = content_text
|
||||
|
||||
# 如果没有从meta-item中获取到remarks
|
||||
if not remarks:
|
||||
remarks_tag = soup.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 构建标准数据结构
|
||||
vod = {
|
||||
"vod_id": vid,
|
||||
"vod_name": title,
|
||||
"vod_pic": pic,
|
||||
"vod_year": year,
|
||||
"vod_area": area,
|
||||
"vod_remarks": remarks,
|
||||
"vod_actor": actor,
|
||||
"vod_director": director,
|
||||
"vod_content": desc,
|
||||
"type_name": ",".join(tags),
|
||||
"vod_play_from": play_from,
|
||||
"vod_play_url": "#".join(play_list)
|
||||
}
|
||||
|
||||
result = {
|
||||
'list': [vod]
|
||||
}
|
||||
except Exception as e:
|
||||
self.log(f"获取详情内容时出错: {str(e)}", "ERROR")
|
||||
|
||||
return result
|
||||
|
||||
def searchContent(self, key, quick, pg=1):
|
||||
"""搜索功能"""
|
||||
result = {}
|
||||
videos = []
|
||||
|
||||
# 构建搜索URL和参数
|
||||
search_url = f"{self.siteUrl}/index.php/vod/search.html"
|
||||
params = {"wd": key}
|
||||
|
||||
try:
|
||||
response = self.fetch(search_url, data=params)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找搜索结果项
|
||||
search_items = soup.find_all('li', class_='item')
|
||||
|
||||
for item in search_items:
|
||||
try:
|
||||
# 获取标题
|
||||
title_tag = item.find('h3')
|
||||
if not title_tag:
|
||||
continue
|
||||
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 获取链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取视频ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理搜索结果时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
except Exception as e:
|
||||
self.log(f"搜索功能发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
return result
|
||||
|
||||
def searchContentPage(self, key, quick, pg=1):
|
||||
return self.searchContent(key, quick, pg)
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
"""获取播放内容"""
|
||||
result = {}
|
||||
|
||||
try:
|
||||
# 判断是否已经是视频URL
|
||||
if self.isVideoFormat(id):
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
|
||||
# 判断是否是完整的页面URL
|
||||
if id.startswith(('http://', 'https://')):
|
||||
play_url = id
|
||||
# 尝试作为相对路径处理
|
||||
elif id.startswith('/'):
|
||||
play_url = urllib.parse.urljoin(self.siteUrl, id)
|
||||
# 假设是视频ID,构建播放页面URL
|
||||
else:
|
||||
# 检查是否是"视频ID_集数"格式
|
||||
parts = id.split('_')
|
||||
if len(parts) > 1 and parts[0].isdigit():
|
||||
vid = parts[0]
|
||||
nid = parts[1]
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/{nid}.html"
|
||||
else:
|
||||
# 直接当作视频ID处理
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{id}/sid/1/nid/1.html"
|
||||
|
||||
# 访问播放页获取真实播放地址
|
||||
try:
|
||||
self.log(f"正在解析播放页面: {play_url}")
|
||||
response = self.fetch(play_url)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
|
||||
# 查找player_aaaa变量
|
||||
player_match = re.search(r'var\s+player_aaaa\s*=\s*({.*?});', html, re.DOTALL)
|
||||
if player_match:
|
||||
try:
|
||||
player_data = json.loads(player_match.group(1))
|
||||
if 'url' in player_data:
|
||||
video_url = player_data['url']
|
||||
if not video_url.startswith('http'):
|
||||
video_url = urllib.parse.urljoin(self.siteUrl, video_url)
|
||||
|
||||
self.log(f"从player_aaaa获取到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
except json.JSONDecodeError as e:
|
||||
self.log(f"解析player_aaaa JSON出错: {str(e)}", "ERROR")
|
||||
|
||||
# 如果player_aaaa解析失败,尝试其他方式
|
||||
# 1. 查找video标签
|
||||
video_match = re.search(r'<video[^>]*src=["\'](.*?)["\']', html)
|
||||
if video_match:
|
||||
video_url = video_match.group(1)
|
||||
if not video_url.startswith('http'):
|
||||
video_url = urllib.parse.urljoin(self.siteUrl, video_url)
|
||||
|
||||
self.log(f"从video标签找到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
|
||||
# 2. 查找iframe
|
||||
iframe_match = re.search(r'<iframe[^>]*src=["\'](.*?)["\']', html)
|
||||
if iframe_match:
|
||||
iframe_url = iframe_match.group(1)
|
||||
if not iframe_url.startswith('http'):
|
||||
iframe_url = urllib.parse.urljoin(self.siteUrl, iframe_url)
|
||||
|
||||
self.log(f"找到iframe,正在解析: {iframe_url}")
|
||||
# 访问iframe内容
|
||||
iframe_response = self.fetch(iframe_url)
|
||||
if iframe_response and iframe_response.status_code == 200:
|
||||
iframe_html = iframe_response.text
|
||||
|
||||
# 在iframe内容中查找视频地址
|
||||
iframe_video_match = re.search(r'(https?://[^\'"]+\.(mp4|m3u8|ts))', iframe_html)
|
||||
if iframe_video_match:
|
||||
video_url = iframe_video_match.group(1)
|
||||
|
||||
self.log(f"从iframe中找到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps({
|
||||
"User-Agent": self.headers["User-Agent"],
|
||||
"Referer": iframe_url
|
||||
})
|
||||
return result
|
||||
|
||||
# 3. 查找任何可能的视频URL
|
||||
url_match = re.search(r'(https?://[^\'"]+\.(mp4|m3u8|ts))', html)
|
||||
if url_match:
|
||||
video_url = url_match.group(1)
|
||||
|
||||
self.log(f"找到可能的视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
except Exception as e:
|
||||
self.log(f"解析播放地址时出错: {str(e)}", "ERROR")
|
||||
|
||||
# 如果所有方式都失败,返回外部解析标志
|
||||
self.log("未找到直接可用的视频地址,需要外部解析", "WARNING")
|
||||
result["parse"] = 1 # 表示需要外部解析
|
||||
result["url"] = play_url # 返回播放页面URL
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
|
||||
except Exception as e:
|
||||
self.log(f"获取播放内容时出错: {str(e)}", "ERROR")
|
||||
|
||||
return result
|
||||
|
||||
def localProxy(self, param):
|
||||
"""本地代理"""
|
||||
return [404, "text/plain", {}, "Not Found"]
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,581 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import requests
|
||||
import re
|
||||
import json
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
sys.path.append('../../')
|
||||
try:
|
||||
from base.spider import Spider
|
||||
except ImportError:
|
||||
# 定义一个基础接口类,用于本地测试
|
||||
class Spider:
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
class Spider(Spider):
|
||||
def __init__(self):
|
||||
self.siteUrl = "https://www.kuaikaw.cn"
|
||||
self.nextData = None # 缓存NEXT_DATA数据
|
||||
self.cateManual = {
|
||||
"甜宠": "462",
|
||||
"古装仙侠": "1102",
|
||||
"现代言情": "1145",
|
||||
"青春": "1170",
|
||||
"豪门恩怨": "585",
|
||||
"逆袭": "417-464",
|
||||
"重生": "439-465",
|
||||
"系统": "1159",
|
||||
"总裁": "1147",
|
||||
"职场商战": "943"
|
||||
}
|
||||
|
||||
def getName(self):
|
||||
# 返回爬虫名称
|
||||
return "河马短剧"
|
||||
|
||||
def init(self, extend=""):
|
||||
return
|
||||
|
||||
def fetch(self, url, headers=None):
|
||||
"""统一的网络请求接口"""
|
||||
if headers is None:
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
|
||||
"Referer": self.siteUrl,
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=headers, timeout=10, allow_redirects=True)
|
||||
response.raise_for_status()
|
||||
return response
|
||||
except Exception as e:
|
||||
print(f"请求异常: {url}, 错误: {str(e)}")
|
||||
return None
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
# 检查是否为视频格式
|
||||
video_formats = ['.mp4', '.mkv', '.avi', '.wmv', '.m3u8', '.flv', '.rmvb']
|
||||
for format in video_formats:
|
||||
if format in url.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def manualVideoCheck(self):
|
||||
# 不需要手动检查
|
||||
return False
|
||||
|
||||
def homeContent(self, filter):
|
||||
"""获取首页分类及筛选"""
|
||||
result = {}
|
||||
# 分类列表,使用已初始化的cateManual
|
||||
classes = []
|
||||
for k in self.cateManual:
|
||||
classes.append({
|
||||
'type_name': k,
|
||||
'type_id': self.cateManual[k]
|
||||
})
|
||||
result['class'] = classes
|
||||
# 获取首页推荐视频
|
||||
try:
|
||||
result['list'] = self.homeVideoContent()['list']
|
||||
except:
|
||||
result['list'] = []
|
||||
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
"""获取首页推荐视频内容"""
|
||||
videos = []
|
||||
try:
|
||||
response = self.fetch(self.siteUrl)
|
||||
html_content = response.text
|
||||
# 提取NEXT_DATA JSON数据
|
||||
next_data_pattern = r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>'
|
||||
next_data_match = re.search(next_data_pattern, html_content, re.DOTALL)
|
||||
if next_data_match:
|
||||
next_data_json = json.loads(next_data_match.group(1))
|
||||
page_props = next_data_json.get("props", {}).get("pageProps", {})
|
||||
# 获取轮播图数据 - 这些通常是推荐内容
|
||||
if "bannerList" in page_props and isinstance(page_props["bannerList"], list):
|
||||
banner_list = page_props["bannerList"]
|
||||
for banner in banner_list:
|
||||
book_id = banner.get("bookId", "")
|
||||
book_name = banner.get("bookName", "")
|
||||
cover_url = banner.get("coverWap", banner.get("wapUrl", ""))
|
||||
# 获取状态和章节数
|
||||
status = banner.get("statusDesc", "")
|
||||
total_chapters = banner.get("totalChapterNum", "")
|
||||
if book_id and book_name:
|
||||
videos.append({
|
||||
"vod_id": f"/drama/{book_id}",
|
||||
"vod_name": book_name,
|
||||
"vod_pic": cover_url,
|
||||
"vod_remarks": f"{status} {total_chapters}集" if total_chapters else status
|
||||
})
|
||||
|
||||
# SEO分类下的推荐
|
||||
if "seoColumnVos" in page_props and isinstance(page_props["seoColumnVos"], list):
|
||||
for column in page_props["seoColumnVos"]:
|
||||
book_infos = column.get("bookInfos", [])
|
||||
for book in book_infos:
|
||||
book_id = book.get("bookId", "")
|
||||
book_name = book.get("bookName", "")
|
||||
cover_url = book.get("coverWap", "")
|
||||
status = book.get("statusDesc", "")
|
||||
total_chapters = book.get("totalChapterNum", "")
|
||||
|
||||
if book_id and book_name:
|
||||
videos.append({
|
||||
"vod_id": f"/drama/{book_id}",
|
||||
"vod_name": book_name,
|
||||
"vod_pic": cover_url,
|
||||
"vod_remarks": f"{status} {total_chapters}集" if total_chapters else status
|
||||
})
|
||||
|
||||
# # 去重
|
||||
# seen = set()
|
||||
# unique_videos = []
|
||||
# for video in videos:
|
||||
# if video["vod_id"] not in seen:
|
||||
# seen.add(video["vod_id"])
|
||||
# unique_videos.append(video)
|
||||
# videos = unique_videos
|
||||
|
||||
except Exception as e:
|
||||
print(f"获取首页推荐内容出错: {e}")
|
||||
|
||||
result = {
|
||||
"list": videos
|
||||
}
|
||||
return result
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
"""获取分类内容"""
|
||||
result = {}
|
||||
videos = []
|
||||
url = f"{self.siteUrl}/browse/{tid}/{pg}"
|
||||
response = self.fetch(url)
|
||||
html_content = response.text
|
||||
# 提取NEXT_DATA JSON数据
|
||||
next_data_pattern = r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>'
|
||||
next_data_match = re.search(next_data_pattern, html_content, re.DOTALL)
|
||||
if next_data_match:
|
||||
next_data_json = json.loads(next_data_match.group(1))
|
||||
page_props = next_data_json.get("props", {}).get("pageProps", {})
|
||||
# 获取总页数和当前页
|
||||
current_page = page_props.get("page", 1)
|
||||
total_pages = page_props.get("pages", 1)
|
||||
# 获取书籍列表
|
||||
book_list = page_props.get("bookList", [])
|
||||
# 转换为通用格式
|
||||
for book in book_list:
|
||||
book_id = book.get("bookId", "")
|
||||
book_name = book.get("bookName", "")
|
||||
cover_url = book.get("coverWap", "")
|
||||
status_desc = book.get("statusDesc", "")
|
||||
total_chapters = book.get("totalChapterNum", "")
|
||||
if book_id and book_name:
|
||||
videos.append({
|
||||
"vod_id": f"/drama/{book_id}",
|
||||
"vod_name": book_name,
|
||||
"vod_pic": cover_url,
|
||||
"vod_remarks": f"{status_desc} {total_chapters}集" if total_chapters else status_desc
|
||||
})
|
||||
# 构建返回结果
|
||||
result = {
|
||||
"list": videos,
|
||||
"page": int(current_page),
|
||||
"pagecount": total_pages,
|
||||
"limit": len(videos),
|
||||
"total": total_pages * len(videos) if videos else 0
|
||||
}
|
||||
return result
|
||||
|
||||
def switch(self, key, pg):
|
||||
# 搜索功能
|
||||
search_results = []
|
||||
# 获取第一页结果,并检查总页数
|
||||
url = f"{self.siteUrl}/search?searchValue={key}&page={pg}"
|
||||
response = self.fetch(url)
|
||||
html_content = response.text
|
||||
# 提取NEXT_DATA JSON数据
|
||||
next_data_pattern = r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>'
|
||||
next_data_match = re.search(next_data_pattern, html_content, re.DOTALL)
|
||||
if next_data_match:
|
||||
next_data_json = json.loads(next_data_match.group(1))
|
||||
page_props = next_data_json.get("props", {}).get("pageProps", {})
|
||||
# 获取总页数
|
||||
total_pages = page_props.get("pages", 1)
|
||||
# 处理所有页的数据
|
||||
all_book_list = []
|
||||
# 添加第一页的书籍列表
|
||||
book_list = page_props.get("bookList", [])
|
||||
all_book_list.extend(book_list)
|
||||
# 如果有多页,获取其他页的数据
|
||||
if total_pages > 1 : # quick模式只获取第一页
|
||||
for page in range(2, total_pages + 1):
|
||||
next_page_url = f"{self.siteUrl}/search?searchValue={key}&page={page}"
|
||||
next_page_response = self.fetch(next_page_url)
|
||||
next_page_html = next_page_response.text
|
||||
next_page_match = re.search(next_data_pattern, next_page_html, re.DOTALL)
|
||||
if next_page_match:
|
||||
next_page_json = json.loads(next_page_match.group(1))
|
||||
next_page_props = next_page_json.get("props", {}).get("pageProps", {})
|
||||
next_page_books = next_page_props.get("bookList", [])
|
||||
all_book_list.extend(next_page_books)
|
||||
# 转换为统一的搜索结果格式
|
||||
for book in all_book_list:
|
||||
book_id = book.get("bookId", "")
|
||||
book_name = book.get("bookName", "")
|
||||
cover_url = book.get("coverWap", "")
|
||||
total_chapters = book.get("totalChapterNum", "0")
|
||||
status_desc = book.get("statusDesc", "")
|
||||
# 构建视频项
|
||||
vod = {
|
||||
"vod_id": f"/drama/{book_id}",
|
||||
"vod_name": book_name,
|
||||
"vod_pic": cover_url,
|
||||
"vod_remarks": f"{status_desc} {total_chapters}集"
|
||||
}
|
||||
search_results.append(vod)
|
||||
result = {
|
||||
"list": search_results,
|
||||
"page": pg
|
||||
}
|
||||
return result
|
||||
|
||||
def searchContent(self, key, quick, pg=1):
|
||||
result = self.switch(key, pg=pg)
|
||||
result['page'] = pg
|
||||
return result
|
||||
|
||||
def searchContentPage(self, key, quick, pg=1):
|
||||
return self.searchContent(key, quick, pg)
|
||||
|
||||
def detailContent(self, ids):
|
||||
# 获取剧集信息
|
||||
vod_id = ids[0]
|
||||
episode_id = None
|
||||
chapter_id = None
|
||||
|
||||
if not vod_id.startswith('/drama/'):
|
||||
if vod_id.startswith('/episode/'):
|
||||
episode_info = vod_id.replace('/episode/', '').split('/')
|
||||
if len(episode_info) >= 2:
|
||||
episode_id = episode_info[0]
|
||||
chapter_id = episode_info[1]
|
||||
vod_id = f'/drama/{episode_id}'
|
||||
else:
|
||||
vod_id = '/drama/' + vod_id
|
||||
|
||||
drama_url = self.siteUrl + vod_id
|
||||
print(f"请求URL: {drama_url}")
|
||||
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
|
||||
"Referer": self.siteUrl,
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
|
||||
}
|
||||
|
||||
rsp = self.fetch(drama_url, headers=headers)
|
||||
if not rsp or rsp.status_code != 200:
|
||||
print(f"请求失败,状态码: {getattr(rsp, 'status_code', 'N/A')}")
|
||||
return {}
|
||||
|
||||
html = rsp.text
|
||||
next_data_match = re.search(r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>', html, re.DOTALL)
|
||||
|
||||
if not next_data_match:
|
||||
print("未找到NEXT_DATA内容")
|
||||
return {}
|
||||
|
||||
try:
|
||||
next_data = json.loads(next_data_match.group(1))
|
||||
page_props = next_data.get("props", {}).get("pageProps", {})
|
||||
print(f"找到页面属性,包含 {len(page_props.keys())} 个键")
|
||||
|
||||
book_info = page_props.get("bookInfoVo", {})
|
||||
chapter_list = page_props.get("chapterList", [])
|
||||
|
||||
title = book_info.get("title", "")
|
||||
sub_title = f"{book_info.get('totalChapterNum', '')}集"
|
||||
|
||||
categories = []
|
||||
for category in book_info.get("categoryList", []):
|
||||
categories.append(category.get("name", ""))
|
||||
|
||||
vod_content = book_info.get("introduction", "")
|
||||
|
||||
vod = {
|
||||
"vod_id": vod_id,
|
||||
"vod_name": title,
|
||||
"vod_pic": book_info.get("coverWap", ""),
|
||||
"type_name": ",".join(categories),
|
||||
"vod_year": "",
|
||||
"vod_area": book_info.get("countryName", ""),
|
||||
"vod_remarks": sub_title,
|
||||
"vod_actor": ", ".join([p.get("name", "") for p in book_info.get("performerList", [])]),
|
||||
"vod_director": "",
|
||||
"vod_content": vod_content
|
||||
}
|
||||
|
||||
# 处理播放列表
|
||||
play_url_list = []
|
||||
episodes = []
|
||||
|
||||
if chapter_list:
|
||||
print(f"找到 {len(chapter_list)} 个章节")
|
||||
|
||||
# 先检查是否有可以直接使用的MP4链接作为模板
|
||||
mp4_template = None
|
||||
first_mp4_chapter_id = None
|
||||
|
||||
# 先搜索第一个章节的MP4链接
|
||||
# 为提高成功率,尝试直接请求第一个章节的播放页
|
||||
if chapter_list and len(chapter_list) > 0:
|
||||
first_chapter = chapter_list[0]
|
||||
first_chapter_id = first_chapter.get("chapterId", "")
|
||||
drama_id_clean = vod_id.replace('/drama/', '')
|
||||
|
||||
if first_chapter_id and drama_id_clean:
|
||||
first_episode_url = f"{self.siteUrl}/episode/{drama_id_clean}/{first_chapter_id}"
|
||||
print(f"请求第一集播放页: {first_episode_url}")
|
||||
|
||||
first_rsp = self.fetch(first_episode_url, headers=headers)
|
||||
if first_rsp and first_rsp.status_code == 200:
|
||||
first_html = first_rsp.text
|
||||
# 直接从HTML提取MP4链接
|
||||
mp4_pattern = r'(https?://[^"\']+\.mp4)'
|
||||
mp4_matches = re.findall(mp4_pattern, first_html)
|
||||
if mp4_matches:
|
||||
mp4_template = mp4_matches[0]
|
||||
first_mp4_chapter_id = first_chapter_id
|
||||
print(f"找到MP4链接模板: {mp4_template}")
|
||||
print(f"模板对应的章节ID: {first_mp4_chapter_id}")
|
||||
|
||||
# 如果未找到模板,再检查章节对象中是否有MP4链接
|
||||
if not mp4_template:
|
||||
for chapter in chapter_list[:5]: # 只检查前5个章节以提高效率
|
||||
if "chapterVideoVo" in chapter and chapter["chapterVideoVo"]:
|
||||
chapter_video = chapter["chapterVideoVo"]
|
||||
mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "")
|
||||
if mp4_url and ".mp4" in mp4_url:
|
||||
mp4_template = mp4_url
|
||||
first_mp4_chapter_id = chapter.get("chapterId", "")
|
||||
print(f"从chapterVideoVo找到MP4链接模板: {mp4_template}")
|
||||
print(f"模板对应的章节ID: {first_mp4_chapter_id}")
|
||||
break
|
||||
|
||||
# 遍历所有章节处理播放信息
|
||||
for chapter in chapter_list:
|
||||
chapter_id = chapter.get("chapterId", "")
|
||||
chapter_name = chapter.get("chapterName", "")
|
||||
|
||||
# 1. 如果章节自身有MP4链接,直接使用
|
||||
if "chapterVideoVo" in chapter and chapter["chapterVideoVo"]:
|
||||
chapter_video = chapter["chapterVideoVo"]
|
||||
mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "")
|
||||
if mp4_url and ".mp4" in mp4_url:
|
||||
episodes.append(f"{chapter_name}${mp4_url}")
|
||||
continue
|
||||
|
||||
# 2. 如果有MP4模板,尝试替换章节ID构建MP4链接
|
||||
if mp4_template and first_mp4_chapter_id and chapter_id:
|
||||
# 替换模板中的章节ID部分
|
||||
if first_mp4_chapter_id in mp4_template:
|
||||
new_mp4_url = mp4_template.replace(first_mp4_chapter_id, chapter_id)
|
||||
episodes.append(f"{chapter_name}${new_mp4_url}")
|
||||
continue
|
||||
|
||||
# 3. 如果上述方法都不可行,回退到使用chapter_id构建中间URL
|
||||
if chapter_id and chapter_name:
|
||||
url = f"{vod_id}${chapter_id}${chapter_name}"
|
||||
episodes.append(f"{chapter_name}${url}")
|
||||
|
||||
if not episodes and vod_id:
|
||||
# 尝试构造默认的集数
|
||||
total_chapters = int(book_info.get("totalChapterNum", "0"))
|
||||
if total_chapters > 0:
|
||||
print(f"尝试构造 {total_chapters} 个默认集数")
|
||||
|
||||
# 如果知道章节ID的模式,可以构造
|
||||
if chapter_id and episode_id:
|
||||
for i in range(1, total_chapters + 1):
|
||||
chapter_name = f"第{i}集"
|
||||
url = f"{vod_id}${chapter_id}${chapter_name}"
|
||||
episodes.append(f"{chapter_name}${url}")
|
||||
else:
|
||||
# 使用普通的构造方式
|
||||
for i in range(1, total_chapters + 1):
|
||||
chapter_name = f"第{i}集"
|
||||
url = f"{vod_id}${chapter_name}"
|
||||
episodes.append(f"{chapter_name}${url}")
|
||||
|
||||
if episodes:
|
||||
play_url_list.append("#".join(episodes))
|
||||
vod['vod_play_from'] = '河马剧场'
|
||||
vod['vod_play_url'] = '$$$'.join(play_url_list)
|
||||
|
||||
result = {
|
||||
'list': [vod]
|
||||
}
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"解析详情页失败: {str(e)}")
|
||||
print(traceback.format_exc())
|
||||
return {}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
result = {}
|
||||
print(f"调用playerContent: flag={flag}, id={id}")
|
||||
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
|
||||
"Referer": self.siteUrl,
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
|
||||
}
|
||||
|
||||
# 解析id参数
|
||||
parts = id.split('$')
|
||||
drama_id = None
|
||||
chapter_id = None
|
||||
|
||||
if len(parts) >= 2:
|
||||
drama_id = parts[0]
|
||||
chapter_id = parts[1]
|
||||
chapter_name = parts[2] if len(parts) > 2 else "第一集"
|
||||
print(f"解析参数: drama_id={drama_id}, chapter_id={chapter_id}")
|
||||
else:
|
||||
# 处理旧数据格式
|
||||
print(f"使用原始URL格式: {id}")
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
# 直接检查chapter_id是否包含http(可能已经是视频链接)
|
||||
if 'http' in chapter_id and '.mp4' in chapter_id:
|
||||
print(f"已经是MP4链接: {chapter_id}")
|
||||
result["parse"] = 0
|
||||
result["url"] = chapter_id
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
# 构建episode页面URL
|
||||
drama_id_clean = drama_id.replace('/drama/', '')
|
||||
episode_url = f"{self.siteUrl}/episode/{drama_id_clean}/{chapter_id}"
|
||||
print(f"请求episode页面: {episode_url}")
|
||||
|
||||
try:
|
||||
rsp = self.fetch(episode_url, headers=headers)
|
||||
if not rsp or rsp.status_code != 200:
|
||||
print(f"请求失败,状态码: {getattr(rsp, 'status_code', 'N/A')}")
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
html = rsp.text
|
||||
print(f"获取页面大小: {len(html)} 字节")
|
||||
|
||||
# 尝试从NEXT_DATA提取视频链接
|
||||
mp4_url = None
|
||||
|
||||
# 方法1: 从NEXT_DATA提取
|
||||
next_data_match = re.search(r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>', html, re.DOTALL)
|
||||
if next_data_match:
|
||||
try:
|
||||
print("找到NEXT_DATA")
|
||||
next_data = json.loads(next_data_match.group(1))
|
||||
page_props = next_data.get("props", {}).get("pageProps", {})
|
||||
|
||||
# 从chapterList中查找当前章节
|
||||
chapter_list = page_props.get("chapterList", [])
|
||||
print(f"找到章节列表,长度: {len(chapter_list)}")
|
||||
|
||||
for chapter in chapter_list:
|
||||
if chapter.get("chapterId") == chapter_id:
|
||||
print(f"找到匹配的章节: {chapter.get('chapterName')}")
|
||||
chapter_video = chapter.get("chapterVideoVo", {})
|
||||
mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "")
|
||||
if mp4_url:
|
||||
print(f"从chapterList找到MP4链接: {mp4_url}")
|
||||
break
|
||||
|
||||
# 如果未找到,尝试从当前章节获取
|
||||
if not mp4_url:
|
||||
current_chapter = page_props.get("chapterInfo", {})
|
||||
if current_chapter:
|
||||
print("找到当前章节信息")
|
||||
chapter_video = current_chapter.get("chapterVideoVo", {})
|
||||
mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "")
|
||||
if mp4_url:
|
||||
print(f"从chapterInfo找到MP4链接: {mp4_url}")
|
||||
except Exception as e:
|
||||
print(f"解析NEXT_DATA失败: {str(e)}")
|
||||
print(traceback.format_exc())
|
||||
|
||||
# 方法2: 直接从HTML中提取MP4链接
|
||||
if not mp4_url:
|
||||
mp4_pattern = r'(https?://[^"\']+\.mp4)'
|
||||
mp4_matches = re.findall(mp4_pattern, html)
|
||||
if mp4_matches:
|
||||
# 查找含有chapter_id的链接
|
||||
matched_mp4 = False
|
||||
for url in mp4_matches:
|
||||
if chapter_id in url:
|
||||
mp4_url = url
|
||||
matched_mp4 = True
|
||||
print(f"从HTML直接提取章节MP4链接: {mp4_url}")
|
||||
break
|
||||
|
||||
# 如果没找到包含chapter_id的链接,使用第一个
|
||||
if not matched_mp4 and mp4_matches:
|
||||
mp4_url = mp4_matches[0]
|
||||
print(f"从HTML直接提取MP4链接: {mp4_url}")
|
||||
|
||||
if mp4_url and ".mp4" in mp4_url:
|
||||
print(f"最终找到的MP4链接: {mp4_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = mp4_url
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
else:
|
||||
print(f"未找到有效的MP4链接,尝试再次解析页面内容")
|
||||
# 再尝试一次从HTML中广泛搜索所有可能的MP4链接
|
||||
all_mp4_pattern = r'(https?://[^"\']+\.mp4)'
|
||||
all_mp4_matches = re.findall(all_mp4_pattern, html)
|
||||
if all_mp4_matches:
|
||||
mp4_url = all_mp4_matches[0]
|
||||
print(f"从HTML广泛搜索找到MP4链接: {mp4_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = mp4_url
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
print(f"未找到视频链接,返回原episode URL: {episode_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = episode_url
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"请求或解析失败: {str(e)}")
|
||||
print(traceback.format_exc())
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
def localProxy(self, param):
|
||||
# 本地代理处理,此处简单返回传入的参数
|
||||
return [200, "video/MP2T", {}, param]
|
||||
|
||||
def destroy(self):
|
||||
# 资源回收
|
||||
pass
|
|
@ -0,0 +1,248 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import random
|
||||
import sys
|
||||
from base64 import b64encode, b64decode
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from urllib.parse import urlencode
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
self.did = self.random_str(32)
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
rhost = 'https://www.iqiyi.com'
|
||||
|
||||
hhost='https://mesh.if.iqiyi.com'
|
||||
|
||||
dhost='https://miniapp.iqiyi.com'
|
||||
|
||||
headers = {
|
||||
'Origin': rhost,
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
|
||||
'Referer': f'{rhost}/',
|
||||
}
|
||||
|
||||
def homeContent(self, filter):
|
||||
result = {}
|
||||
cateManual = {
|
||||
"全部": "1009",
|
||||
"电影": "1",
|
||||
"剧集": "2",
|
||||
"综艺": "6",
|
||||
"动漫": "4",
|
||||
"儿童": "15",
|
||||
"微剧": "35",
|
||||
"纪录片": "3"
|
||||
}
|
||||
classes = []
|
||||
filters = {}
|
||||
for k in cateManual:
|
||||
classes.append({
|
||||
'type_name': k,
|
||||
'type_id': cateManual[k]
|
||||
})
|
||||
with ThreadPoolExecutor(max_workers=len(classes)) as executor:
|
||||
results = executor.map(self.getf, classes)
|
||||
for id, ft in results:
|
||||
if len(ft):filters[id] = ft
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
data=self.fetch(f'{self.hhost}/portal/lw/v5/channel/recommend?v=13.014.21150', headers=self.headers).json()
|
||||
vlist = []
|
||||
for i in data['items'][1:]:
|
||||
for j in i['video'][0]['data']:
|
||||
id = j.get('firstId')
|
||||
pic=j.get('prevue',{}).get('image_url') or j.get('album_image_url_hover')
|
||||
if id and pic:
|
||||
pu=j.get('prevue',{}).get('page_url') or j.get('page_url').split('?')[0]
|
||||
id = f'{id}@{self.e64(pu)}'
|
||||
vlist.append({
|
||||
'vod_id': id,
|
||||
'vod_name': j.get('display_name'),
|
||||
'vod_pic': pic,
|
||||
'vod_year': j.get('sns_score'),
|
||||
'vod_remarks': j.get('dq_updatestatus') or j.get('rank_prefix')
|
||||
})
|
||||
return {'list':vlist}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
if pg == "1":
|
||||
self.sid = ''
|
||||
new_data = {'mode':'24'}
|
||||
for key, value in extend.items():
|
||||
if value:
|
||||
key_value_pairs = self.d64(value).split(',')
|
||||
for pair in key_value_pairs:
|
||||
k, v = pair.split('=')
|
||||
if k in new_data:
|
||||
new_data[k] += "," + v
|
||||
else:
|
||||
new_data[k] = v
|
||||
path=f'/portal/lw/videolib/data?uid=&passport_id=&ret_num=60&version=13.014.21150&device_id={self.did}&channel_id={tid}&page_id={pg}&session={self.sid}&os=&conduit_id=&vip=0&auth&recent_selected_tag=&ad=%5B%7B%22lm%22:%225%22,%22ai%22:%225%22,%22fp%22:%226%22,%22sei%22:%22Sa867aa9d326e2bd8654d8c2a8636055e%22,%22position%22:%22library%22%7D%5D&adExt=%7B%22r%22:%221.2.1-ares6-pure%22%7D&dfp=a12f96215b2f7842a98c082799ca0c3d9236be00946701b106829754d8ece3aaf8&filter={urlencode(new_data)}'
|
||||
data=self.fetch(f'{self.hhost}{path}', headers=self.headers).json()
|
||||
self.sid = data['session']
|
||||
videos = []
|
||||
for i in data['data']:
|
||||
id = i.get('firstId') or i.get('tv_id')
|
||||
if not id:
|
||||
id=i.get('play_url').split(';')[0].split('=')[-1]
|
||||
if id and not i.get('h'):
|
||||
id=f'{id}@{self.e64(i.get("page_url"))}'
|
||||
videos.append({
|
||||
'vod_id': id,
|
||||
'vod_name': i.get('display_name'),
|
||||
'vod_pic': i.get('album_image_url_hover'),
|
||||
'vod_year': i.get('sns_score'),
|
||||
'vod_remarks': i.get('dq_updatestatus') or i.get('pay_mark')
|
||||
})
|
||||
result = {}
|
||||
result['list'] = videos
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 9999
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
ids = ids[0].split('@')
|
||||
ids[-1] = self.d64(ids[-1])
|
||||
data = self.fetch(f'{self.dhost}/h5/mina/baidu/play/body/v1/{ids[0]}/', headers=self.headers).json()
|
||||
v=data['data']['playInfo']
|
||||
vod = {
|
||||
'vod_name': v.get('albumName'),
|
||||
'type_name': v.get('tags'),
|
||||
'vod_year': v.get('albumYear'),
|
||||
'vod_remarks': v.get('updateStrategy'),
|
||||
'vod_actor': v.get('mainActors'),
|
||||
'vod_director': v.get('directors'),
|
||||
'vod_content': v.get('albumDesc'),
|
||||
'vod_play_from': '爱奇艺',
|
||||
'vod_play_url': ''
|
||||
}
|
||||
if data.get('data') and data['data'].get('videoList') and data['data']['videoList'].get('videos'):
|
||||
purl=[f'{i["shortTitle"]}${i["pageUrl"]}' for i in data['data']['videoList']['videos']]
|
||||
pg=data['data']['videoList'].get('totalPages')
|
||||
if pg and pg > 1:
|
||||
id = v['albumId']
|
||||
pages = list(range(2, pg + 1))
|
||||
page_results = {}
|
||||
with ThreadPoolExecutor(max_workers=10) as executor:
|
||||
future_to_page = {
|
||||
executor.submit(self.fetch_page_data, page, id): page
|
||||
for page in pages
|
||||
}
|
||||
for future in as_completed(future_to_page):
|
||||
page = future_to_page[future]
|
||||
try:
|
||||
result = future.result()
|
||||
page_results[page] = result
|
||||
except Exception as e:
|
||||
print(f"Error fetching page {page}: {e}")
|
||||
for page in sorted(page_results.keys()):
|
||||
purl.extend(page_results[page])
|
||||
vod['vod_play_url'] = '#'.join(purl)
|
||||
else:
|
||||
vdata=self.fetch(f'{self.dhost}/h5/mina/baidu/play/head/v1/{ids[0]}/', headers=self.headers).json()
|
||||
v=vdata['data']['playInfo']
|
||||
vod = {
|
||||
'vod_name': v.get('shortTitle'),
|
||||
'type_name': v.get('channelName'),
|
||||
'vod_year': v.get('year'),
|
||||
'vod_remarks': v.get('focus'),
|
||||
'vod_actor': v.get('mainActors'),
|
||||
'vod_director': v.get('directors'),
|
||||
'vod_content': v.get('desc'),
|
||||
'vod_play_from': '爱奇艺',
|
||||
'vod_play_url': f'{v.get("shortTitle")}${ids[-1]}'
|
||||
}
|
||||
return {'list':[vod]}
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
data=self.fetch(f'{self.hhost}/portal/lw/search/homePageV3?key={key}¤t_page={pg}&mode=1&source=input&suggest=&version=13.014.21150&pageNum={pg}&pageSize=25&pu=&u={self.did}&scale=150&token=&userVip=0&conduit=&vipType=-1&os=&osShortName=win10&dataType=&appMode=', headers=self.headers).json()
|
||||
videos = []
|
||||
vdata=data['data']['templates']
|
||||
for i in data['data']['templates']:
|
||||
if i.get('intentAlbumInfos'):
|
||||
vdata=[{'albumInfo': c} for c in i['intentAlbumInfos']]+vdata
|
||||
|
||||
for i in vdata:
|
||||
if i.get('albumInfo') and (i['albumInfo'].get('playQipuId','') or i['albumInfo'].get('qipuId')) and i['albumInfo'].get('pageUrl'):
|
||||
b=i['albumInfo']
|
||||
id=f"{(b.get('playQipuId','') or b.get('qipuId'))}@{self.e64(b.get('pageUrl'))}"
|
||||
videos.append({
|
||||
'vod_id': id,
|
||||
'vod_name': b.get('title'),
|
||||
'vod_pic': b.get('img'),
|
||||
'vod_year': (b.get('year',{}) or {}).get('value'),
|
||||
'vod_remarks': b.get('subscriptContent') or b.get('channel') or b.get('vipTips')
|
||||
})
|
||||
return {'list':videos,'page':pg}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
return {'jx':1,'parse': 1, 'url': id, 'header': ''}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def fetch_page_data(self, page, id):
|
||||
try:
|
||||
url = f'{self.dhost}/h5/mina/avlist/{page}/{id}/'
|
||||
data = self.fetch(url, headers=self.headers).json()
|
||||
return [f'{i["shortTitle"]}${i["pageUrl"]}' for i in data['data']['videoList']['videos']]
|
||||
except:
|
||||
return []
|
||||
|
||||
def getf(self,body):
|
||||
data=self.fetch(f'{self.hhost}/portal/lw/videolib/tag?channel_id={body["type_id"]}&tagAdd=&selected_tag_name=&version=13.014.21150&device={self.did}&uid=', headers=self.headers).json()
|
||||
ft = []
|
||||
# for i in data[:-1]:
|
||||
for i in data:
|
||||
try:
|
||||
value_array = [{"n": value['text'], "v": self.e64(value['tag_param'])} for value in i['tags'] if
|
||||
value.get('tag_param')]
|
||||
ft.append({"key": i['group'], "name": i['group'], "value": value_array})
|
||||
except:
|
||||
print(i)
|
||||
return (body['type_id'], ft)
|
||||
|
||||
def e64(self, text):
|
||||
try:
|
||||
text_bytes = text.encode('utf-8')
|
||||
encoded_bytes = b64encode(text_bytes)
|
||||
return encoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64编码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def d64(self,encoded_text: str):
|
||||
try:
|
||||
encoded_bytes = encoded_text.encode('utf-8')
|
||||
decoded_bytes = b64decode(encoded_bytes)
|
||||
return decoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64解码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def random_str(self,length=16):
|
||||
hex_chars = '0123456789abcdef'
|
||||
return ''.join(random.choice(hex_chars) for _ in range(length))
|
|
@ -0,0 +1,768 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
from base64 import b64decode, b64encode
|
||||
from urllib.parse import parse_qs
|
||||
import requests
|
||||
from pyquery import PyQuery as pq
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
tid = 'douyin'
|
||||
headers = self.gethr(0, tid)
|
||||
response = requests.head(self.hosts[tid], headers=headers)
|
||||
ttwid = response.cookies.get('ttwid')
|
||||
headers.update({
|
||||
'authority': self.hosts[tid].split('//')[-1],
|
||||
'cookie': f'ttwid={ttwid}' if ttwid else ''
|
||||
})
|
||||
self.dyheaders = headers
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
headers = [
|
||||
{
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0"
|
||||
},
|
||||
{
|
||||
"User-Agent": "Dart/3.4 (dart:io)"
|
||||
}
|
||||
]
|
||||
|
||||
excepturl = 'https://www.baidu.com'
|
||||
|
||||
hosts = {
|
||||
"huya": ["https://www.huya.com","https://mp.huya.com"],
|
||||
"douyin": "https://live.douyin.com",
|
||||
"douyu": "https://www.douyu.com",
|
||||
"wangyi": "https://cc.163.com",
|
||||
"bili": ["https://api.live.bilibili.com", "https://api.bilibili.com"]
|
||||
}
|
||||
|
||||
referers = {
|
||||
"huya": "https://live.cdn.huya.com",
|
||||
"douyin": "https://live.douyin.com",
|
||||
"douyu": "https://m.douyu.com",
|
||||
"bili": "https://live.bilibili.com"
|
||||
}
|
||||
|
||||
playheaders = {
|
||||
"wangyi": {
|
||||
"User-Agent": "ExoPlayer",
|
||||
"Connection": "Keep-Alive",
|
||||
"Icy-MetaData": "1"
|
||||
},
|
||||
"bili": {
|
||||
'Accept': '*/*',
|
||||
'Icy-MetaData': '1',
|
||||
'referer': referers['bili'],
|
||||
'user-agent': headers[0]['User-Agent']
|
||||
},
|
||||
'douyin': {
|
||||
'User-Agent': 'libmpv',
|
||||
'Icy-MetaData': '1'
|
||||
},
|
||||
'huya': {
|
||||
'User-Agent': 'ExoPlayer',
|
||||
'Connection': 'Keep-Alive',
|
||||
'Icy-MetaData': '1'
|
||||
},
|
||||
'douyu': {
|
||||
'User-Agent': 'libmpv',
|
||||
'Icy-MetaData': '1'
|
||||
}
|
||||
}
|
||||
|
||||
def process_bili(self):
|
||||
try:
|
||||
self.blfdata = self.fetch(
|
||||
f'{self.hosts["bili"][0]}/room/v1/Area/getList?need_entrance=1&parent_id=0',
|
||||
headers=self.gethr(0, 'bili')
|
||||
).json()
|
||||
return ('bili', [{'key': 'cate', 'name': '分类',
|
||||
'value': [{'n': i['name'], 'v': str(i['id'])}
|
||||
for i in self.blfdata['data']]}])
|
||||
except Exception as e:
|
||||
print(f"bili处理错误: {e}")
|
||||
return 'bili', None
|
||||
|
||||
def process_douyin(self):
|
||||
try:
|
||||
data = self.getpq(self.hosts['douyin'], headers=self.dyheaders)('script')
|
||||
for i in data.items():
|
||||
if 'categoryData' in i.text():
|
||||
content = i.text()
|
||||
start = content.find('{')
|
||||
end = content.rfind('}') + 1
|
||||
if start != -1 and end != -1:
|
||||
json_str = content[start:end]
|
||||
json_str = json_str.replace('\\"', '"')
|
||||
try:
|
||||
self.dyifdata = json.loads(json_str)
|
||||
return ('douyin', [{'key': 'cate', 'name': '分类',
|
||||
'value': [{'n': i['partition']['title'],
|
||||
'v': f"{i['partition']['id_str']}@@{i['partition']['title']}"}
|
||||
for i in self.dyifdata['categoryData']]}])
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"douyin解析错误: {e}")
|
||||
return 'douyin', None
|
||||
except Exception as e:
|
||||
print(f"douyin请求或处理错误: {e}")
|
||||
return 'douyin', None
|
||||
|
||||
def process_douyu(self):
|
||||
try:
|
||||
self.dyufdata = self.fetch(
|
||||
f'{self.referers["douyu"]}/api/cate/list',
|
||||
headers=self.headers[1]
|
||||
).json()
|
||||
return ('douyu', [{'key': 'cate', 'name': '分类',
|
||||
'value': [{'n': i['cate1Name'], 'v': str(i['cate1Id'])}
|
||||
for i in self.dyufdata['data']['cate1Info']]}])
|
||||
except Exception as e:
|
||||
print(f"douyu错误: {e}")
|
||||
return 'douyu', None
|
||||
|
||||
def homeContent(self, filter):
|
||||
result = {}
|
||||
cateManual = {
|
||||
"虎牙": "huya",
|
||||
"哔哩": "bili",
|
||||
"抖音": "douyin",
|
||||
"斗鱼": "douyu",
|
||||
"网易": "wangyi"
|
||||
}
|
||||
classes = []
|
||||
filters = {
|
||||
'huya': [{'key': 'cate', 'name': '分类',
|
||||
'value': [{'n': '网游', 'v': '1'}, {'n': '单机', 'v': '2'},
|
||||
{'n': '娱乐', 'v': '8'}, {'n': '手游', 'v': '3'}]}]
|
||||
}
|
||||
|
||||
with ThreadPoolExecutor(max_workers=3) as executor:
|
||||
futures = {
|
||||
executor.submit(self.process_bili): 'bili',
|
||||
executor.submit(self.process_douyin): 'douyin',
|
||||
executor.submit(self.process_douyu): 'douyu'
|
||||
}
|
||||
|
||||
for future in futures:
|
||||
platform, filter_data = future.result()
|
||||
if filter_data:
|
||||
filters[platform] = filter_data
|
||||
|
||||
for k in cateManual:
|
||||
classes.append({
|
||||
'type_name': k,
|
||||
'type_id': cateManual[k]
|
||||
})
|
||||
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
pass
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
vdata = []
|
||||
result = {}
|
||||
pagecount = 9999
|
||||
result['page'] = pg
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
if tid == 'wangyi':
|
||||
vdata, pagecount = self.wyccContent(tid, pg, filter, extend, vdata)
|
||||
elif 'bili' in tid:
|
||||
vdata, pagecount = self.biliContent(tid, pg, filter, extend, vdata)
|
||||
elif 'huya' in tid:
|
||||
vdata, pagecount = self.huyaContent(tid, pg, filter, extend, vdata)
|
||||
elif 'douyin' in tid:
|
||||
vdata, pagecount = self.douyinContent(tid, pg, filter, extend, vdata)
|
||||
elif 'douyu' in tid:
|
||||
vdata, pagecount = self.douyuContent(tid, pg, filter, extend, vdata)
|
||||
result['list'] = vdata
|
||||
result['pagecount'] = pagecount
|
||||
return result
|
||||
|
||||
def wyccContent(self, tid, pg, filter, extend, vdata):
|
||||
params = {
|
||||
'format': 'json',
|
||||
'start': (int(pg) - 1) * 20,
|
||||
'size': '20',
|
||||
}
|
||||
response = self.fetch(f'{self.hosts[tid]}/api/category/live/', params=params, headers=self.headers[0]).json()
|
||||
for i in response['lives']:
|
||||
if i.get('cuteid'):
|
||||
bvdata = self.buildvod(
|
||||
vod_id=f"{tid}@@{i['cuteid']}",
|
||||
vod_name=i.get('title'),
|
||||
vod_pic=i.get('cover'),
|
||||
vod_remarks=i.get('nickname'),
|
||||
style={"type": "rect", "ratio": 1.33}
|
||||
)
|
||||
vdata.append(bvdata)
|
||||
return vdata, 9999
|
||||
|
||||
def biliContent(self, tid, pg, filter, extend, vdata):
|
||||
if extend.get('cate') and pg == '1' and 'click' not in tid:
|
||||
for i in self.blfdata['data']:
|
||||
if str(i['id']) == extend['cate']:
|
||||
for j in i['list']:
|
||||
v = self.buildvod(
|
||||
vod_id=f"click_{tid}@@{i['id']}@@{j['id']}",
|
||||
vod_name=j.get('name'),
|
||||
vod_pic=j.get('pic'),
|
||||
vod_tag=1,
|
||||
style={"type": "oval", "ratio": 1}
|
||||
)
|
||||
vdata.append(v)
|
||||
return vdata, 1
|
||||
else:
|
||||
path = f'/xlive/web-interface/v1/second/getListByArea?platform=web&sort=online&page_size=30&page={pg}'
|
||||
if 'click' in tid:
|
||||
ids = tid.split('_')[1].split('@@')
|
||||
tid = ids[0]
|
||||
path = f'/xlive/web-interface/v1/second/getList?platform=web&parent_area_id={ids[1]}&area_id={ids[-1]}&sort_type=&page={pg}'
|
||||
data = self.fetch(f'{self.hosts[tid][0]}{path}', headers=self.gethr(0, tid)).json()
|
||||
for i in data['data']['list']:
|
||||
if i.get('roomid'):
|
||||
data = self.buildvod(
|
||||
f"{tid}@@{i['roomid']}",
|
||||
i.get('title'),
|
||||
i.get('cover'),
|
||||
i.get('watched_show', {}).get('text_large'),
|
||||
0,
|
||||
i.get('uname'),
|
||||
style={"type": "rect", "ratio": 1.33}
|
||||
)
|
||||
vdata.append(data)
|
||||
return vdata, 9999
|
||||
|
||||
def huyaContent(self, tid, pg, filter, extend, vdata):
|
||||
if extend.get('cate') and pg == '1' and 'click' not in tid:
|
||||
id = extend.get('cate')
|
||||
data = self.fetch(f'{self.referers[tid]}/liveconfig/game/bussLive?bussType={id}',
|
||||
headers=self.headers[1]).json()
|
||||
for i in data['data']:
|
||||
v = self.buildvod(
|
||||
vod_id=f"click_{tid}@@{int(i['gid'])}",
|
||||
vod_name=i.get('gameFullName'),
|
||||
vod_pic=f'https://huyaimg.msstatic.com/cdnimage/game/{int(i["gid"])}-MS.jpg',
|
||||
vod_tag=1,
|
||||
style={"type": "oval", "ratio": 1}
|
||||
)
|
||||
vdata.append(v)
|
||||
return vdata, 1
|
||||
else:
|
||||
gid = ''
|
||||
if 'click' in tid:
|
||||
ids = tid.split('_')[1].split('@@')
|
||||
tid = ids[0]
|
||||
gid = f'&gameId={ids[1]}'
|
||||
data = self.fetch(f'{self.hosts[tid][0]}/cache.php?m=LiveList&do=getLiveListByPage&tagAll=0{gid}&page={pg}',
|
||||
headers=self.headers[1]).json()
|
||||
for i in data['data']['datas']:
|
||||
if i.get('profileRoom'):
|
||||
v = self.buildvod(
|
||||
f"{tid}@@{i['profileRoom']}",
|
||||
i.get('introduction'),
|
||||
i.get('screenshot'),
|
||||
str(int(i.get('totalCount', '1')) / 10000) + '万',
|
||||
0,
|
||||
i.get('nick'),
|
||||
style={"type": "rect", "ratio": 1.33}
|
||||
|
||||
)
|
||||
vdata.append(v)
|
||||
return vdata, 9999
|
||||
|
||||
def douyinContent(self, tid, pg, filter, extend, vdata):
|
||||
if extend.get('cate') and pg == '1' and 'click' not in tid:
|
||||
ids = extend.get('cate').split('@@')
|
||||
for i in self.dyifdata['categoryData']:
|
||||
c = i['partition']
|
||||
if c['id_str'] == ids[0] and c['title'] == ids[1]:
|
||||
vlist = i['sub_partition'].copy()
|
||||
vlist.insert(0, {'partition': c})
|
||||
for j in vlist:
|
||||
j = j['partition']
|
||||
v = self.buildvod(
|
||||
vod_id=f"click_{tid}@@{j['id_str']}@@{j['type']}",
|
||||
vod_name=j.get('title'),
|
||||
vod_pic='https://p3-pc-weboff.byteimg.com/tos-cn-i-9r5gewecjs/pwa_v3/512x512-1.png',
|
||||
vod_tag=1,
|
||||
style={"type": "oval", "ratio": 1}
|
||||
)
|
||||
vdata.append(v)
|
||||
return vdata, 1
|
||||
else:
|
||||
path = f'/webcast/web/partition/detail/room/?aid=6383&app_name=douyin_web&live_id=1&device_platform=web&count=15&offset={(int(pg) - 1) * 15}&partition=720&partition_type=1'
|
||||
if 'click' in tid:
|
||||
ids = tid.split('_')[1].split('@@')
|
||||
tid = ids[0]
|
||||
path = f'/webcast/web/partition/detail/room/?aid=6383&app_name=douyin_web&live_id=1&device_platform=web&count=15&offset={(int(pg) - 1) * 15}&partition={ids[1]}&partition_type={ids[-1]}&req_from=2'
|
||||
data = self.fetch(f'{self.hosts[tid]}{path}', headers=self.dyheaders).json()
|
||||
for i in data['data']['data']:
|
||||
v = self.buildvod(
|
||||
vod_id=f"{tid}@@{i['web_rid']}",
|
||||
vod_name=i['room'].get('title'),
|
||||
vod_pic=i['room']['cover'].get('url_list')[0],
|
||||
vod_year=i.get('user_count_str'),
|
||||
vod_remarks=i['room']['owner'].get('nickname'),
|
||||
style={"type": "rect", "ratio": 1.33}
|
||||
)
|
||||
vdata.append(v)
|
||||
return vdata, 9999
|
||||
|
||||
def douyuContent(self, tid, pg, filter, extend, vdata):
|
||||
if extend.get('cate') and pg == '1' and 'click' not in tid:
|
||||
for i in self.dyufdata['data']['cate2Info']:
|
||||
if str(i['cate1Id']) == extend['cate']:
|
||||
v = self.buildvod(
|
||||
vod_id=f"click_{tid}@@{i['cate2Id']}",
|
||||
vod_name=i.get('cate2Name'),
|
||||
vod_pic=i.get('icon'),
|
||||
vod_remarks=i.get('count'),
|
||||
vod_tag=1,
|
||||
style={"type": "oval", "ratio": 1}
|
||||
)
|
||||
vdata.append(v)
|
||||
return vdata, 1
|
||||
else:
|
||||
path = f'/japi/weblist/apinc/allpage/6/{pg}'
|
||||
if 'click' in tid:
|
||||
ids = tid.split('_')[1].split('@@')
|
||||
tid = ids[0]
|
||||
path = f'/gapi/rkc/directory/mixList/2_{ids[1]}/{pg}'
|
||||
url = f'{self.hosts[tid]}{path}'
|
||||
data = self.fetch(url, headers=self.headers[1]).json()
|
||||
for i in data['data']['rl']:
|
||||
v = self.buildvod(
|
||||
vod_id=f"{tid}@@{i['rid']}",
|
||||
vod_name=i.get('rn'),
|
||||
vod_pic=i.get('rs16'),
|
||||
vod_year=str(int(i.get('ol', 1)) / 10000) + '万',
|
||||
vod_remarks=i.get('nn'),
|
||||
style={"type": "rect", "ratio": 1.33}
|
||||
)
|
||||
vdata.append(v)
|
||||
return vdata, 9999
|
||||
|
||||
def detailContent(self, ids):
|
||||
ids = ids[0].split('@@')
|
||||
if ids[0] == 'wangyi':
|
||||
vod = self.wyccDetail(ids)
|
||||
elif ids[0] == 'bili':
|
||||
vod = self.biliDetail(ids)
|
||||
elif ids[0] == 'huya':
|
||||
vod = self.huyaDetail(ids)
|
||||
elif ids[0] == 'douyin':
|
||||
vod = self.douyinDetail(ids)
|
||||
elif ids[0] == 'douyu':
|
||||
vod = self.douyuDetail(ids)
|
||||
return {'list': [vod]}
|
||||
|
||||
def wyccDetail(self, ids):
|
||||
try:
|
||||
vdata = self.getpq(f'{self.hosts[ids[0]]}/{ids[1]}', self.headers[0])('script').eq(-1).text()
|
||||
|
||||
def get_quality_name(vbr):
|
||||
if vbr <= 600:
|
||||
return "标清"
|
||||
elif vbr <= 1000:
|
||||
return "高清"
|
||||
elif vbr <= 2000:
|
||||
return "超清"
|
||||
else:
|
||||
return "蓝光"
|
||||
|
||||
data = json.loads(vdata)['props']['pageProps']['roomInfoInitData']
|
||||
name = data['live'].get('title', ids[0])
|
||||
vod = self.buildvod(vod_name=data.get('keywords_suffix'), vod_remarks=data['live'].get('title'),
|
||||
vod_content=data.get('description_suffix'))
|
||||
resolution_data = data['live']['quickplay']['resolution']
|
||||
all_streams = {}
|
||||
sorted_qualities = sorted(resolution_data.items(),
|
||||
key=lambda x: x[1]['vbr'],
|
||||
reverse=True)
|
||||
for quality, data in sorted_qualities:
|
||||
vbr = data['vbr']
|
||||
quality_name = get_quality_name(vbr)
|
||||
for cdn_name, url in data['cdn'].items():
|
||||
if cdn_name not in all_streams and type(url) == str and url.startswith('http'):
|
||||
all_streams[cdn_name] = []
|
||||
if isinstance(url, str) and url.startswith('http'):
|
||||
all_streams[cdn_name].extend([quality_name, url])
|
||||
plists = []
|
||||
names = []
|
||||
for i, (cdn_name, stream_list) in enumerate(all_streams.items(), 1):
|
||||
names.append(f'线路{i}')
|
||||
pstr = f"{name}${ids[0]}@@{self.e64(json.dumps(stream_list))}"
|
||||
plists.append(pstr)
|
||||
vod['vod_play_from'] = "$$$".join(names)
|
||||
vod['vod_play_url'] = "$$$".join(plists)
|
||||
return vod
|
||||
except Exception as e:
|
||||
return self.handle_exception(e)
|
||||
|
||||
def biliDetail(self, ids):
|
||||
try:
|
||||
vdata = self.fetch(
|
||||
f'{self.hosts[ids[0]][0]}/xlive/web-room/v1/index/getInfoByRoom?room_id={ids[1]}&wts={int(time.time())}',
|
||||
headers=self.gethr(0, ids[0])).json()
|
||||
v = vdata['data']['room_info']
|
||||
vod = self.buildvod(
|
||||
vod_name=v.get('title'),
|
||||
type_name=v.get('parent_area_name') + '/' + v.get('area_name'),
|
||||
vod_remarks=v.get('tags'),
|
||||
vod_play_from=v.get('title'),
|
||||
)
|
||||
data = self.fetch(
|
||||
f'{self.hosts[ids[0]][0]}/xlive/web-room/v2/index/getRoomPlayInfo?room_id={ids[1]}&protocol=0%2C1&format=0%2C1%2C2&codec=0%2C1&platform=web',
|
||||
headers=self.gethr(0, ids[0])).json()
|
||||
vdnams = data['data']['playurl_info']['playurl']['g_qn_desc']
|
||||
all_accept_qns = []
|
||||
streams = data['data']['playurl_info']['playurl']['stream']
|
||||
for stream in streams:
|
||||
for format_item in stream['format']:
|
||||
for codec in format_item['codec']:
|
||||
if 'accept_qn' in codec:
|
||||
all_accept_qns.append(codec['accept_qn'])
|
||||
max_accept_qn = max(all_accept_qns, key=len) if all_accept_qns else []
|
||||
quality_map = {
|
||||
item['qn']: item['desc']
|
||||
for item in vdnams
|
||||
}
|
||||
quality_names = [f"{quality_map.get(qn)}${ids[0]}@@{ids[1]}@@{qn}" for qn in max_accept_qn]
|
||||
vod['vod_play_url'] = "#".join(quality_names)
|
||||
return vod
|
||||
except Exception as e:
|
||||
return self.handle_exception(e)
|
||||
|
||||
def huyaDetail(self, ids):
|
||||
try:
|
||||
vdata = self.fetch(f'{self.hosts[ids[0]][1]}/cache.php?m=Live&do=profileRoom&roomid={ids[1]}',
|
||||
headers=self.headers[0]).json()
|
||||
v = vdata['data']['liveData']
|
||||
vod = self.buildvod(
|
||||
vod_name=v.get('introduction'),
|
||||
type_name=v.get('gameFullName'),
|
||||
vod_director=v.get('nick'),
|
||||
vod_remarks=v.get('contentIntro'),
|
||||
)
|
||||
data = dict(reversed(list(vdata['data']['stream'].items())))
|
||||
names = []
|
||||
plist = []
|
||||
|
||||
for stream_type, stream_data in data.items():
|
||||
if isinstance(stream_data, dict) and 'multiLine' in stream_data and 'rateArray' in stream_data:
|
||||
names.append(f"线路{len(names) + 1}")
|
||||
qualities = sorted(
|
||||
stream_data['rateArray'],
|
||||
key=lambda x: (x['iBitRate'], x['sDisplayName']),
|
||||
reverse=True
|
||||
)
|
||||
cdn_urls = []
|
||||
for cdn in stream_data['multiLine']:
|
||||
quality_urls = []
|
||||
for quality in qualities:
|
||||
quality_name = quality['sDisplayName']
|
||||
bit_rate = quality['iBitRate']
|
||||
base_url = cdn['url']
|
||||
if bit_rate > 0:
|
||||
if '.m3u8' in base_url:
|
||||
new_url = base_url.replace(
|
||||
'ratio=2000',
|
||||
f'ratio={bit_rate}'
|
||||
)
|
||||
else:
|
||||
new_url = base_url.replace(
|
||||
'imgplus.flv',
|
||||
f'imgplus_{bit_rate}.flv'
|
||||
)
|
||||
else:
|
||||
new_url = base_url
|
||||
quality_urls.extend([quality_name, new_url])
|
||||
encoded_urls = self.e64(json.dumps(quality_urls))
|
||||
cdn_urls.append(f"{cdn['cdnType']}${ids[0]}@@{encoded_urls}")
|
||||
|
||||
if cdn_urls:
|
||||
plist.append('#'.join(cdn_urls))
|
||||
vod['vod_play_from'] = "$$$".join(names)
|
||||
vod['vod_play_url'] = "$$$".join(plist)
|
||||
return vod
|
||||
except Exception as e:
|
||||
return self.handle_exception(e)
|
||||
|
||||
def douyinDetail(self, ids):
|
||||
url = f'{self.hosts[ids[0]]}/webcast/room/web/enter/?aid=6383&app_name=douyin_web&live_id=1&device_platform=web&enter_from=web_live&web_rid={ids[1]}&room_id_str=&enter_source=&Room-Enter-User-Login-Ab=0&is_need_double_stream=false&cookie_enabled=true&screen_width=1980&screen_height=1080&browser_language=zh-CN&browser_platform=Win32&browser_name=Edge&browser_version=125.0.0.0'
|
||||
data = self.fetch(url, headers=self.dyheaders).json()
|
||||
try:
|
||||
vdata = data['data']['data'][0]
|
||||
vod = self.buildvod(
|
||||
vod_name=vdata['title'],
|
||||
vod_remarks=vdata['user_count_str'],
|
||||
)
|
||||
resolution_data = vdata['stream_url']['live_core_sdk_data']['pull_data']['options']['qualities']
|
||||
stream_json = vdata['stream_url']['live_core_sdk_data']['pull_data']['stream_data']
|
||||
stream_json = json.loads(stream_json)
|
||||
available_types = []
|
||||
if any(sdk_key in stream_json['data'] and 'main' in stream_json['data'][sdk_key] for sdk_key in
|
||||
stream_json['data']):
|
||||
available_types.append('main')
|
||||
if any(sdk_key in stream_json['data'] and 'backup' in stream_json['data'][sdk_key] for sdk_key in
|
||||
stream_json['data']):
|
||||
available_types.append('backup')
|
||||
plist = []
|
||||
for line_type in available_types:
|
||||
format_arrays = {'flv': [], 'hls': [], 'lls': []}
|
||||
qualities = sorted(resolution_data, key=lambda x: x['level'], reverse=True)
|
||||
for quality in qualities:
|
||||
sdk_key = quality['sdk_key']
|
||||
if sdk_key in stream_json['data'] and line_type in stream_json['data'][sdk_key]:
|
||||
stream_info = stream_json['data'][sdk_key][line_type]
|
||||
if stream_info.get('flv'):
|
||||
format_arrays['flv'].extend([quality['name'], stream_info['flv']])
|
||||
if stream_info.get('hls'):
|
||||
format_arrays['hls'].extend([quality['name'], stream_info['hls']])
|
||||
if stream_info.get('lls'):
|
||||
format_arrays['lls'].extend([quality['name'], stream_info['lls']])
|
||||
format_urls = []
|
||||
for format_name, url_array in format_arrays.items():
|
||||
if url_array:
|
||||
encoded_urls = self.e64(json.dumps(url_array))
|
||||
format_urls.append(f"{format_name}${ids[0]}@@{encoded_urls}")
|
||||
|
||||
if format_urls:
|
||||
plist.append('#'.join(format_urls))
|
||||
|
||||
names = ['线路1', '线路2'][:len(plist)]
|
||||
vod['vod_play_from'] = "$$$".join(names)
|
||||
vod['vod_play_url'] = "$$$".join(plist)
|
||||
return vod
|
||||
|
||||
except Exception as e:
|
||||
return self.handle_exception(e)
|
||||
|
||||
def douyuDetail(self, ids):
|
||||
headers = self.gethr(0, zr=f'{self.hosts[ids[0]]}/{ids[1]}')
|
||||
try:
|
||||
data = self.fetch(f'{self.hosts[ids[0]]}/betard/{ids[1]}', headers=headers).json()
|
||||
vname = data['room']['room_name']
|
||||
vod = self.buildvod(
|
||||
vod_name=vname,
|
||||
vod_remarks=data['room'].get('second_lvl_name'),
|
||||
vod_director=data['room'].get('nickname'),
|
||||
)
|
||||
vdata = self.fetch(f'{self.hosts[ids[0]]}/swf_api/homeH5Enc?rids={ids[1]}', headers=headers).json()
|
||||
json_body = vdata['data']
|
||||
json_body = {"html": self.douyu_text(json_body[f'room{ids[1]}']), "rid": ids[1]}
|
||||
sign = self.post('http://alive.nsapps.cn/api/AllLive/DouyuSign', json=json_body, headers=self.headers[1]).json()['data']
|
||||
body = f'{sign}&cdn=&rate=-1&ver=Douyu_223061205&iar=1&ive=1&hevc=0&fa=0'
|
||||
body=self.params_to_json(body)
|
||||
nubdata = self.post(f'{self.hosts[ids[0]]}/lapi/live/getH5Play/{ids[1]}', data=body, headers=headers).json()
|
||||
plist = []
|
||||
names = []
|
||||
for i,x in enumerate(nubdata['data']['cdnsWithName']):
|
||||
names.append(f'线路{i+1}')
|
||||
d = {'sign': sign, 'cdn': x['cdn'], 'id': ids[1]}
|
||||
plist.append(
|
||||
f'{vname}${ids[0]}@@{self.e64(json.dumps(d))}@@{self.e64(json.dumps(nubdata["data"]["multirates"]))}')
|
||||
vod['vod_play_from'] = "$$$".join(names)
|
||||
vod['vod_play_url'] = "$$$".join(plist)
|
||||
return vod
|
||||
except Exception as e:
|
||||
return self.handle_exception(e)
|
||||
|
||||
def douyu_text(self, text):
|
||||
function_positions = [m.start() for m in re.finditer('function', text)]
|
||||
total_functions = len(function_positions)
|
||||
if total_functions % 2 == 0:
|
||||
target_index = total_functions // 2 + 1
|
||||
else:
|
||||
target_index = (total_functions - 1) // 2 + 1
|
||||
if total_functions >= target_index:
|
||||
cut_position = function_positions[target_index - 1]
|
||||
ctext = text[4:cut_position]
|
||||
return re.sub(r'eval\(strc\)\([\w\d,]+\)', 'strc', ctext)
|
||||
return text
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
pass
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
try:
|
||||
ids = id.split('@@')
|
||||
p = 1
|
||||
if ids[0] in ['wangyi', 'douyin','huya']:
|
||||
p, url = 0, json.loads(self.d64(ids[1]))
|
||||
elif ids[0] == 'bili':
|
||||
p, url = self.biliplay(ids)
|
||||
elif ids[0] == 'huya':
|
||||
p, url = 0, json.loads(self.d64(ids[1]))
|
||||
elif ids[0] == 'douyu':
|
||||
p, url = self.douyuplay(ids)
|
||||
return {'parse': p, 'url': url, 'header': self.playheaders[ids[0]]}
|
||||
except Exception as e:
|
||||
return {'parse': 1, 'url': self.excepturl, 'header': self.headers[0]}
|
||||
|
||||
def biliplay(self, ids):
|
||||
try:
|
||||
data = self.fetch(
|
||||
f'{self.hosts[ids[0]][0]}/xlive/web-room/v2/index/getRoomPlayInfo?room_id={ids[1]}&protocol=0,1&format=0,2&codec=0&platform=web&qn={ids[2]}',
|
||||
headers=self.gethr(0, ids[0])).json()
|
||||
urls = []
|
||||
line_index = 1
|
||||
for stream in data['data']['playurl_info']['playurl']['stream']:
|
||||
for format_item in stream['format']:
|
||||
for codec in format_item['codec']:
|
||||
for url_info in codec['url_info']:
|
||||
full_url = f"{url_info['host']}/{codec['base_url'].lstrip('/')}{url_info['extra']}"
|
||||
urls.extend([f"线路{line_index}", full_url])
|
||||
line_index += 1
|
||||
return 0, urls
|
||||
except Exception as e:
|
||||
return 1, self.excepturl
|
||||
|
||||
def douyuplay(self, ids):
|
||||
try:
|
||||
sdata = json.loads(self.d64(ids[1]))
|
||||
headers = self.gethr(0, zr=f'{self.hosts[ids[0]]}/{sdata["id"]}')
|
||||
ldata = json.loads(self.d64(ids[2]))
|
||||
result_obj = {}
|
||||
with ThreadPoolExecutor(max_workers=len(ldata)) as executor:
|
||||
futures = [
|
||||
executor.submit(
|
||||
self.douyufp,
|
||||
sdata,
|
||||
quality,
|
||||
headers,
|
||||
self.hosts[ids[0]],
|
||||
result_obj
|
||||
) for quality in ldata
|
||||
]
|
||||
for future in futures:
|
||||
future.result()
|
||||
|
||||
result = []
|
||||
for bit in sorted(result_obj.keys(), reverse=True):
|
||||
result.extend(result_obj[bit])
|
||||
|
||||
if result:
|
||||
return 0, result
|
||||
return 1, self.excepturl
|
||||
|
||||
except Exception as e:
|
||||
return 1, self.excepturl
|
||||
|
||||
def douyufp(self, sdata, quality, headers, host, result_obj):
|
||||
try:
|
||||
body = f'{sdata["sign"]}&cdn={sdata["cdn"]}&rate={quality["rate"]}'
|
||||
body=self.params_to_json(body)
|
||||
data = self.post(f'{host}/lapi/live/getH5Play/{sdata["id"]}',
|
||||
data=body, headers=headers).json()
|
||||
if data.get('data'):
|
||||
play_url = data['data']['rtmp_url'] + '/' + data['data']['rtmp_live']
|
||||
bit = quality.get('bit', 0)
|
||||
if bit not in result_obj:
|
||||
result_obj[bit] = []
|
||||
result_obj[bit].extend([quality['name'], play_url])
|
||||
except Exception as e:
|
||||
print(f"Error fetching {quality['name']}: {str(e)}")
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def e64(self, text):
|
||||
try:
|
||||
text_bytes = text.encode('utf-8')
|
||||
encoded_bytes = b64encode(text_bytes)
|
||||
return encoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64编码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def d64(self, encoded_text):
|
||||
try:
|
||||
encoded_bytes = encoded_text.encode('utf-8')
|
||||
decoded_bytes = b64decode(encoded_bytes)
|
||||
return decoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"Base64解码错误: {str(e)}")
|
||||
return ""
|
||||
|
||||
def josn_to_params(self, params, skip_empty=False):
|
||||
query = []
|
||||
for k, v in params.items():
|
||||
if skip_empty and not v:
|
||||
continue
|
||||
query.append(f"{k}={v}")
|
||||
return "&".join(query)
|
||||
|
||||
def params_to_json(self, query_string):
|
||||
parsed_data = parse_qs(query_string)
|
||||
result = {key: value[0] for key, value in parsed_data.items()}
|
||||
return result
|
||||
|
||||
def buildvod(self, vod_id='', vod_name='', vod_pic='', vod_year='', vod_tag='', vod_remarks='', style='',
|
||||
type_name='', vod_area='', vod_actor='', vod_director='',
|
||||
vod_content='', vod_play_from='', vod_play_url=''):
|
||||
vod = {
|
||||
'vod_id': vod_id,
|
||||
'vod_name': vod_name,
|
||||
'vod_pic': vod_pic,
|
||||
'vod_year': vod_year,
|
||||
'vod_tag': 'folder' if vod_tag else '',
|
||||
'vod_remarks': vod_remarks,
|
||||
'style': style,
|
||||
'type_name': type_name,
|
||||
'vod_area': vod_area,
|
||||
'vod_actor': vod_actor,
|
||||
'vod_director': vod_director,
|
||||
'vod_content': vod_content,
|
||||
'vod_play_from': vod_play_from,
|
||||
'vod_play_url': vod_play_url
|
||||
}
|
||||
vod = {key: value for key, value in vod.items() if value}
|
||||
return vod
|
||||
|
||||
def getpq(self, url, headers=None, cookies=None):
|
||||
data = self.fetch(url, headers=headers, cookies=cookies).text
|
||||
try:
|
||||
return pq(data)
|
||||
except Exception as e:
|
||||
print(f"解析页面错误: {str(e)}")
|
||||
return pq(data.encode('utf-8'))
|
||||
|
||||
def gethr(self, index, rf='', zr=''):
|
||||
headers = self.headers[index]
|
||||
if zr:
|
||||
headers['referer'] = zr
|
||||
else:
|
||||
headers['referer'] = f"{self.referers[rf]}/"
|
||||
return headers
|
||||
|
||||
def handle_exception(self, e):
|
||||
print(f"报错: {str(e)}")
|
||||
return {'vod_play_from': '哎呀翻车啦', 'vod_play_url': f'翻车啦${self.excepturl}'}
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import json
|
||||
import sys
|
||||
import uuid
|
||||
import copy
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
self.dbody = {
|
||||
"page_params": {
|
||||
"channel_id": "",
|
||||
"filter_params": "sort=75",
|
||||
"page_type": "channel_operation",
|
||||
"page_id": "channel_list_second_page"
|
||||
}
|
||||
}
|
||||
self.body = self.dbody
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
host = 'https://v.qq.com'
|
||||
|
||||
apihost = 'https://pbaccess.video.qq.com'
|
||||
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5410.0 Safari/537.36',
|
||||
'origin': host,
|
||||
'referer': f'{host}/'
|
||||
}
|
||||
|
||||
def homeContent(self, filter):
|
||||
cdata = {
|
||||
"电视剧": "100113",
|
||||
"电影": "100173",
|
||||
"综艺": "100109",
|
||||
"纪录片": "100105",
|
||||
"动漫": "100119",
|
||||
"少儿": "100150",
|
||||
"短剧": "110755"
|
||||
}
|
||||
result = {}
|
||||
classes = []
|
||||
filters = {}
|
||||
for k in cdata:
|
||||
classes.append({
|
||||
'type_name': k,
|
||||
'type_id': cdata[k]
|
||||
})
|
||||
with ThreadPoolExecutor(max_workers=len(classes)) as executor:
|
||||
futures = [executor.submit(self.get_filter_data, item['type_id']) for item in classes]
|
||||
for future in futures:
|
||||
cid, data = future.result()
|
||||
if not data.get('data', {}).get('module_list_datas'):
|
||||
continue
|
||||
filter_dict = {}
|
||||
try:
|
||||
items = data['data']['module_list_datas'][-1]['module_datas'][-1]['item_data_lists']['item_datas']
|
||||
for item in items:
|
||||
if not item.get('item_params', {}).get('index_item_key'):
|
||||
continue
|
||||
params = item['item_params']
|
||||
filter_key = params['index_item_key']
|
||||
if filter_key not in filter_dict:
|
||||
filter_dict[filter_key] = {
|
||||
'key': filter_key,
|
||||
'name': params['index_name'],
|
||||
'value': []
|
||||
}
|
||||
filter_dict[filter_key]['value'].append({
|
||||
'n': params['option_name'],
|
||||
'v': params['option_value']
|
||||
})
|
||||
except (IndexError, KeyError):
|
||||
continue
|
||||
filters[cid] = list(filter_dict.values())
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
json_data = {'page_context':None,'page_params':{'page_id':'100101','page_type':'channel','skip_privacy_types':'0','support_click_scan':'1','new_mark_label_enabled':'1','ams_cookies':'',},'page_bypass_params':{'params':{'caller_id':'','data_mode':'default','page_id':'','page_type':'channel','platform_id':'2','user_mode':'default',},'scene':'channel','abtest_bypass_id':'',}}
|
||||
data = self.post(f'{self.apihost}/trpc.vector_layout.page_view.PageService/getPage',headers=self.headers, json=json_data).json()
|
||||
vlist = []
|
||||
for it in data['data']['CardList'][0]['children_list']['list']['cards']:
|
||||
if it.get('params'):
|
||||
p = it['params']
|
||||
tag = json.loads(p.get('uni_imgtag', '{}') or p.get('imgtag', '{}') or '{}')
|
||||
id = it.get('id') or p.get('cid')
|
||||
name = p.get('mz_title') or p.get('title')
|
||||
if name and 'http' not in id:
|
||||
vlist.append({
|
||||
'vod_id': id,
|
||||
'vod_name': name,
|
||||
'vod_pic': p.get('image_url'),
|
||||
'vod_year': tag.get('tag_2', {}).get('text'),
|
||||
'vod_remarks': tag.get('tag_4', {}).get('text')
|
||||
})
|
||||
return {'list': vlist}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
result = {}
|
||||
params = {
|
||||
"sort": extend.get('sort', '75'),
|
||||
"attr": extend.get('attr', '-1'),
|
||||
"itype": extend.get('itype', '-1'),
|
||||
"ipay": extend.get('ipay', '-1'),
|
||||
"iarea": extend.get('iarea', '-1'),
|
||||
"iyear": extend.get('iyear', '-1'),
|
||||
"theater": extend.get('theater', '-1'),
|
||||
"award": extend.get('award', '-1'),
|
||||
"recommend": extend.get('recommend', '-1')
|
||||
}
|
||||
if pg == '1':
|
||||
self.body = self.dbody.copy()
|
||||
self.body['page_params']['channel_id'] = tid
|
||||
self.body['page_params']['filter_params'] = self.josn_to_params(params)
|
||||
data = self.post(
|
||||
f'{self.apihost}/trpc.universal_backend_service.page_server_rpc.PageServer/GetPageData?video_appid=1000005&vplatform=2&vversion_name=8.9.10&new_mark_label_enabled=1',
|
||||
json=self.body, headers=self.headers).json()
|
||||
ndata = data['data']
|
||||
if ndata['has_next_page']:
|
||||
result['pagecount'] = 9999
|
||||
self.body['page_context'] = ndata['next_page_context']
|
||||
else:
|
||||
result['pagecount'] = int(pg)
|
||||
vlist = []
|
||||
for its in ndata['module_list_datas'][-1]['module_datas'][-1]['item_data_lists']['item_datas']:
|
||||
id = its.get('item_params', {}).get('cid')
|
||||
if id:
|
||||
p = its['item_params']
|
||||
tag = json.loads(p.get('uni_imgtag', '{}') or p.get('imgtag', '{}') or '{}')
|
||||
name = p.get('mz_title') or p.get('title')
|
||||
pic = p.get('new_pic_hz') or p.get('new_pic_vt')
|
||||
vlist.append({
|
||||
'vod_id': id,
|
||||
'vod_name': name,
|
||||
'vod_pic': pic,
|
||||
'vod_year': tag.get('tag_2', {}).get('text'),
|
||||
'vod_remarks': tag.get('tag_4', {}).get('text')
|
||||
})
|
||||
result['list'] = vlist
|
||||
result['page'] = pg
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
vbody = {"page_params":{"req_from":"web","cid":ids[0],"vid":"","lid":"","page_type":"detail_operation","page_id":"detail_page_introduction"},"has_cache":1}
|
||||
body = {"page_params":{"req_from":"web_vsite","page_id":"vsite_episode_list","page_type":"detail_operation","id_type":"1","page_size":"","cid":ids[0],"vid":"","lid":"","page_num":"","page_context":"","detail_page_type":"1"},"has_cache":1}
|
||||
with ThreadPoolExecutor(max_workers=2) as executor:
|
||||
future_detail = executor.submit(self.get_vdata, vbody)
|
||||
future_episodes = executor.submit(self.get_vdata, body)
|
||||
vdata = future_detail.result()
|
||||
data = future_episodes.result()
|
||||
|
||||
pdata = self.process_tabs(data, body, ids)
|
||||
if not pdata:
|
||||
return self.handle_exception(None, "No pdata available")
|
||||
|
||||
try:
|
||||
star_list = vdata['data']['module_list_datas'][0]['module_datas'][0]['item_data_lists']['item_datas'][
|
||||
0].get('sub_items', {}).get('star_list', {}).get('item_datas', [])
|
||||
actors = [star['item_params']['name'] for star in star_list]
|
||||
names = ['腾讯视频', '预告片']
|
||||
plist, ylist = self.process_pdata(pdata, ids)
|
||||
if not plist:
|
||||
del names[0]
|
||||
if not ylist:
|
||||
del names[1]
|
||||
vod = self.build_vod(vdata, actors, plist, ylist, names)
|
||||
return {'list': [vod]}
|
||||
except Exception as e:
|
||||
return self.handle_exception(e, "Error processing detail")
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
headers = self.headers.copy()
|
||||
headers.update({'Content-Type': 'application/json'})
|
||||
body = {'version':'25021101','clientType':1,'filterValue':'','uuid':str(uuid.uuid4()),'retry':0,'query':key,'pagenum':int(pg)-1,'pagesize':30,'queryFrom':0,'searchDatakey':'','transInfo':'','isneedQc':True,'preQid':'','adClientInfo':'','extraInfo':{'isNewMarkLabel':'1','multi_terminal_pc':'1','themeType':'1',},}
|
||||
data = self.post(f'{self.apihost}/trpc.videosearch.mobile_search.MultiTerminalSearch/MbSearch?vplatform=2',
|
||||
json=body, headers=headers).json()
|
||||
vlist = []
|
||||
vname=["电视剧", "电影", "综艺", "纪录片", "动漫", "少儿", "短剧"]
|
||||
v=data['data']['normalList']['itemList']
|
||||
d=data['data']['areaBoxList'][0]['itemList']
|
||||
q=v+d
|
||||
if v[0].get('doc') and v[0]['doc'].get('id') =='MainNeed':q=d+v
|
||||
for k in q:
|
||||
if k.get('doc') and k.get('videoInfo') and k['doc'].get('id') and '外站' not in k['videoInfo'].get('subTitle') and k['videoInfo'].get('title') and k['videoInfo'].get('typeName') in vname:
|
||||
img_tag = k.get('videoInfo', {}).get('imgTag')
|
||||
if img_tag is not None and isinstance(img_tag, str):
|
||||
try:
|
||||
tag = json.loads(img_tag)
|
||||
except json.JSONDecodeError as e:
|
||||
tag = {}
|
||||
else:
|
||||
tag = {}
|
||||
pic = k.get('videoInfo', {}).get('imgUrl')
|
||||
vlist.append({
|
||||
'vod_id': k['doc']['id'],
|
||||
'vod_name': self.removeHtmlTags(k['videoInfo']['title']),
|
||||
'vod_pic': pic,
|
||||
'vod_year': k['videoInfo'].get('typeName') +' '+ tag.get('tag_2', {}).get('text', ''),
|
||||
'vod_remarks': tag.get('tag_4', {}).get('text', '')
|
||||
})
|
||||
return {'list': vlist, 'page': pg}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
ids = id.split('@')
|
||||
url = f"{self.host}/x/cover/{ids[0]}/{ids[1]}.html"
|
||||
return {'jx':1,'parse': 1, 'url': url, 'header': ''}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def get_filter_data(self, cid):
|
||||
hbody = self.dbody.copy()
|
||||
hbody['page_params']['channel_id'] = cid
|
||||
data = self.post(
|
||||
f'{self.apihost}/trpc.universal_backend_service.page_server_rpc.PageServer/GetPageData?video_appid=1000005&vplatform=2&vversion_name=8.9.10&new_mark_label_enabled=1',
|
||||
json=hbody, headers=self.headers).json()
|
||||
return cid, data
|
||||
|
||||
def get_vdata(self, body):
|
||||
try:
|
||||
vdata = self.post(
|
||||
f'{self.apihost}/trpc.universal_backend_service.page_server_rpc.PageServer/GetPageData?video_appid=3000010&vplatform=2&vversion_name=8.2.96',
|
||||
json=body, headers=self.headers
|
||||
).json()
|
||||
return vdata
|
||||
except Exception as e:
|
||||
print(f"Error in get_vdata: {str(e)}")
|
||||
return {'data': {'module_list_datas': []}}
|
||||
|
||||
def process_pdata(self, pdata, ids):
|
||||
plist = []
|
||||
ylist = []
|
||||
for k in pdata:
|
||||
if k.get('item_id'):
|
||||
pid = f"{k['item_params']['union_title']}${ids[0]}@{k['item_id']}"
|
||||
if '预告' in k['item_params']['union_title']:
|
||||
ylist.append(pid)
|
||||
else:
|
||||
plist.append(pid)
|
||||
return plist, ylist
|
||||
|
||||
def build_vod(self, vdata, actors, plist, ylist, names):
|
||||
d = vdata['data']['module_list_datas'][0]['module_datas'][0]['item_data_lists']['item_datas'][0]['item_params']
|
||||
urls = []
|
||||
if plist:
|
||||
urls.append('#'.join(plist))
|
||||
if ylist:
|
||||
urls.append('#'.join(ylist))
|
||||
vod = {
|
||||
'type_name': d.get('sub_genre', ''),
|
||||
'vod_name': d.get('title', ''),
|
||||
'vod_year': d.get('year', ''),
|
||||
'vod_area': d.get('area_name', ''),
|
||||
'vod_remarks': d.get('holly_online_time', '') or d.get('hotval', ''),
|
||||
'vod_actor': ','.join(actors),
|
||||
'vod_content': d.get('cover_description', ''),
|
||||
'vod_play_from': '$$$'.join(names),
|
||||
'vod_play_url': '$$$'.join(urls)
|
||||
}
|
||||
return vod
|
||||
|
||||
def handle_exception(self, e, message):
|
||||
print(f"{message}: {str(e)}")
|
||||
return {'list': [{'vod_play_from': '哎呀翻车啦', 'vod_play_url': '翻车啦#555'}]}
|
||||
|
||||
def process_tabs(self, data, body, ids):
|
||||
try:
|
||||
pdata = data['data']['module_list_datas'][-1]['module_datas'][-1]['item_data_lists']['item_datas']
|
||||
tabs = data['data']['module_list_datas'][-1]['module_datas'][-1]['module_params'].get('tabs')
|
||||
if tabs and len(json.loads(tabs)):
|
||||
tabs = json.loads(tabs)
|
||||
remaining_tabs = tabs[1:]
|
||||
task_queue = []
|
||||
for tab in remaining_tabs:
|
||||
nbody = copy.deepcopy(body)
|
||||
nbody['page_params']['page_context'] = tab['page_context']
|
||||
task_queue.append(nbody)
|
||||
with ThreadPoolExecutor(max_workers=10) as executor:
|
||||
future_map = {executor.submit(self.get_vdata, task): idx for idx, task in enumerate(task_queue)}
|
||||
results = [None] * len(task_queue)
|
||||
for future in as_completed(future_map.keys()):
|
||||
idx = future_map[future]
|
||||
results[idx] = future.result()
|
||||
for result in results:
|
||||
if result:
|
||||
page_data = result['data']['module_list_datas'][-1]['module_datas'][-1]['item_data_lists'][
|
||||
'item_datas']
|
||||
pdata.extend(page_data)
|
||||
return pdata
|
||||
except Exception as e:
|
||||
print(f"Error processing episodes: {str(e)}")
|
||||
return []
|
||||
|
||||
def josn_to_params(self, params, skip_empty=False):
|
||||
query = []
|
||||
for k, v in params.items():
|
||||
if skip_empty and not v:
|
||||
continue
|
||||
query.append(f"{k}={v}")
|
||||
return "&".join(query)
|
||||
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import sys
|
||||
import time
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
rhost='https://www.mgtv.com'
|
||||
|
||||
host='https://pianku.api.mgtv.com'
|
||||
|
||||
vhost='https://pcweb.api.mgtv.com'
|
||||
|
||||
mhost='https://dc.bz.mgtv.com'
|
||||
|
||||
shost='https://mobileso.bz.mgtv.com'
|
||||
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Chrome/126.0.6478.61 Not/A)Brand/8 Safari/537.36',
|
||||
'origin': rhost,
|
||||
'referer': f'{rhost}/'
|
||||
}
|
||||
|
||||
def homeContent(self, filter):
|
||||
result = {}
|
||||
cateManual = {
|
||||
"电影": "3",
|
||||
"电视剧": "2",
|
||||
"综艺": "1",
|
||||
"动画": "50",
|
||||
"少儿": "10",
|
||||
"纪录片": "51",
|
||||
"教育": "115"
|
||||
}
|
||||
classes = []
|
||||
filters = {}
|
||||
for k in cateManual:
|
||||
classes.append({
|
||||
'type_name': k,
|
||||
'type_id': cateManual[k]
|
||||
})
|
||||
with ThreadPoolExecutor(max_workers=len(classes)) as executor:
|
||||
results = executor.map(self.getf, classes)
|
||||
for id, ft in results:
|
||||
if len(ft):filters[id] = ft
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
data=self.fetch(f'{self.mhost}/dynamic/v1/channel/index/0/0/0/1000000/0/0/17/1354?type=17&version=5.0&t={str(int(time.time()*1000))}&_support=10000000', headers=self.headers).json()
|
||||
videoList = []
|
||||
for i in data['data']:
|
||||
if i.get('DSLList') and len(i['DSLList']):
|
||||
for j in i['DSLList']:
|
||||
if j.get('data') and j['data'].get('items') and len(j['data']['items']):
|
||||
for k in j['data']['items']:
|
||||
videoList.append({
|
||||
'vod_id': k["videoId"],
|
||||
'vod_name': k['videoName'],
|
||||
'vod_pic': k['img'],
|
||||
'vod_year': k.get('cornerTitle'),
|
||||
'vod_remarks': k.get('time') or k.get('desc'),
|
||||
})
|
||||
return {'list':videoList}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
body={
|
||||
'allowedRC': '1',
|
||||
'platform': 'pcweb',
|
||||
'channelId': tid,
|
||||
'pn': pg,
|
||||
'pc': '80',
|
||||
'hudong': '1',
|
||||
'_support': '10000000'
|
||||
}
|
||||
body.update(extend)
|
||||
data=self.fetch(f'{self.host}/rider/list/pcweb/v3', params=body, headers=self.headers).json()
|
||||
videoList = []
|
||||
for i in data['data']['hitDocs']:
|
||||
videoList.append({
|
||||
'vod_id': i["playPartId"],
|
||||
'vod_name': i['title'],
|
||||
'vod_pic': i['img'],
|
||||
'vod_year': (i.get('rightCorner',{}) or {}).get('text') or i.get('year'),
|
||||
'vod_remarks': i['updateInfo']
|
||||
})
|
||||
result = {}
|
||||
result['list'] = videoList
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 9999
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
vbody={'allowedRC': '1', 'vid': ids[0], 'type': 'b', '_support': '10000000'}
|
||||
vdata=self.fetch(f'{self.vhost}/video/info', params=vbody, headers=self.headers).json()
|
||||
d=vdata['data']['info']['detail']
|
||||
vod = {
|
||||
'vod_name': vdata['data']['info']['title'],
|
||||
'type_name': d.get('kind'),
|
||||
'vod_year': d.get('releaseTime'),
|
||||
'vod_area': d.get('area'),
|
||||
'vod_lang': d.get('language'),
|
||||
'vod_remarks': d.get('updateInfo'),
|
||||
'vod_actor': d.get('leader'),
|
||||
'vod_director': d.get('director'),
|
||||
'vod_content': d.get('story'),
|
||||
'vod_play_from': '芒果TV',
|
||||
'vod_play_url': ''
|
||||
}
|
||||
data,pdata=self.fetch_page_data('1', ids[0],True)
|
||||
pagecount=data['data'].get('total_page') or 1
|
||||
if int(pagecount)>1:
|
||||
pages = list(range(2, pagecount+1))
|
||||
page_results = {}
|
||||
with ThreadPoolExecutor(max_workers=10) as executor:
|
||||
future_to_page = {
|
||||
executor.submit(self.fetch_page_data, page, ids[0]): page
|
||||
for page in pages
|
||||
}
|
||||
for future in as_completed(future_to_page):
|
||||
page = future_to_page[future]
|
||||
try:
|
||||
result = future.result()
|
||||
page_results[page] = result
|
||||
except Exception as e:
|
||||
print(f"Error fetching page {page}: {e}")
|
||||
for page in sorted(page_results.keys()):
|
||||
pdata.extend(page_results[page])
|
||||
vod['vod_play_url'] = '#'.join(pdata)
|
||||
return {'list':[vod]}
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
data=self.fetch(f'{self.shost}/applet/search/v1?channelCode=mobile-wxap&q={key}&pn={pg}&pc=10&_support=10000000', headers=self.headers).json()
|
||||
videoList = []
|
||||
for i in data['data']['contents']:
|
||||
if i.get('data') and len(i['data']):
|
||||
k = i['data'][0]
|
||||
if k.get('vid') and k.get('img'):
|
||||
try:
|
||||
videoList.append({
|
||||
'vod_id': k['vid'],
|
||||
'vod_name': k['title'],
|
||||
'vod_pic': k['img'],
|
||||
'vod_year': (i.get('rightTopCorner',{}) or {}).get('text') or i.get('year'),
|
||||
'vod_remarks': '/'.join(i.get('desc',[])),
|
||||
})
|
||||
except:
|
||||
print(k)
|
||||
return {'list':videoList,'page':pg}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
id=f'{self.rhost}{id}'
|
||||
return {'jx':1,'parse': 1, 'url': id, 'header': ''}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def getf(self, body):
|
||||
params = {
|
||||
'allowedRC': '1',
|
||||
'channelId': body['type_id'],
|
||||
'platform': 'pcweb',
|
||||
'_support': '10000000',
|
||||
}
|
||||
data = self.fetch(f'{self.host}/rider/config/channel/v1', params=params, headers=self.headers).json()
|
||||
ft = []
|
||||
for i in data['data']['listItems']:
|
||||
try:
|
||||
value_array = [{"n": value['tagName'], "v": value['tagId']} for value in i['items'] if
|
||||
value.get('tagName')]
|
||||
ft.append({"key": i['eName'], "name": i['typeName'], "value": value_array})
|
||||
except:
|
||||
print(i)
|
||||
return body['type_id'], ft
|
||||
|
||||
def fetch_page_data(self, page, id, b=False):
|
||||
body = {'version': '5.5.35', 'video_id': id, 'page': page, 'size': '30',
|
||||
'platform': '4', 'src': 'mgtv', 'allowedRC': '1', '_support': '10000000'}
|
||||
data = self.fetch(f'{self.vhost}/episode/list', params=body, headers=self.headers).json()
|
||||
ldata = [f'{i["t3"]}${i["url"]}' for i in data['data']['list']]
|
||||
if b:
|
||||
return data, ldata
|
||||
else:
|
||||
return ldata
|
|
@ -0,0 +1,225 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import json
|
||||
import sys
|
||||
import threading
|
||||
import uuid
|
||||
import requests
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
import time
|
||||
from Crypto.Hash import MD5, SHA1
|
||||
|
||||
class Spider(Spider):
|
||||
'''
|
||||
配置示例:
|
||||
{
|
||||
"key": "xxxx",
|
||||
"name": "xxxx",
|
||||
"type": 3,
|
||||
"api": ".所在路径/金牌.py",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": {
|
||||
"site": "https://www.jiabaide.cn,域名2,域名3"
|
||||
}
|
||||
},
|
||||
'''
|
||||
def init(self, extend=""):
|
||||
if extend:
|
||||
hosts=json.loads(extend)['site']
|
||||
self.host = self.host_late(hosts)
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
def homeContent(self, filter):
|
||||
cdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/get/filer/type", headers=self.getheaders()).json()
|
||||
fdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/get/filer/list", headers=self.getheaders()).json()
|
||||
result = {}
|
||||
classes = []
|
||||
filters={}
|
||||
for k in cdata['data']:
|
||||
classes.append({
|
||||
'type_name': k['typeName'],
|
||||
'type_id': str(k['typeId']),
|
||||
})
|
||||
sort_values = [{"n": "最近更新", "v": "2"},{"n": "人气高低", "v": "3"}, {"n": "评分高低", "v": "4"}]
|
||||
for tid, d in fdata['data'].items():
|
||||
current_sort_values = sort_values.copy()
|
||||
if tid == '1':
|
||||
del current_sort_values[0]
|
||||
filters[tid] = [
|
||||
{"key": "type", "name": "类型",
|
||||
"value": [{"n": i["itemText"], "v": i["itemValue"]} for i in d["typeList"]]},
|
||||
|
||||
*([] if not d["plotList"] else [{"key": "v_class", "name": "剧情",
|
||||
"value": [{"n": i["itemText"], "v": i["itemText"]}
|
||||
for i in d["plotList"]]}]),
|
||||
|
||||
{"key": "area", "name": "地区",
|
||||
"value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["districtList"]]},
|
||||
|
||||
{"key": "year", "name": "年份",
|
||||
"value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["yearList"]]},
|
||||
|
||||
{"key": "lang", "name": "语言",
|
||||
"value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["languageList"]]},
|
||||
|
||||
{"key": "sort", "name": "排序", "value": current_sort_values}
|
||||
]
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
data1 = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/home/all/list", headers=self.getheaders()).json()
|
||||
data2=self.fetch(f"{self.host}/api/mw-movie/anonymous/home/hotSearch",headers=self.getheaders()).json()
|
||||
data=[]
|
||||
for i in data1['data'].values():
|
||||
data.extend(i['list'])
|
||||
data.extend(data2['data'])
|
||||
vods=self.getvod(data)
|
||||
return {'list':vods}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
|
||||
params = {
|
||||
"area": extend.get('area', ''),
|
||||
"filterStatus": "1",
|
||||
"lang": extend.get('lang', ''),
|
||||
"pageNum": pg,
|
||||
"pageSize": "30",
|
||||
"sort": extend.get('sort', '1'),
|
||||
"sortBy": "1",
|
||||
"type": extend.get('type', ''),
|
||||
"type1": tid,
|
||||
"v_class": extend.get('v_class', ''),
|
||||
"year": extend.get('year', '')
|
||||
}
|
||||
data = self.fetch(f"{self.host}/api/mw-movie/anonymous/video/list?{self.js(params)}", headers=self.getheaders(params)).json()
|
||||
result = {}
|
||||
result['list'] = self.getvod(data['data']['list'])
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 9999
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/detail?id={ids[0]}",headers=self.getheaders({'id':ids[0]})).json()
|
||||
vod=self.getvod([data['data']])[0]
|
||||
vod['vod_play_from']='金牌'
|
||||
vod['vod_play_url'] = '#'.join(
|
||||
f"{i['name'] if len(vod['episodelist']) > 1 else vod['vod_name']}${ids[0]}@@{i['nid']}" for i in
|
||||
vod['episodelist'])
|
||||
vod.pop('episodelist', None)
|
||||
return {'list':[vod]}
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
params = {
|
||||
"keyword": key,
|
||||
"pageNum": pg,
|
||||
"pageSize": "8",
|
||||
"sourceCode": "1"
|
||||
}
|
||||
data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/searchByWord?{self.js(params)}",headers=self.getheaders(params)).json()
|
||||
vods=self.getvod(data['data']['result']['list'])
|
||||
return {'list':vods,'page':pg}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
self.header = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Chrome/126.0.6478.61 Not/A)Brand/8 Safari/537.36',
|
||||
'sec-ch-ua-platform': '"Windows"',
|
||||
'DNT': '1',
|
||||
'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'Origin': self.host,
|
||||
'Referer': f'{self.host}/'
|
||||
}
|
||||
ids=id.split('@@')
|
||||
pdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v2/video/episode/url?clientType=1&id={ids[0]}&nid={ids[1]}",headers=self.getheaders({'clientType':'1','id': ids[0], 'nid': ids[1]})).json()
|
||||
vlist=[]
|
||||
for i in pdata['data']['list']:vlist.extend([i['resolutionName'],i['url']])
|
||||
return {'parse':0,'url':vlist,'header':self.header}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def host_late(self, url_list):
|
||||
if isinstance(url_list, str):
|
||||
urls = [u.strip() for u in url_list.split(',')]
|
||||
else:
|
||||
urls = url_list
|
||||
if len(urls) <= 1:
|
||||
return urls[0] if urls else ''
|
||||
|
||||
results = {}
|
||||
threads = []
|
||||
|
||||
def test_host(url):
|
||||
try:
|
||||
start_time = time.time()
|
||||
response = requests.head(url, timeout=1.0, allow_redirects=False)
|
||||
delay = (time.time() - start_time) * 1000
|
||||
results[url] = delay
|
||||
except Exception as e:
|
||||
results[url] = float('inf')
|
||||
for url in urls:
|
||||
t = threading.Thread(target=test_host, args=(url,))
|
||||
threads.append(t)
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
return min(results.items(), key=lambda x: x[1])[0]
|
||||
|
||||
def md5(self, sign_key):
|
||||
md5_hash = MD5.new()
|
||||
md5_hash.update(sign_key.encode('utf-8'))
|
||||
md5_result = md5_hash.hexdigest()
|
||||
return md5_result
|
||||
|
||||
def js(self, param):
|
||||
return '&'.join(f"{k}={v}" for k, v in param.items())
|
||||
|
||||
def getheaders(self, param=None):
|
||||
if param is None:param = {}
|
||||
t=str(int(time.time()*1000))
|
||||
param['key']='cb808529bae6b6be45ecfab29a4889bc'
|
||||
param['t']=t
|
||||
sha1_hash = SHA1.new()
|
||||
sha1_hash.update(self.md5(self.js(param)).encode('utf-8'))
|
||||
sign = sha1_hash.hexdigest()
|
||||
deviceid = str(uuid.uuid4())
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Chrome/126.0.6478.61 Not/A)Brand/8 Safari/537.36',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'sign': sign,
|
||||
't': t,
|
||||
'deviceid':deviceid
|
||||
}
|
||||
return headers
|
||||
|
||||
def convert_field_name(self, field):
|
||||
field = field.lower()
|
||||
if field.startswith('vod') and len(field) > 3:
|
||||
field = field.replace('vod', 'vod_')
|
||||
if field.startswith('type') and len(field) > 4:
|
||||
field = field.replace('type', 'type_')
|
||||
return field
|
||||
|
||||
def getvod(self, array):
|
||||
return [{self.convert_field_name(k): v for k, v in item.items()} for item in array]
|
||||
|
BIN
潇洒/spider.jar
BIN
潇洒/spider.jar
Binary file not shown.
100
王二小/api.json
100
王二小/api.json
|
@ -628,6 +628,70 @@
|
|||
"json": "./txt/bilisong.txt"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "少儿教育",
|
||||
"name": "📚少儿┃教育📚",
|
||||
"type": 3,
|
||||
"api": "csp_BiliGuard",
|
||||
"style": {
|
||||
"type": "rect",
|
||||
"ratio": 1.597
|
||||
},
|
||||
"searchable": 0,
|
||||
"quickSearch": 0,
|
||||
"changeable": 0,
|
||||
"ext": {
|
||||
"json": "https://im.feelec.com.cn/res/file.html?id=2c9a91099584ed4901963ec8251e772b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "小学课堂",
|
||||
"name": "📚小学┃课堂📚",
|
||||
"type": 3,
|
||||
"api": "csp_BiliGuard",
|
||||
"style": {
|
||||
"type": "rect",
|
||||
"ratio": 1.597
|
||||
},
|
||||
"searchable": 0,
|
||||
"quickSearch": 0,
|
||||
"changeable": 0,
|
||||
"ext": {
|
||||
"json": "https://im.feelec.com.cn/res/file.html?id=2c9a91099584ed4901963ec82537772c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "初中课堂",
|
||||
"name": "📚初中┃课堂📚",
|
||||
"type": 3,
|
||||
"api": "csp_BiliGuard",
|
||||
"style": {
|
||||
"type": "rect",
|
||||
"ratio": 1.597
|
||||
},
|
||||
"searchable": 0,
|
||||
"quickSearch": 0,
|
||||
"changeable": 0,
|
||||
"ext": {
|
||||
"json": "https://im.feelec.com.cn/res/file.html?id=2c9a91099584ed4901963ec824cc7729"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "高中教育",
|
||||
"name": "📚高中┃课堂📚",
|
||||
"type": 3,
|
||||
"api": "csp_BiliGuard",
|
||||
"style": {
|
||||
"type": "rect",
|
||||
"ratio": 1.597
|
||||
},
|
||||
"searchable": 0,
|
||||
"quickSearch": 0,
|
||||
"changeable": 0,
|
||||
"ext": {
|
||||
"json": "https://im.feelec.com.cn/res/file.html?id=2c9a91099584ed4901963ec824fd772a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "Wexqingfengdj",
|
||||
"name": "🎼舞曲┃摇头🎼",
|
||||
|
@ -693,38 +757,6 @@
|
|||
"type": "list"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "Wexmiso",
|
||||
"name": "🎠米搜┃综合🎠",
|
||||
"type": 3,
|
||||
"api": "csp_WexmisoGuard",
|
||||
"searchable": 1,
|
||||
"changeable": 0
|
||||
},
|
||||
{
|
||||
"key": "Wexed3000",
|
||||
"name": "🎠易迪┃综合🎠",
|
||||
"type": 3,
|
||||
"api": "csp_Wexed3000Guard",
|
||||
"searchable": 1,
|
||||
"changeable": 0
|
||||
},
|
||||
{
|
||||
"key": "易搜",
|
||||
"name": "🎠易搜┃综合🎠",
|
||||
"type": 3,
|
||||
"api": "csp_YiSoGuard",
|
||||
"searchable": 1,
|
||||
"changeable": 0
|
||||
},
|
||||
{
|
||||
"key": "Wexyingso",
|
||||
"name": "🎠影子┃综合🎠",
|
||||
"type": 3,
|
||||
"api": "csp_WexyingsoGuard",
|
||||
"searchable": 1,
|
||||
"changeable": 0
|
||||
},
|
||||
{
|
||||
"key": "WexTJso",
|
||||
"name": "🎠TJ┃综合🎠",
|
||||
|
@ -1027,13 +1059,13 @@
|
|||
"name": "BJTV",
|
||||
"type": 0,
|
||||
"url": "./lives/BJTV.txt",
|
||||
"epg": ""
|
||||
"playerType":1
|
||||
},
|
||||
{
|
||||
"name": "钵钵鸡(四网通用)",
|
||||
"type": 0,
|
||||
"url": "./lives/钵钵鸡(四网通用).txt",
|
||||
"epg": ""
|
||||
"playerType":1
|
||||
}
|
||||
]
|
||||
}
|
BIN
王二小/spider.jar
BIN
王二小/spider.jar
Binary file not shown.
12
肥猫/api.json
12
肥猫/api.json
|
@ -145,10 +145,10 @@
|
|||
"ext": "https://www.wwgz.cn"
|
||||
},
|
||||
{
|
||||
"key": "csp_Apphip",
|
||||
"name": "🌼┃️嗨皮┃影视",
|
||||
"key": "csp_KmeiJu",
|
||||
"name": "🍐┃鸭梨┃影视",
|
||||
"type": 3,
|
||||
"api": "csp_Apphip"
|
||||
"api": "csp_KmeiJu"
|
||||
},
|
||||
{
|
||||
"key": "csp_Siren",
|
||||
|
@ -175,6 +175,12 @@
|
|||
"api": "csp_Qiyou",
|
||||
"ext": "http://www.dyxz2.com/"
|
||||
},
|
||||
{
|
||||
"key": "csp_Apphip",
|
||||
"name": "🌼┃️嗨皮┃影视",
|
||||
"type": 3,
|
||||
"api": "csp_Apphip"
|
||||
},
|
||||
{
|
||||
"key": "荐片",
|
||||
"name": "🎬┃荐片┃影视",
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<html>
|
||||
<head><title>403 Forbidden</title></head>
|
||||
<body>
|
||||
<center><h1>403 Forbidden</h1></center>
|
||||
<hr><center>nginx</center>
|
||||
</body>
|
||||
</html>
|
2655
肥猫/json/初中课堂.json
2655
肥猫/json/初中课堂.json
File diff suppressed because it is too large
Load Diff
1960
肥猫/lives/live.txt
1960
肥猫/lives/live.txt
File diff suppressed because it is too large
Load Diff
BIN
肥猫/spider.jar
BIN
肥猫/spider.jar
Binary file not shown.
13
饭太硬/api.json
13
饭太硬/api.json
|
@ -681,25 +681,30 @@
|
|||
"name": "牛播一(仅新版影视仓┃ok影视)",
|
||||
"type": 0,
|
||||
"url": "http://127.0.0.1:9978/proxy?do=饭太硬&type=liveList",
|
||||
"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}"
|
||||
"playerType":2,
|
||||
"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}",
|
||||
"logo":"https://epg.v1.mk/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "V4聚合(卡顿请按左┃右键换线)",
|
||||
"type": 0,
|
||||
"url": "./lives/V4聚合(卡顿请按左┃右键换线).txt",
|
||||
"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}"
|
||||
"playerType":2,
|
||||
"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}",
|
||||
"logo":"https://epg.v1.mk/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "V6范明明",
|
||||
"type": 0,
|
||||
"url": "./lives/V6范明明.txt",
|
||||
"epg": ""
|
||||
"playerType":2
|
||||
},
|
||||
{
|
||||
"name": "平台直播",
|
||||
"type": 0,
|
||||
"url": "./lives/平台直播.txt",
|
||||
"epg": ""
|
||||
"ua":"okhttp/3.15",
|
||||
"playerType":2
|
||||
}
|
||||
]
|
||||
}
|
4068
饭太硬/lives/平台直播.txt
4068
饭太硬/lives/平台直播.txt
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue