金牌.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. # -*- coding: utf-8 -*-
  2. # by @嗷呜
  3. import json
  4. import sys
  5. import threading
  6. import uuid
  7. import requests
  8. sys.path.append('..')
  9. from base.spider import Spider
  10. import time
  11. from Crypto.Hash import MD5, SHA1
  12. class Spider(Spider):
  13. def init(self, extend=""):
  14. if extend:
  15. hosts=json.loads(extend)['site']
  16. self.host = self.host_late(hosts)
  17. pass
  18. def getName(self):
  19. pass
  20. def isVideoFormat(self, url):
  21. pass
  22. def manualVideoCheck(self):
  23. pass
  24. def destroy(self):
  25. pass
  26. def homeContent(self, filter):
  27. cdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/get/filer/type", headers=self.getheaders()).json()
  28. fdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/get/filer/list", headers=self.getheaders()).json()
  29. result = {}
  30. classes = []
  31. filters={}
  32. for k in cdata['data']:
  33. classes.append({
  34. 'type_name': k['typeName'],
  35. 'type_id': str(k['typeId']),
  36. })
  37. sort_values = [{"n": "最近更新", "v": "2"},{"n": "人气高低", "v": "3"}, {"n": "评分高低", "v": "4"}]
  38. for tid, d in fdata['data'].items():
  39. current_sort_values = sort_values.copy()
  40. if tid == '1':
  41. del current_sort_values[0]
  42. filters[tid] = [
  43. {"key": "type", "name": "类型",
  44. "value": [{"n": i["itemText"], "v": i["itemValue"]} for i in d["typeList"]]},
  45. *([] if not d["plotList"] else [{"key": "v_class", "name": "剧情",
  46. "value": [{"n": i["itemText"], "v": i["itemText"]}
  47. for i in d["plotList"]]}]),
  48. {"key": "area", "name": "地区",
  49. "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["districtList"]]},
  50. {"key": "year", "name": "年份",
  51. "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["yearList"]]},
  52. {"key": "lang", "name": "语言",
  53. "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["languageList"]]},
  54. {"key": "sort", "name": "排序", "value": current_sort_values}
  55. ]
  56. result['class'] = classes
  57. result['filters'] = filters
  58. return result
  59. def homeVideoContent(self):
  60. data1 = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/home/all/list", headers=self.getheaders()).json()
  61. data2=self.fetch(f"{self.host}/api/mw-movie/anonymous/home/hotSearch",headers=self.getheaders()).json()
  62. data=[]
  63. for i in data1['data'].values():
  64. data.extend(i['list'])
  65. data.extend(data2['data'])
  66. vods=self.getvod(data)
  67. return {'list':vods}
  68. def categoryContent(self, tid, pg, filter, extend):
  69. params = {
  70. "area": extend.get('area', ''),
  71. "filterStatus": "1",
  72. "lang": extend.get('lang', ''),
  73. "pageNum": pg,
  74. "pageSize": "30",
  75. "sort": extend.get('sort', '1'),
  76. "sortBy": "1",
  77. "type": extend.get('type', ''),
  78. "type1": tid,
  79. "v_class": extend.get('v_class', ''),
  80. "year": extend.get('year', '')
  81. }
  82. data = self.fetch(f"{self.host}/api/mw-movie/anonymous/video/list?{self.js(params)}", headers=self.getheaders(params)).json()
  83. result = {}
  84. result['list'] = self.getvod(data['data']['list'])
  85. result['page'] = pg
  86. result['pagecount'] = 9999
  87. result['limit'] = 90
  88. result['total'] = 999999
  89. return result
  90. def detailContent(self, ids):
  91. data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/detail?id={ids[0]}",headers=self.getheaders({'id':ids[0]})).json()
  92. vod=self.getvod([data['data']])[0]
  93. vod['vod_play_from']='嗷呜有金牌'
  94. vod['vod_play_url'] = '#'.join(
  95. f"{i['name'] if len(vod['episodelist']) > 1 else vod['vod_name']}${ids[0]}@@{i['nid']}" for i in
  96. vod['episodelist'])
  97. vod.pop('episodelist', None)
  98. return {'list':[vod]}
  99. def searchContent(self, key, quick, pg="1"):
  100. params = {
  101. "keyword": key,
  102. "pageNum": pg,
  103. "pageSize": "8",
  104. "sourceCode": "1"
  105. }
  106. data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/searchByWord?{self.js(params)}",headers=self.getheaders(params)).json()
  107. vods=self.getvod(data['data']['result']['list'])
  108. return {'list':vods,'page':pg}
  109. def playerContent(self, flag, id, vipFlags):
  110. self.header = {
  111. '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',
  112. 'sec-ch-ua-platform': '"Windows"',
  113. 'DNT': '1',
  114. 'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
  115. 'sec-ch-ua-mobile': '?0',
  116. 'Origin': self.host,
  117. 'Referer': f'{self.host}/'
  118. }
  119. ids=id.split('@@')
  120. 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()
  121. vlist=[]
  122. for i in pdata['data']['list']:vlist.extend([i['resolutionName'],i['url']])
  123. return {'parse':0,'url':vlist,'header':self.header}
  124. def localProxy(self, param):
  125. pass
  126. def host_late(self, url_list):
  127. if isinstance(url_list, str):
  128. urls = [u.strip() for u in url_list.split(',')]
  129. else:
  130. urls = url_list
  131. if len(urls) <= 1:
  132. return urls[0] if urls else ''
  133. results = {}
  134. threads = []
  135. def test_host(url):
  136. try:
  137. start_time = time.time()
  138. response = requests.head(url, timeout=1.0, allow_redirects=False)
  139. delay = (time.time() - start_time) * 1000
  140. results[url] = delay
  141. except Exception as e:
  142. results[url] = float('inf')
  143. for url in urls:
  144. t = threading.Thread(target=test_host, args=(url,))
  145. threads.append(t)
  146. t.start()
  147. for t in threads:
  148. t.join()
  149. return min(results.items(), key=lambda x: x[1])[0]
  150. def md5(self, sign_key):
  151. md5_hash = MD5.new()
  152. md5_hash.update(sign_key.encode('utf-8'))
  153. md5_result = md5_hash.hexdigest()
  154. return md5_result
  155. def js(self, param):
  156. return '&'.join(f"{k}={v}" for k, v in param.items())
  157. def getheaders(self, param=None):
  158. if param is None:param = {}
  159. t=str(int(time.time()*1000))
  160. param['key']='cb808529bae6b6be45ecfab29a4889bc'
  161. param['t']=t
  162. sha1_hash = SHA1.new()
  163. sha1_hash.update(self.md5(self.js(param)).encode('utf-8'))
  164. sign = sha1_hash.hexdigest()
  165. deviceid = str(uuid.uuid4())
  166. headers = {
  167. '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',
  168. 'Accept': 'application/json, text/plain, */*',
  169. 'sign': sign,
  170. 't': t,
  171. 'deviceid':deviceid
  172. }
  173. return headers
  174. def convert_field_name(self, field):
  175. field = field.lower()
  176. if field.startswith('vod') and len(field) > 3:
  177. field = field.replace('vod', 'vod_')
  178. if field.startswith('type') and len(field) > 4:
  179. field = field.replace('type', 'type_')
  180. return field
  181. def getvod(self, array):
  182. return [{self.convert_field_name(k): v for k, v in item.items()} for item in array]