py_推特.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. # coding=utf-8
  2. # !/usr/bin/python
  3. # by嗷呜
  4. import json
  5. import sys
  6. import time
  7. from base64 import b64decode
  8. from urllib.parse import quote
  9. from Crypto.Cipher import AES
  10. from Crypto.Hash import MD5
  11. from Crypto.Util.Padding import unpad
  12. sys.path.append('..')
  13. from base.spider import Spider
  14. class Spider(Spider):
  15. def getName(self):
  16. return "tuit"
  17. def init(self, extend=""):
  18. self.did = MD5.new((self.t).encode()).hexdigest()
  19. self.token = self.gettoken()
  20. pass
  21. def isVideoFormat(self, url):
  22. pass
  23. def manualVideoCheck(self):
  24. pass
  25. def action(self, action):
  26. pass
  27. def destroy(self):
  28. pass
  29. def aes(self, word):
  30. key = b64decode("SmhiR2NpT2lKSVV6STFOaQ==")
  31. iv = key
  32. cipher = AES.new(key, AES.MODE_CBC, iv)
  33. decrypted = unpad(cipher.decrypt(b64decode(word)), AES.block_size)
  34. return json.loads(decrypted.decode('utf-8'))
  35. def dtim(self, seconds):
  36. seconds = int(seconds)
  37. hours = seconds // 3600
  38. remaining_seconds = seconds % 3600
  39. minutes = remaining_seconds // 60
  40. remaining_seconds = remaining_seconds % 60
  41. formatted_minutes = str(minutes).zfill(2)
  42. formatted_seconds = str(remaining_seconds).zfill(2)
  43. if hours > 0:
  44. formatted_hours = str(hours).zfill(2)
  45. return f"{formatted_hours}:{formatted_minutes}:{formatted_seconds}"
  46. else:
  47. return f"{formatted_minutes}:{formatted_seconds}"
  48. def gettoken(self):
  49. url = 'https://d1frehx187fm2c.cloudfront.net/api/user/traveler'
  50. headers = {
  51. 'User-Agent': 'Mozilla/5.0 (Linux; Android 11; M2012K10C Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36;SuiRui/twitter/ver=1.3.4',
  52. 'deviceid': self.did, 't': self.t, 's': self.sign, }
  53. data = {'deviceId': self.did, 'tt': 'U', 'code': '', 'chCode': ''}
  54. data1 = self.post(url, json=data, headers=headers).json()
  55. token = data1['data']['token']
  56. return token
  57. t = str(int(time.time() * 1000))
  58. sign = MD5.new((t[3:8]).encode()).hexdigest()
  59. host = 'https://api.wcyfhknomg.work'
  60. def headers(self):
  61. henda = {
  62. 'User-Agent': 'Mozilla/5.0 (Linux; Android 11; M2012K10C Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36;SuiRui/twitter/ver=1.3.4',
  63. 'deviceid': self.did, 't': self.t, 's': self.sign, 'aut': self.token}
  64. return henda
  65. def homeContent(self, filter):
  66. data = self.fetch(f'{self.host}/api/video/classifyList', headers=self.headers()).json()['encData']
  67. data1 = self.aes(data)
  68. result = {'filters': {"1": [{"key": "fl", "name": "分类",
  69. "value": [{"n": "最近更新", "v": "1"}, {"n": "最多播放", "v": "2"},
  70. {"n": "好评榜", "v": "3"}]}], "2": [{"key": "fl", "name": "分类",
  71. "value": [
  72. {"n": "最近更新", "v": "1"},
  73. {"n": "最多播放", "v": "2"},
  74. {"n": "好评榜", "v": "3"}]}],
  75. "3": [{"key": "fl", "name": "分类",
  76. "value": [{"n": "最近更新", "v": "1"}, {"n": "最多播放", "v": "2"},
  77. {"n": "好评榜", "v": "3"}]}], "4": [{"key": "fl", "name": "分类",
  78. "value": [
  79. {"n": "最近更新", "v": "1"},
  80. {"n": "最多播放", "v": "2"},
  81. {"n": "好评榜", "v": "3"}]}],
  82. "5": [{"key": "fl", "name": "分类",
  83. "value": [{"n": "最近更新", "v": "1"}, {"n": "最多播放", "v": "2"},
  84. {"n": "好评榜", "v": "3"}]}], "6": [{"key": "fl", "name": "分类",
  85. "value": [
  86. {"n": "最近更新", "v": "1"},
  87. {"n": "最多播放", "v": "2"},
  88. {"n": "好评榜", "v": "3"}]}],
  89. "7": [{"key": "fl", "name": "分类",
  90. "value": [{"n": "最近更新", "v": "1"}, {"n": "最多播放", "v": "2"},
  91. {"n": "好评榜", "v": "3"}]}], "jx": [{"key": "type", "name": "精选",
  92. "value": [{"n": "日榜", "v": "1"},
  93. {"n": "周榜", "v": "2"},
  94. {"n": "月榜", "v": "3"},
  95. {"n": "总榜",
  96. "v": "4"}]}]}}
  97. classes = [{'type_name': "精选", 'type_id': "jx"}]
  98. for k in data1['data']:
  99. classes.append({'type_name': k['classifyTitle'], 'type_id': k['classifyId']})
  100. result['class'] = classes
  101. return result
  102. def homeVideoContent(self):
  103. pass
  104. def categoryContent(self, tid, pg, filter, extend):
  105. path = f'/api/video/queryVideoByClassifyId?pageSize=20&page={pg}&classifyId={tid}&sortType={extend.get("fl", "1")}'
  106. if 'click' in tid:
  107. path = f'/api/video/queryPersonVideoByType?pageSize=20&page={pg}&userId={tid.replace("click", "")}'
  108. if tid == 'jx':
  109. path = f'/api/video/getRankVideos?pageSize=20&page={pg}&type={extend.get("type", "1")}'
  110. data = self.fetch(f'{self.host}{path}', headers=self.headers()).json()['encData']
  111. data1 = self.aes(data)['data']
  112. result = {}
  113. videos = []
  114. for k in data1:
  115. img = 'https://dg2ordyr4k5v3.cloudfront.net/' + k.get('coverImg')[0]
  116. id = f'{k.get("videoId")}?{k.get("userId")}?{k.get("nickName")}'
  117. if 'click' in tid:
  118. id = id + 'click'
  119. videos.append({"vod_id": id, 'vod_name': k.get('title'), 'vod_pic': self.getProxyUrl() + '&url=' + img,
  120. 'vod_remarks': self.dtim(k.get('playTime')),'style': {"type": "rect", "ratio": 1.33}})
  121. result["list"] = videos
  122. result["page"] = pg
  123. result["pagecount"] = 9999
  124. result["limit"] = 90
  125. result["total"] = 999999
  126. return result
  127. def detailContent(self, ids):
  128. vid = ids[0].replace('click', '').split('?')
  129. path = f'/api/video/can/watch?videoId={vid[0]}'
  130. data = self.fetch(f'{self.host}{path}', headers=self.headers()).json()['encData']
  131. data1 = self.aes(data)['playPath']
  132. clj = '[a=cr:' + json.dumps({'id': vid[1] + 'click', 'name': vid[2]}) + '/]' + vid[2] + '[/a]'
  133. if 'click' in ids[0]:
  134. clj = vid[2]
  135. vod = {'vod_director': clj, 'vod_play_from': "推特", 'vod_play_url': vid[2] + "$" + data1}
  136. result = {"list": [vod]}
  137. return result
  138. def searchContent(self, key, quick, pg='1'):
  139. path = f'/api/search/keyWord?pageSize=20&page={pg}&searchWord={quote(key)}&searchType=1'
  140. data = self.fetch(f'{self.host}{path}', headers=self.headers()).json()['encData']
  141. data1 = self.aes(data)['videoList']
  142. result = {}
  143. videos = []
  144. for k in data1:
  145. img = 'https://dg2ordyr4k5v3.cloudfront.net/' + k.get('coverImg')[0]
  146. id = f'{k.get("videoId")}?{k.get("userId")}?{k.get("nickName")}'
  147. videos.append({"vod_id": id, 'vod_name': k.get('title'), 'vod_pic': self.getProxyUrl() + '&url=' + img,
  148. 'vod_remarks': self.dtim(k.get('playTime')), 'style': {"type": "rect", "ratio": 1.33}})
  149. result["list"] = videos
  150. result["page"] = pg
  151. result["pagecount"] = 9999
  152. result["limit"] = 90
  153. result["total"] = 999999
  154. return result
  155. def playerContent(self, flag, id, vipFlags):
  156. result = {"parse": 0, "url": id, "header": {'User-Agent': 'Mozilla/5.0 (Linux; Android 11; M2012K10C Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36;SuiRui/twitter/ver=1.3.4'}}
  157. return result
  158. def localProxy(self, param):
  159. return self.imgs(param)
  160. def imgs(self, param):
  161. headers = {
  162. 'User-Agent': 'Mozilla/5.0 (Linux; Android 11; M2012K10C Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36;SuiRui/twitter/ver=1.3.4'}
  163. url = param['url']
  164. type = url.split('.')[-1].split('_')[0]
  165. data = self.fetch(url,headers=headers).content
  166. bdata = self.img(data, 100, '2020-zq3-888')
  167. return [200, f'image/{type}', bdata]
  168. def img(self, data: bytes, length: int, key: str):
  169. GIF = b'\x47\x49\x46'
  170. JPG = b'\xFF\xD8\xFF'
  171. PNG = b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A'
  172. def is_dont_need_decode_for_gif(data):
  173. return len(data) > 2 and data[:3] == GIF
  174. def is_dont_need_decode_for_jpg(data):
  175. return len(data) > 7 and data[:3] == JPG
  176. def is_dont_need_decode_for_png(data):
  177. return len(data) > 7 and data[1:8] == PNG[1:8]
  178. if is_dont_need_decode_for_png(data):
  179. return data
  180. elif is_dont_need_decode_for_gif(data):
  181. return data
  182. elif is_dont_need_decode_for_jpg(data):
  183. return data
  184. else:
  185. key_bytes = key.encode('utf-8')
  186. result = bytearray(data)
  187. for i in range(length):
  188. result[i] ^= key_bytes[i % len(key_bytes)]
  189. return bytes(result)