九龙影视.py 7.6 KB

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