py_1712024cntv.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #coding=utf-8
  2. #!/usr/bin/python
  3. import re
  4. import sys
  5. import time
  6. import json
  7. from urllib.parse import quote
  8. sys.path.append('..')
  9. from base.spider import Spider
  10. class Spider(Spider): # 元类 默认的元类 type
  11. def getName(self):
  12. return "中央电视台"
  13. def init(self, extend):
  14. pass
  15. def destroy(self):
  16. pass
  17. def isVideoFormat(self, url):
  18. pass
  19. def manualVideoCheck(self):
  20. pass
  21. def homeContent(self, filter):
  22. result = {}
  23. cateManual = {
  24. "栏目大全": "栏目大全",
  25. "特别节目": "特别节目"
  26. }
  27. classes = []
  28. for k in cateManual:
  29. classes.append({
  30. 'type_name': k,
  31. 'type_id': cateManual[k]
  32. })
  33. result['class'] = classes
  34. if filter:
  35. import datetime
  36. result['filters'] = self.config['filter']
  37. currentYear = datetime.datetime.now().year
  38. yearList = [{"n": "全部", "v": ""}]
  39. for year in range(currentYear, currentYear - 10, -1):
  40. yearList.append({"n": year, "v": year})
  41. for classe in classes:
  42. if classe['type_id'] == '栏目大全':
  43. key = 'year'
  44. elif classe['type_id'] == '特别节目':
  45. key = 'datanf-year'
  46. else:
  47. key = 'year'
  48. yearDict = {"key": key, "name": "年份", "value": yearList}
  49. if yearDict not in result['filters'][classe['type_id']]:
  50. result['filters'][classe['type_id']].append(yearDict)
  51. return result
  52. def homeVideoContent(self):
  53. result = {
  54. 'list': []
  55. }
  56. return result
  57. def categoryContent(self, cid, page, filter, ext):
  58. result = {}
  59. params = {
  60. 'n': '20',
  61. 'p': page,
  62. 't': 'json',
  63. 'serviceId': 'tvcctv'
  64. }
  65. year = ''
  66. month = ''
  67. for key in ext.keys():
  68. if key == 'year':
  69. year = ext['year']
  70. elif key == 'month':
  71. month = ext['month']
  72. else:
  73. params[key] = ext[key]
  74. if year == '':
  75. date = ''
  76. else:
  77. date = year + month
  78. if cid == '栏目大全':
  79. url = 'https://api.cntv.cn/lanmu/columnSearch?'
  80. for key in params:
  81. url += f'{key}={params[key]}&'
  82. url = url.strip('&')
  83. data = self.fetch(url, headers=self.header, timeout=10).json()
  84. vodList = data['response']['docs']
  85. videos = []
  86. for vod in vodList:
  87. lastVideo = vod['lastVIDE']['videoSharedCode']
  88. if len(lastVideo) == 0:
  89. lastVideo = '_'
  90. guid = json.dumps({'cid': '栏目大全', 'date': date, 'title': vod['column_name'], 'lastVideo': lastVideo, 'logo': vod['column_logo']}, ensure_ascii=False)
  91. title = vod['column_name']
  92. img = vod['column_logo']
  93. videos.append({
  94. "vod_id": guid,
  95. "vod_name": title,
  96. "vod_pic": img,
  97. "vod_remarks": ''
  98. })
  99. lenvodList = len(vodList)
  100. page = int(page)
  101. if lenvodList * page < data['response']['numFound']:
  102. pagecount = page + 1
  103. else:
  104. pagecount = page
  105. elif cid == '特别节目':
  106. url = f'https://api.cntv.cn/list/getVideoAlbumList?channelid=CHAL1460955953877151&fc={quote(cid)}&'
  107. for key in params:
  108. if key.startswith('data'):
  109. keyName = key.split('-')[1]
  110. else:
  111. keyName = key
  112. url += f'{keyName}={quote(params[key])}&'
  113. url = url.strip('&')
  114. data = self.fetch(url, headers=self.header, timeout=10).json()
  115. vodList = data['data']['list']
  116. videos = []
  117. for vod in vodList:
  118. guid = json.dumps({'cid': '特别节目', 'date': date, 'title': vod['title'], 'vid': vod['id'], 'logo': vod['image'], 'content': vod['brief']}, ensure_ascii=False)
  119. title = vod['title']
  120. img = vod['image']
  121. videos.append({
  122. "vod_id": guid,
  123. "vod_name": title,
  124. "vod_pic": img,
  125. "vod_remarks": ''
  126. })
  127. lenvodList = len(vodList)
  128. page = int(page)
  129. if lenvodList * page < data['data']['total']:
  130. pagecount = page + 1
  131. else:
  132. pagecount = page
  133. else:
  134. videos = []
  135. lenvodList = 0
  136. pagecount = page
  137. result['list'] = videos
  138. result['page'] = page
  139. result['pagecount'] = pagecount
  140. result['limit'] = lenvodList
  141. result['total'] = lenvodList
  142. return result
  143. def detailContent(self, did):
  144. videoList = []
  145. params = json.loads(did[0])
  146. cid = params['cid']
  147. date = params['date']
  148. if date == '':
  149. content = '仅展示近100期节目,其余节目通过筛选访问\n'
  150. else:
  151. content = ''
  152. if cid == '栏目大全':
  153. title = params['title']
  154. logo = params['logo']
  155. lastVideo = params['lastVideo']
  156. if lastVideo == '_':
  157. return {}
  158. url = f"https://api.cntv.cn/video/videoinfoByGuid?serviceId=tvcctv&guid={lastVideo}"
  159. data = self.fetch(url, headers=self.header, timeout=10).json()
  160. topicId = data['ctid']
  161. content = content + data['vset_brief']
  162. url = f"https://api.cntv.cn/NewVideo/getVideoListByColumn?n=100&t=json&mode=0&sort=desc&serviceId=tvcctv&d={date}&id={topicId}"
  163. data = self.fetch(url, headers=self.header, timeout=10).json()
  164. vodList = data['data']['list']
  165. for video in vodList:
  166. videoList.append(video['title'] + "$" + video['guid'])
  167. for video in vodList:
  168. videoList.append(video['title'] + "$" + video['guid'])
  169. elif cid == '特别节目':
  170. title = params['title']
  171. logo = params['logo']
  172. content += params['content']
  173. url = f'https://api.cntv.cn/NewVideo/getVideoListByAlbumIdNew?id={params["vid"]}&serviceId=tvcctv&p=1&n=100&mode=0&pub=1'
  174. r = self.fetch(url, headers=self.header, timeout=10)
  175. data = r.json()
  176. vodList = data['data']['list']
  177. if len(vodList) == 0:
  178. vodList = re.finditer(r'href="(?P<guid>.+?)" target="_blank" alt="(?P<title>.+?)" title=".+?">', r.text, re.M | re.S)
  179. for video in vodList:
  180. try:
  181. name = video['title']
  182. guid = video['guid']
  183. except:
  184. name = video.group('title')
  185. guid = video.group('guid')
  186. if len(guid) == 0:
  187. continue
  188. videoList.append(name + "$" + guid)
  189. if len(videoList) == 0:
  190. return {}
  191. if len(date) == 0:
  192. date = time.strftime("%Y", time.localtime(time.time()))
  193. else:
  194. title = ''
  195. logo = ''
  196. vod = {"vod_id": did[0], "vod_name": date + " " + title, "vod_pic": logo, "vod_year": date, "vod_remarks": date, "vod_content": content}
  197. vod['vod_play_from'] = 'CCTV'
  198. vod['vod_play_url'] = "#".join(videoList)
  199. result = {'list': [vod]}
  200. return result
  201. def searchContent(self, key, quick):
  202. return self.searchContentPage(key, quick, '1')
  203. def searchContentPage(self, key, quick, page):
  204. result = {}
  205. return result
  206. def playerContent(self, flag, pid, vipFlags):
  207. result = {}
  208. url = f"https://vdn.apps.cntv.cn/api/getHttpVideoInfo.do?pid={pid}"
  209. data = self.fetch(url, headers=self.header, timeout=10).json()
  210. url = data['hls_url'].strip()
  211. result["parse"] = 0
  212. result["playUrl"] = ''
  213. result["url"] = url
  214. result["header"] = ''
  215. return result
  216. config = {"filter": {"栏目大全": [{"key": "cid", "name": "频道", "value": [{"n": "全部", "v": ""}, {"n": "CCTV-1综合", "v": "EPGC1386744804340101"}, {"n": "CCTV-2财经", "v": "EPGC1386744804340102"}, {"n": "CCTV-3综艺", "v": "EPGC1386744804340103"}, {"n": "CCTV-4中文国际", "v": "EPGC1386744804340104"}, {"n": "CCTV-5体育", "v": "EPGC1386744804340107"}, {"n": "CCTV-6电影", "v": "EPGC1386744804340108"}, {"n": "CCTV-7国防军事", "v": "EPGC1386744804340109"}, {"n": "CCTV-8电视剧", "v": "EPGC1386744804340110"}, {"n": "CCTV-9纪录", "v": "EPGC1386744804340112"}, {"n": "CCTV-10科教", "v": "EPGC1386744804340113"}, {"n": "CCTV-11戏曲", "v": "EPGC1386744804340114"}, {"n": "CCTV-12社会与法", "v": "EPGC1386744804340115"}, {"n": "CCTV-13新闻", "v": "EPGC1386744804340116"}, {"n": "CCTV-14少儿", "v": "EPGC1386744804340117"}, {"n": "CCTV-15音乐", "v": "EPGC1386744804340118"}, {"n": "CCTV-16奥林匹克", "v": "EPGC1634630207058998"}, {"n": "CCTV-17农业农村", "v": "EPGC1563932742616872"}, {"n": "CCTV-5+体育赛事", "v": "EPGC1468294755566101"}]}, {"key": "fc", "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": "fl", "name": "字母", "value": [{"n": "全部", "v": ""}, {"n": "A", "v": "A"}, {"n": "B", "v": "B"}, {"n": "C", "v": "C"}, {"n": "D", "v": "D"}, {"n": "E", "v": "E"}, {"n": "F", "v": "F"}, {"n": "G", "v": "G"}, {"n": "H", "v": "H"}, {"n": "I", "v": "I"}, {"n": "J", "v": "J"}, {"n": "K", "v": "K"}, {"n": "L", "v": "L"}, {"n": "M", "v": "M"}, {"n": "N", "v": "N"}, {"n": "O", "v": "O"}, {"n": "P", "v": "P"}, {"n": "Q", "v": "Q"}, {"n": "R", "v": "R"}, {"n": "S", "v": "S"}, {"n": "T", "v": "T"}, {"n": "U", "v": "U"}, {"n": "V", "v": "V"}, {"n": "W", "v": "W"}, {"n": "X", "v": "X"}, {"n": "Y", "v": "Y"}, {"n": "Z", "v": "Z"}]}, {"key": "month", "name": "月份", "value": [{"n": "全部", "v": ""}, {"n": "12", "v": "12"}, {"n": "11", "v": "11"}, {"n": "10", "v": "10"}, {"n": "09", "v": "09"}, {"n": "08", "v": "08"}, {"n": "07", "v": "07"}, {"n": "06", "v": "06"}, {"n": "05", "v": "05"}, {"n": "04", "v": "04"}, {"n": "03", "v": "03"}, {"n": "02", "v": "02"}, {"n": "01", "v": "01"}]}], "特别节目": [{"key": "datapd-channel", "name": "频道", "value": [{"n": "全部", "v": ""}, {"n": "CCTV-1 综合", "v": "CCTV-1综合,CCTV-1高清,CCTV-1综合高清"}, {"n": "CCTV-2 财经", "v": "CCTV-2财经,CCTV-2高清,CCTV-2财经高清"}, {"n": "CCTV-3 综艺", "v": "CCTV-3综艺,CCTV-3高清,CCTV-3综艺高清"}, {"n": "CCTV-4 中文国际", "v": "CCTV-4中文国际,CCTV-4高清,CCTV-4中文国际(亚)高清"}, {"n": "CCTV-5 体育", "v": "CCTV-5体育,CCTV-5高清,CCTV-5体育高清"}, {"n": "CCTV-6 电影", "v": "CCTV-6电影,CCTV-6高清,CCTV-6电影高清"}, {"n": "CCTV-7 国防军事", "v": "CCTV-7军事农业,CCTV-7高清,CCTV-7军事农业高清,CCTV-7国防军事高清"}, {"n": "CCTV-8 电视剧", "v": "CCTV-8电视剧,CCTV-8高清,CCTV-8电视剧高清"}, {"n": "CCTV-9 纪录", "v": "CCTV-9纪录,CCTV-9高清,CCTV-9纪录高清"}, {"n": "CCTV-10 科教", "v": "CCTV-10科教,CCTV-10高清,CCTV-10科教高清"}, {"n": "CCTV-11 戏曲", "v": "CCTV-11戏曲,CCTV-11高清,CCTV-11戏曲高清"}, {"n": "CCTV-12 社会与法", "v": "CCTV-12社会与法,CCTV-12高清,CCTV-12社会与法高清"}, {"n": "CCTV-13 新闻", "v": "CCTV-13新闻,CCTV-13高清,CCTV-13新闻高清"}, {"n": "CCTV-14 少儿", "v": "CCTV-14少儿,CCTV-14高清,CCTV-14少儿高清"}, {"n": "CCTV-15 音乐", "v": "CCTV-15音乐,CCTV-15高清,CCTV-15音乐高清"}, {"n": "CCTV-17 农业农村", "v": "CCTV-17农业农村高清"}]}, {"key": "datafl-sc", "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": "dataszm-letter", "name": "首字母", "value": [{"n": "全部", "v": ""}, {"n": "A", "v": "A"}, {"n": "B", "v": "B"}, {"n": "C", "v": "C"}, {"n": "D", "v": "D"}, {"n": "E", "v": "E"}, {"n": "F", "v": "F"}, {"n": "G", "v": "G"}, {"n": "H", "v": "H"}, {"n": "I", "v": "I"}, {"n": "J", "v": "J"}, {"n": "K", "v": "K"}, {"n": "L", "v": "L"}, {"n": "M", "v": "M"}, {"n": "N", "v": "N"}, {"n": "O", "v": "O"}, {"n": "P", "v": "P"}, {"n": "Q", "v": "Q"}, {"n": "R", "v": "R"}, {"n": "S", "v": "S"}, {"n": "T", "v": "T"}, {"n": "U", "v": "U"}, {"n": "V", "v": "V"}, {"n": "W", "v": "W"}, {"n": "X", "v": "X"}, {"n": "Y", "v": "Y"}, {"n": "Z", "v": "Z"}]}]}}
  217. header = {
  218. "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36",
  219. "Origin": "https://tv.cctv.com",
  220. "Referer": "https://tv.cctv.com/"
  221. }
  222. def localProxy(self, param):
  223. return [200, "video/MP2T", ""]