sj.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. # coding=utf-8
  2. # !/usr/bin/python
  3. # by嗷呜
  4. import sys
  5. sys.path.append("..")
  6. import re
  7. import os
  8. from Crypto.Cipher import AES
  9. from Crypto.Util.Padding import pad, unpad
  10. from base64 import b64encode, b64decode
  11. import json
  12. from base.spider import Spider
  13. from urllib.parse import quote
  14. class Spider(Spider):
  15. def getName(self):
  16. return "视觉"
  17. def init(self, extend=""):
  18. self.host = self.host()
  19. pass
  20. def isVideoFormat(self, url):
  21. pass
  22. def manualVideoCheck(self):
  23. pass
  24. def action(self, action):
  25. pass
  26. def destroy(self):
  27. pass
  28. def homeContent(self, filter):
  29. data = self.fetch(
  30. f"{self.host}/api/v3/drama/getCategory?orderBy=type_id",
  31. headers=self.headers,
  32. ).json()
  33. dy = {
  34. "class": "类型",
  35. "area": "地区",
  36. "lang": "语言",
  37. "year": "年份",
  38. "letter": "字母",
  39. "by": "排序",
  40. "sort": "排序",
  41. }
  42. filters = {}
  43. classes = []
  44. for item in data["data"]:
  45. has_non_empty_field = False
  46. jsontype_extend = json.loads(item["converUrl"])
  47. classes.append({"type_name": item["name"], "type_id": str(item["id"])})
  48. for key in dy:
  49. if key in jsontype_extend and jsontype_extend[key].strip() != "":
  50. has_non_empty_field = True
  51. break
  52. if has_non_empty_field:
  53. filters[str(item["id"])] = []
  54. for dkey in jsontype_extend:
  55. if dkey in dy and jsontype_extend[dkey].strip() != "":
  56. values = jsontype_extend[dkey].split(",")
  57. value_array = [
  58. {"n": value.strip(), "v": value.strip()}
  59. for value in values
  60. if value.strip() != ""
  61. ]
  62. filters[str(item["id"])].append(
  63. {"key": dkey, "name": dy[dkey], "value": value_array}
  64. )
  65. result = {}
  66. result["class"] = classes
  67. result["filters"] = filters
  68. return result
  69. def homeVideoContent(self):
  70. data = self.fetch(f"{self.host}/api/ex/v3/security/tag/list", headers=self.headers).json()["data"]
  71. data1 = self.aes(self.aes(data, self.key[0]), self.key[1], 'decrypt', True)
  72. list = []
  73. for item in data1[0]['carousels']:
  74. id = item['link'].split("id=")[1]
  75. list.append({
  76. "vod_id": id,
  77. 'vod_name': item.get("title"),
  78. 'vod_pic': item.get("cover"),
  79. 'vod_remarks': item.get("sort"),
  80. })
  81. result = {"list": list}
  82. return result
  83. def categoryContent(self, tid, pg, filter, extend):
  84. params = []
  85. if extend.get('area'):
  86. params.append(f"vodArea={extend['area']}")
  87. if extend.get('classs'):
  88. params.append(f"vodClass={extend['class']}")
  89. params.append("pagesize=20")
  90. params.append(f"typeId1={tid}")
  91. params.append(f"page={pg}")
  92. if extend.get('year'):
  93. params.append(f"vodYear={extend['year']}")
  94. body = '&'.join(params)
  95. path = self.aes(self.aes(body, self.key[1], 'encrypt'), self.key[0], 'encrypt', True)
  96. data = self.fetch(f"{self.host}/api/ex/v3/security/drama/list?query={path}", headers=self.headers).json()[
  97. "data"]
  98. data = self.aes(self.aes(data, self.key[0]), self.key[1], 'decrypt', True)['list']
  99. list = []
  100. for item in data:
  101. list.append({
  102. 'vod_id': item.get("id"),
  103. 'vod_pic': item["coverImage"].get("path"),
  104. 'vod_name': item.get("name"),
  105. 'vod_year': item.get("year"),
  106. 'vod_remarks': item.get("remark")
  107. })
  108. result = {}
  109. result["list"] = list
  110. result["page"] = pg
  111. result["pagecount"] = 9999
  112. result["limit"] = 90
  113. result["total"] = 999999
  114. return result
  115. def detailContent(self, ids):
  116. url = f"{self.host}/api/v3/drama/getDetail?id={ids[0]}"
  117. data = self.fetch(url, headers=self.headers).json()["data"]
  118. vod = {
  119. 'vod_name': data.get("name"),
  120. 'vod_area': data.get("area"),
  121. 'type_name': data.get("clazz"),
  122. 'vod_actor': data.get("actor"),
  123. 'vod_director': data.get("director"),
  124. 'vod_content': data.get("brief").strip(),
  125. }
  126. play = []
  127. names = []
  128. plays = {}
  129. for itt in data["videos"]:
  130. if itt["sourceCn"] not in names:
  131. plays[itt["source"]] = []
  132. names.append(itt["sourceCn"])
  133. url = f"vodPlayFrom={itt['source']}&playUrl={itt['path']}"
  134. if re.search(r"\.(mp4|m3u8|flv)$", itt["path"]):
  135. url = itt["path"]
  136. plays[itt["source"]].append(f"{itt['titleOld']}${url}")
  137. for it in plays:
  138. play.append("#".join(plays[it]))
  139. vod["vod_play_from"] = "$$$".join(names)
  140. vod["vod_play_url"] = "$$$".join(play)
  141. result = {"list": [vod]}
  142. return result
  143. def searchContent(self, key, quick, pg=1):
  144. body = f"pagesize=20&page={pg}&searchKeys={key}"
  145. path = self.aes(self.aes(body, self.key[1], 'encrypt'), self.key[0], 'encrypt', True)
  146. data = self.fetch(f"{self.host}/api/ex/v3/security/drama/list?query={path}", headers=self.headers).json()[
  147. "data"]
  148. data = self.aes(self.aes(data, self.key[0]), self.key[1], 'decrypt', True)['list']
  149. list = []
  150. for item in data:
  151. list.append({
  152. 'vod_id': item.get("id"),
  153. 'vod_pic': item["coverImage"].get("path"),
  154. 'vod_name': item.get("name"),
  155. 'vod_year': item.get("year"),
  156. 'vod_remarks': item.get("remark")
  157. })
  158. result = {"list": list, "page": pg}
  159. return result
  160. def playerContent(self, flag, id, vipFlags):
  161. url = id
  162. if "vodPlayFrom" in url:
  163. try:
  164. path = self.aes(self.aes(id, self.key[1], 'encrypt'), self.key[0], 'encrypt', True)
  165. data = self.fetch(f"{self.host}/api/ex/v3/security/videoUsableUrl?query={path}", headers=self.headers).json()[
  166. "data"]
  167. url = self.aes(self.aes(data, self.key[0]), self.key[1], 'decrypt', True)['playUrl']
  168. # try:
  169. # url1 = self.fetch(url, headers=self.headers, timeout=5, allow_redirects=False).headers['Location']
  170. # if "http" in url1 and url1:
  171. # url = url1
  172. # except:
  173. # pass
  174. except Exception as e:
  175. pass
  176. if '.jpg' in url or '.jpeg' in url or '.png' in url:
  177. url = self.getProxyUrl() + "&url=" + b64encode(url.encode('utf-8')).decode('utf-8') + "&type=m3u8"
  178. result = {}
  179. result["parse"] = 0
  180. result["url"] = url
  181. result["header"] = {'User-Agent': 'okhttp/3.12.1'}
  182. return result
  183. def localProxy(self, param):
  184. url = b64decode(param["url"]).decode('utf-8')
  185. durl = url[:url.rfind('/')]
  186. data = self.fetch(url, headers=self.headers).content.decode("utf-8")
  187. lines = data.strip().split('\n')
  188. for index, string in enumerate(lines):
  189. if '#EXT' not in string and 'http' not in string:
  190. lines[index] = durl + ('' if string.startswith('/') else '/') + string
  191. data = '\n'.join(lines)
  192. return [200, "application/vnd.apple.mpegur", data]
  193. def host(self):
  194. try:
  195. url = self.fetch('https://www.shijue.pro/token.txt', headers=self.headers).json()['domain']
  196. return url
  197. except:
  198. return "http://118.25.18.217:6632"
  199. headers = {
  200. 'User-Agent': 'okhttp/3.12.1',
  201. 'Content-Type': 'application/json;'
  202. }
  203. key = ['TFLYWVJ5EG5YB1PLZLVVMGVLBGRIDCSW', 'nj6E5K4yYYT5W4ScJ3J3rJ2zrzcJkpTk']
  204. def aes(self, word, key, mode='decrypt', bool=False):
  205. key = key.encode('utf-8')
  206. if mode == 'decrypt':
  207. word = b64decode(word)
  208. cipher = AES.new(key, AES.MODE_ECB)
  209. decrypted = cipher.decrypt(word)
  210. word = unpad(decrypted, AES.block_size).decode('utf-8')
  211. if bool:
  212. word = json.loads(word)
  213. elif mode == 'encrypt':
  214. cipher = AES.new(key, AES.MODE_ECB)
  215. padded = pad(word.encode('utf-8'), AES.block_size)
  216. encrypted = cipher.encrypt(padded)
  217. word = b64encode(encrypted).decode('utf-8')
  218. if bool:
  219. word = quote(word)
  220. return word