py_ali.py 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318
  1. # coding=utf-8
  2. # !/usr/bin/python
  3. import sys
  4. import time
  5. import json
  6. import hashlib
  7. from base64 import b64decode
  8. from Crypto.Cipher import AES
  9. from difflib import SequenceMatcher
  10. from collections import OrderedDict
  11. from urllib.parse import quote, unquote
  12. from concurrent.futures import ThreadPoolExecutor, as_completed
  13. sys.path.append('..')
  14. from base.spider import Spider
  15. class Spider(Spider):
  16. fileidList = []
  17. shareidList = []
  18. header = {
  19. "Referer": "https://www.aliyundrive.com/",
  20. "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"
  21. }
  22. def getName(self):
  23. return "首页"
  24. def init(self, extend):
  25. try:
  26. self.extendDict = json.loads(extend)
  27. except:
  28. self.extendDict = {}
  29. def isVideoFormat(self, url):
  30. pass
  31. def manualVideoCheck(self):
  32. pass
  33. def homeVideoContent(self):
  34. from re import sub
  35. videos = []
  36. header = {
  37. 'Host': 'frodo.douban.com', 'Connection': 'Keep-Alive',
  38. 'Referer': 'https://servicewechat.com/wx2f9b06c1de1ccfca/84/page-frame.html',
  39. 'Content-Type': 'application/json',
  40. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat'}
  41. url = 'https://frodo.douban.com/api/v2/subject_collection/subject_real_time_hotest/items?start=0&count=30&apikey=0ac44ae016490db2204ce0a042db2916'
  42. try:
  43. vodList = self.fetch(url, headers=header, verify=False).json()['subject_collection_items']
  44. for vod in vodList:
  45. remark = vod['rating']['value']
  46. if remark != '':
  47. remark = '{}分'.format(remark)
  48. else:
  49. remark = '暂无评分'
  50. videos.append({
  51. "vod_db_id": vod['id'],
  52. "vod_name": vod['title'],
  53. "vod_pic": sub(r'photo/(.*?)/', 'photo/l/', vod['pic']['large']) + '@User-Agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36@Referer=https://www.douban.com/',
  54. "vod_remarks": remark
  55. })
  56. except:
  57. pass
  58. result = {'list': videos}
  59. return result
  60. def homeContent(self, filter):
  61. result = {}
  62. result['class'] = [{'type_id': 'hot_gaia', 'type_name': '热门电影'}, {'type_id': 'tv_hot', 'type_name': '热播剧集'}, {'type_id': 'show_hot', 'type_name': '热播综艺'}, {'type_id': 'movie', 'type_name': '电影筛选'}, {'type_id': 'tv', 'type_name': '电视筛选'}, {'type_id': 'rank_list_movie', 'type_name': '电影榜单'}, {'type_id': 'rank_list_tv', 'type_name': '电视榜单'}]
  63. if filter:
  64. from datetime import datetime
  65. currentYear = datetime.now().year
  66. result['filters'] = {'hot_gaia': [{'key': 'sort', 'name': '排序', 'value': [{'n': '热度', 'v': 'recommend'}, {'n': '最新', 'v': 'time'}, {'n': '评分', 'v': 'rank'}]}, {'key': 'area', 'name': '地区', 'value': [{'n': '全部', 'v': '全部'}, {'n': '华语', 'v': '华语'}, {'n': '欧美', 'v': '欧美'}, {'n': '韩国', 'v': '韩国'}, {'n': '日本', 'v': '日本'}]}], 'tv_hot': [{'key': 'type', 'name': '分类', 'value': [{'n': '综合', 'v': 'tv_hot'}, {'n': '国产剧', 'v': 'tv_domestic'}, {'n': '欧美剧', 'v': 'tv_american'}, {'n': '日剧', 'v': 'tv_japanese'}, {'n': '韩剧', 'v': 'tv_korean'}, {'n': '动画', 'v': 'tv_animation'}]}], 'show_hot': [{'key': 'type', 'name': '分类', 'value': [{'n': '综合', 'v': 'show_hot'}, {'n': '国内', 'v': 'show_domestic'}, {'n': '国外', 'v': 'show_foreign'}]}], 'movie': [{'key': '类型', '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': '歌舞'}, {'n': '武侠', 'v': '武侠'}, {'n': '情色', 'v': '情色'}, {'n': '灾难', 'v': '灾难'}, {'n': '西部', 'v': '西部'}, {'n': '纪录片', 'v': '纪录片'}, {'n': '短片', 'v': '短片'}]}, {'key': '地区', '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': '俄罗斯'}, {'n': '加拿大', 'v': '加拿大'}, {'n': '澳大利亚', 'v': '澳大利亚'}, {'n': '爱尔兰', 'v': '爱尔兰'}, {'n': '瑞典', 'v': '瑞典'}, {'n': '巴西', 'v': '巴西'}, {'n': '丹麦', 'v': '丹麦'}]}, {'key': 'sort', 'name': '排序', 'value': [{'n': '近期热度', 'v': 'T'}, {'n': '首映时间', 'v': 'R'}, {'n': '高分优先', 'v': 'S'}]}, {'key': '年代', 'name': '年代', 'value': [{'n': '全部年代', 'v': ''}, {'n': '2020年代', 'v': '2020年代'}, {'n': '2022', 'v': '2022'}, {'n': '2021', 'v': '2021'}, {'n': '2020', 'v': '2020'}, {'n': '2019', 'v': '2019'}, {'n': '2010年代', 'v': '2010年代'}, {'n': '2000年代', 'v': '2000年代'}, {'n': '90年代', 'v': '90年代'}, {'n': '80年代', 'v': '80年代'}, {'n': '70年代', 'v': '70年代'}, {'n': '60年代', 'v': '60年代'}, {'n': '更早', 'v': '更早'}]}], 'tv': [{'key': '类型', 'name': '类型', 'value': [{'n': '不限', 'v': ''}, {'n': '电视剧', 'v': '电视剧'}, {'n': '综艺', 'v': '综艺'}]}, {'key': '电视剧形式', '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': '剧情'}, {'n': '奇幻', 'v': '奇幻'}, {'n': '惊悚', 'v': '惊悚'}, {'n': '灾难', 'v': '灾难'}, {'n': '歌舞', 'v': '歌舞'}, {'n': '音乐', 'v': '音乐'}]}, {'key': '综艺形式', 'name': '综艺形式', 'value': [{'n': '不限', 'v': ''}, {'n': '真人秀', 'v': '真人秀'}, {'n': '脱口秀', 'v': '脱口秀'}, {'n': '音乐', 'v': '音乐'}, {'n': '歌舞', 'v': '歌舞'}]}, {'key': '地区', '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': '俄罗斯'}, {'n': '瑞典', 'v': '瑞典'}, {'n': '巴西', 'v': '巴西'}, {'n': '丹麦', 'v': '丹麦'}, {'n': '印度', 'v': '印度'}, {'n': '加拿大', 'v': '加拿大'}, {'n': '爱尔兰', 'v': '爱尔兰'}, {'n': '澳大利亚', 'v': '澳大利亚'}]}, {'key': 'sort', 'name': '排序', 'value': [{'n': '近期热度', 'v': 'T'}, {'n': '首播时间', 'v': 'R'}, {'n': '高分优先', 'v': 'S'}]}, {'key': '年代', 'name': '年代', 'value': [{'n': '全部', 'v': ''}, {'n': '2020年代', 'v': '2020年代'}, {'n': '2022', 'v': '2022'}, {'n': '2021', 'v': '2021'}, {'n': '2020', 'v': '2020'}, {'n': '2019', 'v': '2019'}, {'n': '2010年代', 'v': '2010年代'}, {'n': '2000年代', 'v': '2000年代'}, {'n': '90年代', 'v': '90年代'}, {'n': '80年代', 'v': '80年代'}, {'n': '70年代', 'v': '70年代'}, {'n': '60年代', 'v': '60年代'}, {'n': '更早', 'v': '更早'}]}, {'key': '平台', 'name': '平台', 'value': [{'n': '全部', 'v': ''}, {'n': '腾讯视频', 'v': '腾讯视频'}, {'n': '爱奇艺', 'v': '爱奇艺'}, {'n': '优酷', 'v': '优酷'}, {'n': '湖南卫视', 'v': '湖南卫视'}, {'n': 'Netflix', 'v': 'Netflix'}, {'n': 'HBO', 'v': 'HBO'}, {'n': 'BBC', 'v': 'BBC'}, {'n': 'NHK', 'v': 'NHK'}, {'n': 'CBS', 'v': 'CBS'}, {'n': 'NBC', 'v': 'NBC'}, {'n': 'tvN', 'v': 'tvN'}]}], 'rank_list_movie': [{'key': '榜单', 'name': '榜单', 'value': [{'n': '实时热门电影', 'v': 'movie_real_time_hotest'}, {'n': '一周口碑电影榜', 'v': 'movie_weekly_best'}, {'n': '豆瓣电影Top250', 'v': 'movie_top250'}]}], 'rank_list_tv': [{'key': '榜单', 'name': '榜单', 'value': [{'n': '实时热门电视', 'v': 'tv_real_time_hotest'}, {'n': '华语口碑剧集榜', 'v': 'tv_chinese_best_weekly'}, {'n': '全球口碑剧集榜', 'v': 'tv_global_best_weekly'}, {'n': '国内口碑综艺榜', 'v': 'show_chinese_best_weekly'}, {'n': '国外口碑综艺榜', 'v': 'show_global_best_weekly'}]}]}
  67. maxYear = float('-inf')
  68. for tv in result['filters']['tv']:
  69. if tv['key'] == '年代':
  70. for item in tv['value']:
  71. v = item['v']
  72. if v.isnumeric():
  73. numericValue = int(v)
  74. maxYear = max(maxYear, numericValue)
  75. for year in range(currentYear, 0, -1):
  76. if year > maxYear:
  77. pos = tv['value'].index({'n': str(maxYear), 'v': str(maxYear)})
  78. tv['value'].insert(pos, {'n': str(year), 'v': str(year)})
  79. else:
  80. break
  81. break
  82. for movie in result['filters']['movie']:
  83. if movie['key'] == '年代':
  84. for item in movie['value']:
  85. v = item['v']
  86. if v.isnumeric():
  87. numericValue = int(v)
  88. maxYear = max(maxYear, numericValue)
  89. for year in range(currentYear, 0, -1):
  90. if year > maxYear:
  91. pos = movie['value'].index({'n': str(maxYear), 'v': str(maxYear)})
  92. movie['value'].insert(pos, {'n': str(year), 'v': str(year)})
  93. else:
  94. break
  95. break
  96. return result
  97. def categoryContent(self, cid, page, filter, ext):
  98. from re import sub
  99. page = int(page)
  100. result = {}
  101. videos = []
  102. header = {
  103. 'Content-Type': 'application/json',
  104. 'Host': 'frodo.douban.com', 'Connection': 'Keep-Alive',
  105. 'Referer': 'https://servicewechat.com/wx2f9b06c1de1ccfca/84/page-frame.html',
  106. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat'}
  107. if cid == 'hot_gaia':
  108. if 'area' in ext.keys():
  109. area = ext['area']
  110. else:
  111. area = '全部'
  112. if 'sort' in ext.keys():
  113. sort = ext['sort']
  114. else:
  115. sort = 'recommend'
  116. params = {'area': area, 'sort': sort, 'start': ((int(page) - 1) * 30), 'count': 30, 'apikey': '0ac44ae016490db2204ce0a042db2916'}
  117. url = f'https://frodo.douban.com/api/v2/movie/{cid}?'
  118. for key in params:
  119. url += f'&{key}={params[key]}'
  120. append = 'items'
  121. elif cid == 'tv_hot' or cid == 'show_hot':
  122. if 'type' in ext.keys():
  123. cid = ext['type']
  124. url = f'https://frodo.douban.com/api/v2/subject_collection/{cid}/items?'
  125. params = {'start': (int(page) - 1) * 30, 'count': 30, 'apikey': '0ac44ae016490db2204ce0a042db2916'}
  126. for key in params:
  127. url += f'&{key}={params[key]}'
  128. append = 'subject_collection_items'
  129. elif cid == 'tv' or cid == 'movie':
  130. tags = ''
  131. tagsList = []
  132. if '类型' in ext.keys():
  133. movieType = ext['类型']
  134. else:
  135. movieType = ''
  136. if '地区' in ext.keys():
  137. area = ext['地区']
  138. else:
  139. area = ''
  140. if 'sort' in ext.keys():
  141. sort = ext['sort']
  142. else:
  143. sort = 'T'
  144. selectedCategories = {"类型": movieType, "地区": area}
  145. for key in ext:
  146. if '形式' in key:
  147. selectedCategories.update({key: ext[key]})
  148. if key == 'sort':
  149. continue
  150. tagsList.append(ext[key])
  151. tagsList = [item for item in tagsList if item != '']
  152. if len(tagsList) == 1:
  153. tags = tagsList[0]
  154. elif len(tagsList) > 1:
  155. tags = json.dumps(tagsList, ensure_ascii=False)
  156. url = f'https://frodo.douban.com/api/v2/{cid}/recommend?'
  157. params = {'tags': tags, 'sort': sort, 'refresh': 0, 'selected_categories': json.dumps(selectedCategories, ensure_ascii=False), 'start': (int(page) - 1) * 30, 'count': 30, 'apikey': '0ac44ae016490db2204ce0a042db2916'}
  158. for key in params:
  159. url += f'&{key}={params[key]}'
  160. append = 'items'
  161. else:
  162. if '榜单' in ext.keys():
  163. cid = ext['榜单']
  164. else:
  165. cid = cid.split('_')[2] + '_real_time_hotest'
  166. url = f'https://frodo.douban.com/api/v2/subject_collection/{cid}/items?'
  167. params = {'start': ((int(page) - 1) * 30), 'count': 30, 'apikey': '0ac44ae016490db2204ce0a042db2916'}
  168. for key in params:
  169. url += f'&{key}={params[key]}'
  170. append = 'subject_collection_items'
  171. data = self.fetch(url, headers=header, verify=False, timeout=5).json()
  172. for video in data[append]:
  173. vid = video['id']
  174. if not vid.isnumeric():
  175. continue
  176. img = sub(r'photo/(.*?)/', 'photo/l/', video['pic']['large']) + '@User-Agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36@Referer=https://www.douban.com/'
  177. name = video['title'].strip()
  178. try:
  179. remark = video['rating']['value']
  180. except:
  181. remark = video['episodes_info']
  182. if remark != '':
  183. remark = '{}分'.format(remark)
  184. else:
  185. remark = '暂无评分'
  186. videos.append({
  187. "vod_db_id": vid,
  188. "vod_name": name,
  189. "vod_pic": img,
  190. "vod_remarks": remark
  191. })
  192. lenvodList = len(videos)
  193. if page * 30 < data['total']:
  194. pagecount = page + 1
  195. else:
  196. pagecount = page
  197. result['list'] = videos
  198. result['page'] = page
  199. result['pagecount'] = pagecount
  200. result['limit'] = lenvodList
  201. result['total'] = lenvodList
  202. return result
  203. def detailContent(self, did):
  204. name = ''
  205. did = did[0]
  206. if '###' in did:
  207. idsList = did.split('###')
  208. tag = idsList[0]
  209. tid = idsList[1]
  210. if tag == 'wogg':
  211. if '---' in tid:
  212. tids = tid.split('---')
  213. tid = tids[0]
  214. name = tids[1]
  215. if not 'www.aliyundrive.com' in tid:
  216. url = 'http://wogg.xyz/index.php/voddetail/{}.html'.format(tid)
  217. r = self.fetch(url, headers={"User-Agent": "okhttp/3.12.13"}, verify=False)
  218. m = self.regStr(reg='https://www.aliyundrive.com/s/[^"]+', src=r.text.replace('www.alipan.com', 'www.aliyundrive.com'), group=0)
  219. else:
  220. m = self.regStr(reg='https://www.aliyundrive.com/s/[^"]+', src=tid.replace('www.alipan.com', 'www.aliyundrive.com'), group=0)
  221. tid = m.replace('\\', '')
  222. elif tag == 'ps':
  223. if '---' in tid:
  224. tids = tid.split('---')
  225. tid = tids[0]
  226. name = tids[1]
  227. header = {
  228. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
  229. 'Referer': 'https://www.alipansou.com' + '/s/' + tid
  230. }
  231. r = self.fetch('https://www.alipansou.com' + '/cv/' + tid, allow_redirects=False, headers=header, timeout=5)
  232. tid = self.regStr(r.text.replace('www.alipan.com', 'www.aliyundrive.com'), 'https://www.aliyundrive.com/s/[^"]+', 0).replace('\\', '')
  233. elif tag == 'cz':
  234. header = {
  235. 'Referer': 'https://www.czzy88.com/',
  236. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
  237. }
  238. url = 'https://www.czzy88.com/' + tid + '.html'
  239. r = self.getContent({'pf': 'cz', 'url': url}, header)
  240. html = self.html(r.content.decode())
  241. name = self.xpText(html, "//div[contains(@class,'moviedteail_tt')]/h1/text()")
  242. pic = self.xpText(html, "//div[contains(@class,'dyimg')]/img/@src")
  243. content = self.xpText(html, "//div[contains(@class,'yp_context')]/text()").strip().replace('\t\t', '')
  244. vodList = {
  245. 'vod_id': did,
  246. 'vod_name': name,
  247. 'vod_pic': pic,
  248. 'vod_content': content,
  249. 'vod_play_from': '厂长'
  250. }
  251. playUrl = ''
  252. playInfosList = html.xpath("//div[contains(@class,'paly_list_btn')]/a")
  253. i = 0
  254. for playInfos in playInfosList:
  255. i += 1
  256. playUrl += '#' + self.xpText(playInfos, "./text()").replace('\xa0', '') + '$' + self.xpText(playInfos, "./qyg13.js") + '---{}---{}'.format(name, i)
  257. vodList['vod_play_url'] = playUrl.strip('#')
  258. result = {'list': [vodList]}
  259. return result
  260. else:
  261. tid = did
  262. if 'www.aliyundrive.com' in tid or 'www.alipan.com' in tid:
  263. tid = tid.replace('www.alipan.com', 'www.aliyundrive.com')
  264. if '---' in tid:
  265. tids = tid.split('---')
  266. tid = tids[0]
  267. name = tids[1]
  268. shareId = self.regStr(reg='www.aliyundrive.com\\/s\\/([^\\/]+)(\\/folder\\/([^\\/]+))?', src=tid, group=1)
  269. fileId = self.regStr(reg='www.aliyundrive.com\\/s\\/([^\\/]+)(\\/folder\\/([^\\/]+))?', src=tid, group=3)
  270. url = 'https://api.aliyundrive.com/adrive/v3/share_link/get_share_by_anonymous'
  271. params = {'share_id': shareId}
  272. data = self.postJson(url, json=params, headers=self.header, verify=False, timeout=5).json()
  273. fileInfos = []
  274. if 'file_infos' in data:
  275. fileInfos = data['file_infos']
  276. if len(fileInfos) <= 0:
  277. return {'list': [], 'msg': '分享链接已失效'}
  278. fileInfo = fileInfos[0]
  279. if fileId == None or len(fileId) <= 0:
  280. fileId = fileInfo['file_id']
  281. if name == '':
  282. name = data['share_name']
  283. vodList = {
  284. 'vod_id': tid,
  285. 'vod_name': name,
  286. 'vod_pic': data['avatar'],
  287. 'vod_content': tid,
  288. 'vod_play_from': '原画$$$普画'
  289. }
  290. fileType = fileInfo['type']
  291. if fileType != 'folder':
  292. if fileType != 'file' or fileInfo['category'] != 'video':
  293. return {'list': [], 'msg': '分享链接已失效'}
  294. fileId = 'root'
  295. shareToken = self.getshareToken(shareId, '')
  296. itemsDict = self.listFiles({}, shareId, fileId, shareToken)
  297. if len(itemsDict) == 0:
  298. return {'list': [], 'msg': '无可播放资源'}
  299. itemsDict = sorted(itemsDict.items(), key=lambda x: x[0])
  300. videoList = []
  301. playList = []
  302. for item in itemsDict:
  303. videoList.append(item[0] + '$' + '{}---'.format(name) + quote(item[1]))
  304. playList.append('#'.join(videoList))
  305. vodList['vod_play_url'] = '$$$'.join(playList + playList)
  306. result = {
  307. 'list': [vodList]
  308. }
  309. else:
  310. url = tid.replace('#', '***')
  311. vodList = {
  312. 'vod_id': tid,
  313. 'vod_name': tid,
  314. 'vod_content': tid,
  315. 'vod_play_from': '直链$$$嗅探$$$解析',
  316. 'vod_play_url': '推送${}$$$推送${}$$$推送${}'.format(url, url, url)
  317. }
  318. result = {'list': [vodList]}
  319. return result
  320. def playerContent(self, flag, pid, vipFlags):
  321. result = {}
  322. pid = pid.replace('***', '#')
  323. result["url"] = pid
  324. if flag == '原画':
  325. name = pid.split('---')[0]
  326. pos = pid.split('---')[1]
  327. pid = pid.split('---')[2]
  328. params = self.getDanmaku(name, pos)
  329. result = self.ognContent(flag, pid)
  330. if params:
  331. danmuUrl = f'https://api-lmteam.koyeb.app/danmu?params={quote(json.dumps(params))}'
  332. result['danmaku'] = danmuUrl
  333. return result
  334. elif flag == '普画':
  335. name = pid.split('---')[0]
  336. pos = pid.split('---')[1]
  337. pid = pid.split('---')[2]
  338. params = self.getDanmaku(name, pos)
  339. result = self.fhdContent(flag, pid)
  340. if params:
  341. danmuUrl = f'https://api-lmteam.koyeb.app/danmu?params={quote(json.dumps(params))}'
  342. result['danmaku'] = danmuUrl
  343. return result
  344. elif flag == '直链':
  345. result["parse"] = 0
  346. elif flag == '嗅探':
  347. result["parse"] = 1
  348. elif flag == '解析':
  349. result["jx"] = 1
  350. elif flag == '厂长':
  351. result["parse"] = 0
  352. header = {
  353. 'Referer': 'https://www.czzy88.com/',
  354. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
  355. }
  356. url = pid.split('---')[0]
  357. name = pid.split('---')[1]
  358. pos = pid.split('---')[2]
  359. params = self.getDanmaku(name, pos)
  360. if params:
  361. danmuUrl = f'https://api-lmteam.koyeb.app/danmu?params={quote(json.dumps(params))}'
  362. result['danmaku'] = danmuUrl
  363. r = self.getContent({'pf': 'cz', 'url': url}, header)
  364. try:
  365. b64 = self.regStr(reg='\"([^\"]+)\";var [\d\w]+=function dncry.*md5.enc.Utf8.parse\(\"([\d\w]+)\".*md5.enc.Utf8.parse\(([\d]+)\)', src=r.text, group=1)
  366. key = self.regStr(reg='\"([^\"]+)\";var [\d\w]+=function dncry.*md5.enc.Utf8.parse\(\"([\d\w]+)\".*md5.enc.Utf8.parse\(([\d]+)\)', src=r.text, group=2).encode()
  367. iv = self.regStr(reg='\"([^\"]+)\";var [\d\w]+=function dncry.*md5.enc.Utf8.parse\(\"([\d\w]+)\".*md5.enc.Utf8.parse\(([\d]+)\)', src=r.text, group=3).encode()
  368. enc = b64decode(b64)
  369. cipher = AES.new(key, AES.MODE_CBC, iv)
  370. data = cipher.decrypt(enc)
  371. content = data[:-data[-1]].decode()
  372. playUrl = self.regStr(reg='video: *\{url: *\"([^\"]+)\"', src=content)
  373. subUrl = self.regStr(reg='subtitle: *\{url: *\"([^\"]+)\"', src=content)
  374. if len(subUrl) > 0:
  375. result['subs'] = [{'url': subUrl, 'name': 'czspp'}]
  376. except:
  377. url = self.regStr(reg='<iframe.*?src=\"(.*?)\".*?</iframe>', src=r.text)
  378. header.update({'sec-ch-ua-platform': '"Windows"', 'Sec-Fetch-Dest': "iframe", 'Sec-Fetch-Mode': "navigate", 'Sec-Fetch-Site': "cross-site", "Upgrade-Insecure-Requests": "1", "sec-ch-ua-mobile": "?0", "sec-ch-ua": '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"', "Cookies": 'DNT=1'})
  379. r = self.getContent({'pf': 'cz', 'url': url}, header)
  380. try:
  381. b64 = self.regStr(reg='var rand = \"(.*?)\".*var player = \"(.*?)\"', src=r.text.replace('\n', ''), group=2)
  382. iv = self.regStr(reg='var rand = \"(.*?)\".*var player = \"(.*?)\"', src=r.text.replace('\n', ''), group=1).encode()
  383. enc = b64decode(b64)
  384. cipher = AES.new('VFBTzdujpR9FWBhe'.encode(), AES.MODE_CBC, iv)
  385. data = cipher.decrypt(enc)
  386. content = data[:-data[-1]].decode()
  387. playUrl = json.loads(content)['url']
  388. except:
  389. playUrl = ''
  390. content = self.regStr(r.text.replace('\n', ''), '\"data\":\"(.*?)\"')[::-1]
  391. for i in range(0, len(content), 2):
  392. combinedChars = content[i] + content[i + 1]
  393. decimalValue = int(combinedChars, 16)
  394. playUrl += chr(decimalValue)
  395. pos = int((len(playUrl) - 7) / 2)
  396. playUrl = playUrl[:pos] + playUrl[pos + 7:]
  397. result["url"] = playUrl
  398. else:
  399. result = {}
  400. return result
  401. def searchContent(self, key, quick):
  402. return self.searchContentPage(key, quick, '1')
  403. def searchContentPage(self, key, quick, page):
  404. self.fileidList = []
  405. self.shareidList = []
  406. page = int(page)
  407. items = []
  408. keyword = key
  409. if page == 1:
  410. siteList = ['cz', 'ps', 'zt', 'xy', 'wogg']
  411. else:
  412. siteList = self.getCache('alisiteList_{}_{}'.format(keyword, page))
  413. self.delCache('alisiteList_{}_{}'.format(keyword, page))
  414. if not siteList:
  415. return {'list': items}
  416. contents = []
  417. if quick:
  418. siteList = ['cz']
  419. with ThreadPoolExecutor(max_workers=5) as executor:
  420. searchList = []
  421. try:
  422. for site in siteList:
  423. tag = site
  424. future = executor.submit(self.runSearch, key, tag, page)
  425. searchList.append(future)
  426. for result in as_completed(searchList, timeout=10):
  427. contents.append(result.result())
  428. except:
  429. pass
  430. finally:
  431. executor.shutdown(wait=False)
  432. nextpageList = []
  433. for content in contents:
  434. if content is None:
  435. continue
  436. contkey = list(content.keys())[0]
  437. infos = content[contkey]
  438. items = items + content[contkey][0]
  439. nextpageList.append(infos[1])
  440. if not infos[1]:
  441. siteList.remove(contkey)
  442. self.setCache('alisiteList_{}_{}'.format(keyword, page+1), siteList)
  443. result = {
  444. 'list': items,
  445. 'hasNext': True in nextpageList
  446. }
  447. return result
  448. def runSearch(self, key, tag, pg):
  449. try:
  450. defname = 'self.search' + tag
  451. result = eval(defname)(key, tag, pg)
  452. return result
  453. except Exception as e:
  454. return {tag: [[], False]}
  455. def searchcz(self, key, tag, pg):
  456. items = []
  457. header = {
  458. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.37"
  459. }
  460. r = self.post('https://ymck.pro/API/v2.php', headers=header, data={'q': key, 'size': 25}, timeout=5, verify=False)
  461. vList = json.loads(b64decode(self.cleanText(r.text)))[1:]
  462. vidList = []
  463. for video in vList[1:]:
  464. if 'website' not in video or video['website'] != '厂长资源':
  465. continue
  466. name = video['text']
  467. vid = self.regStr(reg='http.*?//.*?/(\S+/.*?).html', src=video['url'])
  468. if vid in vidList:
  469. continue
  470. else:
  471. vidList.append(vid)
  472. items.append({
  473. 'vod_id': 'cz###' + vid,
  474. 'vod_name': name,
  475. "vod_remarks": '厂长'
  476. })
  477. return {tag: [items, False]}
  478. def searchps(self, key, tag, pg):
  479. pg = int(pg)
  480. items = []
  481. header = {
  482. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.37",
  483. # "Content-Type": "text/html; charset=UTF-8",
  484. "Referer": "https://www.alipansou.com/"
  485. }
  486. r = self.fetch(f'https://www.alipansou.com/search?page={pg}&k={key}&t=7', headers=header, verify=False, timeout=5)
  487. html = self.html(self.cleanText(r.content.decode('utf-8')))
  488. vList = html.xpath("//van-row/a")
  489. for video in vList:
  490. href = self.xpText(video, "./qyg13.js")
  491. if 'xunlei' in href:
  492. continue
  493. vid = self.regStr(reg=r'/s/(.*)', src=href)
  494. nameElement = self.xpText(video, ".//template/div")
  495. name = ''.join(nameElement.xpath('./qyg8.js')).strip()
  496. if name.count(key) > 1 or len(name) - len(key) > 10:
  497. name = ''.join(OrderedDict.fromkeys(name))
  498. if SequenceMatcher(None, name, key).ratio() < 0.6 and not key in name:
  499. continue
  500. items.append({
  501. 'vod_id': 'ps###' + vid + "---{}".format(key),
  502. 'vod_name': name,
  503. 'vod_pic': './qyg14.png',
  504. "vod_remarks": '阿里盘搜'
  505. })
  506. try:
  507. maxPage = int(self.xpText(html, ".//van-row/van-col/van-pagination/@page-count"))
  508. except:
  509. maxPage = pg
  510. if len(items) == 0:
  511. maxPage = pg
  512. return {tag: [items, pg < maxPage]}
  513. def searchzt(self, key, tag, pg):
  514. items = []
  515. header = {
  516. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.37",
  517. "Referer": "http://a.gitcafe.net/"
  518. }
  519. params = {
  520. "action": "search",
  521. "from": "web",
  522. "token": "c128f28b5aca32c462c6bb0e032e77ebacca8c",
  523. "keyword": key
  524. }
  525. r = self.post('https://gitcafe.net/tool/alipaper/', data=params, headers=header, timeout=5)
  526. vList = json.loads(self.cleanText(r.text))['data']
  527. for video in vList:
  528. if video['alikey'] in self.shareidList:
  529. continue
  530. self.shareidList.append(video['alikey'])
  531. name = video['title']
  532. if len(name) > len(key) + 20:
  533. name = ''.join(OrderedDict.fromkeys(name))
  534. items.append({
  535. 'vod_id': 'https://www.aliyundrive.com/s/' + video['alikey'] + "---{}".format(key),
  536. 'vod_name': name,
  537. 'vod_pic': './qyg14.png',
  538. "vod_remarks": '阿里纸条'
  539. })
  540. return {tag: [items, False]}
  541. def searchxy(self, key, tag, pg):
  542. items = []
  543. header = {
  544. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.37",
  545. "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
  546. "Referer": f"http://www.yunso.net/index/user/s?wd={quote(key)}"
  547. }
  548. r = self.post(f'http://www.yunso.net/api/validate/search?wd={key}&page={pg}&uk=&mode=90001&stype=20100&scope_content=', data=f'/api/validate/search?wd={key}&page={pg}&uk=&mode=90001&stype=20100&scope_content=', verify=False, headers=header, timeout=5)
  549. data = json.loads(self.cleanText(r.text))
  550. html = self.html(data['data'].replace('</>', ''))
  551. vList = html.xpath("//div[contains(@class,'layui-card-header')]")
  552. count = 0
  553. for video in vList:
  554. name = self.xpText(video, './qyg9.js').strip()
  555. if name.count(key) > 1 or len(name) > len(key) + 20:
  556. name = ''.join(OrderedDict.fromkeys(name))
  557. vid = b64decode(self.xpText(video, './qyg10.js')).decode().replace('www.alipan.com', 'www.aliyundrive.com')
  558. if 'www.aliyundrive.com' not in vid:
  559. continue
  560. shareId = self.regStr(vid, 'www.aliyundrive.com\/s\/([^\/]+)(\/folder\/([^\/]+))?')
  561. if shareId not in self.shareidList:
  562. self.shareidList.append(shareId)
  563. else:
  564. count += 1
  565. continue
  566. items.append({
  567. 'vod_id': vid + "---{}".format(key),
  568. 'vod_name': name,
  569. 'vod_pic': './qyg14.png',
  570. "vod_remarks": '阿里小云'
  571. })
  572. return {tag: [items, len(items) + count == 20]}
  573. def searchwogg(self, key, tag, pg):
  574. pg = int(pg)
  575. items = []
  576. header = {
  577. "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"}
  578. url = 'http://wogg.xyz/index.php/vodsearch/{}----------{}---.html'.format(key, pg)
  579. r = self.fetch(url, headers=header, verify=False, timeout=5)
  580. html = self.html(self.cleanText(r.text))
  581. vList = html.xpath("//div[contains(@class,'module-items')]/div")
  582. nextpage = True
  583. for video in vList:
  584. img = self.xpText(video, './qyg11.js')
  585. if not img.startswith('http'):
  586. img = self.regStr(img, '\((http.*?)\)')
  587. title = self.xpText(video, './qyg12.js').strip()
  588. vid = self.xpText(video, ".//div[contains(@class,'video-info-footer')]/a/@href")
  589. vid = self.regStr(vid, '/(\d+)\.html')
  590. items.append({
  591. 'vod_id': 'wogg###' + vid + "---{}".format(key),
  592. 'vod_name': title,
  593. 'vod_pic': img,
  594. "vod_remarks": '阿里玩偶哥哥'
  595. })
  596. maxPageLiset = html.xpath(".//div[@id='page']/a")
  597. if maxPageLiset != []:
  598. maxPage = self.xpText(maxPageLiset[-1], './qyg13.js')
  599. maxPage = self.regStr(maxPage, '-(\d+)-')
  600. if pg == int(maxPage):
  601. nextpage = False
  602. else:
  603. nextpage = False
  604. return {tag: [items, nextpage]}
  605. def localProxy(self, params):
  606. if params['type'] == "m3u8":
  607. return self.proxyM3u8(params)
  608. elif params['type'] == "media":
  609. return self.proxyMedia(params)
  610. elif params['type'] == "ts":
  611. return self.proxyTs(params)
  612. return None
  613. def ognContent(self, flag, oid):
  614. oid = unquote(oid)
  615. ids = oid.split('+')
  616. shareId = ids[0]
  617. fileId = ids[2]
  618. if 'thread' in self.extendDict:
  619. thread = self.extendDict['thread']
  620. else:
  621. thread = '0'
  622. token = self.extendDict['token']
  623. if token.startswith('http'):
  624. token = quote(token)
  625. subtitleList = self.subtitleContent(oid)
  626. result = {
  627. 'parse': '0',
  628. 'playUrl': '',
  629. 'url': f"http://127.0.0.1:UndCover/proxy?do=py&type=media&shareId={shareId}&fileId={fileId}&token={token}&thread={thread}",
  630. 'header': self.header,
  631. 'subs': subtitleList
  632. }
  633. return result
  634. def fhdContent(self, flag, fid):
  635. fid = unquote(fid)
  636. ids = fid.split('+')
  637. shareId = ids[0]
  638. fileId = ids[2]
  639. token = self.extendDict['token']
  640. if token.startswith('http'):
  641. token = quote(token)
  642. subtitleList = self.subtitleContent(fid)
  643. result = {
  644. 'parse': '0',
  645. 'playUrl': '',
  646. 'url': f"http://127.0.0.1:UndCover/proxy?do=py&type=m3u8&shareId={shareId}&fileId={fileId}&token={token}",
  647. 'header': self.header,
  648. 'subs': subtitleList
  649. }
  650. return result
  651. def subtitleContent(self, sid):
  652. ids = sid.split('+')
  653. shareId = ids[0]
  654. shareToken = ids[1]
  655. subtitle = ids[4]
  656. token = self.extendDict['token']
  657. if token.startswith('http'):
  658. token = quote(token)
  659. if len(subtitle) == 0:
  660. return []
  661. tokenDict = self.getToken(self.extendDict['token'])
  662. header = self.header.copy()
  663. header['Content-Type'] = 'application/json'
  664. header['x-share-token'] = shareToken
  665. header['authorization'] = tokenDict['authorization']
  666. subtitleList = subtitle.strip("&&&").split('&&&')
  667. subs = []
  668. for sub in subtitleList:
  669. subList = sub.split('###')
  670. subname = subList[0]
  671. if subname.split('.')[-1].lower() == 'ssa' or subname.split('.')[-1].lower() == 'ass':
  672. subformat = 'text/x-ssa'
  673. elif subname.split('.')[-1].lower() == 'srt':
  674. subformat = 'application/x-subrip'
  675. elif subname.split('.')[-1].lower() == 'vtt':
  676. subformat = 'text/vtt'
  677. else:
  678. subformat = 'text/plain'
  679. fileId = subList[1]
  680. subs.append({'url': f"http://127.0.0.1:UndCover/proxy?do=py&type=media&shareId={shareId}&fileId={fileId}&token={token}&subformat{subformat}", 'name': subname, 'format': subformat})
  681. return subs
  682. def delFiles(self, header, toDriveId, tempidsList):
  683. delidsList = []
  684. for fileId in tempidsList:
  685. jsonStr = '{\"requests\":[{\"body\":{\"drive_id\":\"%s\",\"file_id\":\"%s\"},\"headers\":{\"Content-Type\":\"application/json\"},\"id\":\"%s\",\"method\":\"POST\",\"url\":\"/file/delete\"}],\"resource\":\"file\"}' % (toDriveId, fileId, fileId)
  686. r = self.post('https://api.aliyundrive.com/v3/batch', data=jsonStr, headers=header, verify=False, timeout=5)
  687. if r.status_code == 200 and r.json()['responses'][0]['status'] == 404:
  688. delidsList.append(fileId)
  689. for fileId in delidsList:
  690. tempidsList.remove(fileId)
  691. if tempidsList != []:
  692. self.setCache('tempidsList', tempidsList)
  693. else:
  694. self.delCache('tempidsList')
  695. def proxyMedia(self, params):
  696. thread = 0
  697. downloadUrl = ''
  698. token = params['token']
  699. fileId = params['fileId']
  700. shareId = params['shareId']
  701. if 'thread' in params:
  702. thread = int(params['thread'])
  703. tokenDict = self.getToken(token, True)
  704. shareToken = self.getshareToken(shareId, '')
  705. header = self.header.copy()
  706. header['Content-Type'] = 'application/json'
  707. header['x-share-token'] = shareToken
  708. header['authorization'] = tokenDict['authorization']
  709. toDriveId = tokenDict['drive_id']
  710. tempidsList = self.getCache('tempidsList')
  711. if not tempidsList:
  712. tempidsList = []
  713. if tempidsList != []:
  714. self.delFiles(header, toDriveId, tempidsList)
  715. key = f'alidownloadUrl_{shareId}_{fileId}'
  716. data = self.getCache(key)
  717. if data and 'downloadUrl' in data:
  718. header = self.header.copy()
  719. if 'range' in params:
  720. header['Range'] = params['range']
  721. contentType = data['contentType']
  722. if contentType == "video/MP2T":
  723. action = {'url': data['downloadUrl'], 'header': header, 'param': '', 'type': 'redirect'}
  724. return [302, contentType, action, data['downloadUrl']]
  725. action = {'url': data['downloadUrl'], 'header': header, 'param': '', 'type': 'stream'}
  726. return [206, "application/octet-stream", action, '']
  727. code = 200
  728. contentType = "application/octet-stream"
  729. if tokenDict['open_token'] == '':
  730. thread = 10
  731. if 'thread' in params:
  732. thread = int(params['thread'])
  733. if thread == 0:
  734. code = 206
  735. contentType = "application/octet-stream"
  736. try:
  737. jsonStr = "{\"requests\":[{\"body\":{\"file_id\":\"%s\",\"share_id\":\"%s\",\"auto_rename\":true,\"to_parent_file_id\":\"root\",\"to_drive_id\":\"%s\"},\"headers\":{\"Content-Type\":\"application/json\"},\"id\":\"0\",\"method\":\"POST\",\"url\":\"/file/copy\"}],\"resource\":\"file\"}" % (fileId, shareId, toDriveId)
  738. r = self.post('https://api.aliyundrive.com/v3/batch', data=jsonStr, headers=header, verify=False, timeout=5)
  739. if r.status_code == 400:
  740. r = self.post('https://user.aliyundrive.com/v2/user/get', headers=header, verify=False)
  741. toDriveId = r.json()['resource_drive_id']
  742. jsonStr = "{\"requests\":[{\"body\":{\"file_id\":\"%s\",\"share_id\":\"%s\",\"auto_rename\":true,\"to_parent_file_id\":\"root\",\"to_drive_id\":\"%s\"},\"headers\":{\"Content-Type\":\"application/json\"},\"id\":\"0\",\"method\":\"POST\",\"url\":\"/file/copy\"}],\"resource\":\"file\"}" % (fileId, shareId, toDriveId)
  743. r = self.post('https://api.aliyundrive.com/v3/batch', data=jsonStr, headers=header, verify=False, timeout=5)
  744. myFileId = r.json()['responses'][0]['body']['file_id']
  745. tempidsList.append(myFileId)
  746. header['authorization'] = tokenDict['open_authorization']
  747. data = self.postJson('https://open.aliyundrive.com/adrive/v1.0/openFile/getDownloadUrl',
  748. json={
  749. "expire_sec": 115200,
  750. 'file_id': myFileId,
  751. 'drive_id': toDriveId
  752. },
  753. headers=header,
  754. verify=False,
  755. timeout=5).json()
  756. downloadUrl = data['url']
  757. try:
  758. if 'auth_key=' in downloadUrl:
  759. expiresAt = int(self.regStr(reg="auth_key=(\d+)-", src=downloadUrl)) - 60
  760. elif 'x-oss-expires=' in downloadUrl:
  761. expiresAt = int(self.regStr(reg="x-oss-expires=(\d+)", src=downloadUrl)) - 60
  762. else:
  763. expiresAt = int(time.time()) - 60
  764. except:
  765. expiresAt = int(time.time()) - 60
  766. self.setCache(key, {"thread": 0, 'downloadUrl': downloadUrl, 'expiresAt': expiresAt, 'shareId': shareId, 'fileId': fileId, "contentType": contentType})
  767. except:
  768. if 'thread' in params and int(params['thread']) != 0:
  769. thread = int(params['thread'])
  770. else:
  771. thread = 10
  772. finally:
  773. if tempidsList != []:
  774. header['authorization'] = tokenDict['authorization']
  775. self.delFiles(header, toDriveId, tempidsList)
  776. if thread > 0:
  777. code = 302
  778. contentType = "video/MP2T"
  779. header['authorization'] = tokenDict['authorization']
  780. r = self.postJson(
  781. 'https://api.aliyundrive.com/v2/file/get_share_link_download_url',
  782. json={
  783. 'share_id': shareId,
  784. 'file_id': fileId,
  785. "expire_sec": 600,
  786. },
  787. headers=header,
  788. verify=False,
  789. timeout=5)
  790. downloadUrl = r.json()['url']
  791. try:
  792. if 'auth_key=' in downloadUrl:
  793. expiresAt = int(self.regStr(reg="auth_key=(\d+)-", src=downloadUrl)) - 60
  794. elif 'x-oss-expires=' in downloadUrl:
  795. expiresAt = int(self.regStr(reg="x-oss-expires=(\d+)", src=downloadUrl)) - 60
  796. else:
  797. expiresAt = int(time.time()) - 60
  798. except:
  799. expiresAt = int(time.time()) - 60
  800. try:
  801. # self.fetch('http://192.168.1.254:7777')
  802. self.fetch('http://127.0.0.1:7777')
  803. except:
  804. # self.fetch('http://192.168.1.254:9978/go')
  805. self.fetch('http://127.0.0.1:9978/go')
  806. downloadUrl = f'http://127.0.0.1:7777?url={quote(downloadUrl)}&thread={thread}'
  807. self.setCache(key, {"thread": thread, 'downloadUrl': downloadUrl, 'expiresAt': expiresAt, 'shareId': shareId, 'fileId': fileId, "contentType": contentType})
  808. action = {'url': downloadUrl, 'header': self.header, 'param': '', 'type': 'redirect'}
  809. return [code, contentType, action, downloadUrl]
  810. header = self.header.copy()
  811. if 'range' in params:
  812. header['Range'] = params['range']
  813. action = {'url': downloadUrl, 'header': header, 'param': '', 'type': 'stream'}
  814. return [code, contentType, action, '']
  815. def proxyTs(self, params):
  816. mediaId = params['mediaId']
  817. _, m3u8Infos = self.getM3u8(params)
  818. url = m3u8Infos[str(mediaId)]
  819. if url.count('https') > 1:
  820. url = self.regStr(url, 'http.*?(http.*?://.*)')
  821. action = {'url': url, 'header': self.header, 'param': '', 'type': 'stream'}
  822. return [200, "video/MP2T", action, '']
  823. def proxyM3u8(self, params):
  824. content, _ = self.getM3u8(params)
  825. action = {'url': '', 'header': self.header, 'param': '', 'type': 'string'}
  826. return [200, "application/vnd.apple.mpegurl", action, content]
  827. def getM3u8(self, params):
  828. token = params['token']
  829. fileId = params['fileId']
  830. shareId = params['shareId']
  831. key = f'alim3u8Cache_{fileId}_{shareId}'
  832. data = self.getCache(key)
  833. if data:
  834. return data['content'], data['m3u8Infos']
  835. tokenDict = self.getToken(token)
  836. shareToken = self.getshareToken(shareId, '')
  837. params = {
  838. "share_id": shareId,
  839. "category": "live_transcoding",
  840. "file_id": fileId,
  841. "template_id": "",
  842. }
  843. header = self.header.copy()
  844. header['x-share-token'] = shareToken
  845. header['x-device-id'] = tokenDict['device_id']
  846. header['x-signature'] = tokenDict['signature']
  847. header['authorization'] = tokenDict['authorization']
  848. r = self.postJson(
  849. 'https://api.aliyundrive.com/users/v1/users/device/create_session',
  850. json={
  851. 'deviceName': 'Edge浏览器',
  852. 'modelName': 'Windows网页版',
  853. 'pubKey': tokenDict['public_key'],
  854. },
  855. headers=header,
  856. verify=False,
  857. timeout=5)
  858. result = r.json()
  859. if 'success' not in result or not result['success']:
  860. return '', {}
  861. header['authorization'] = tokenDict['authorization']
  862. url = 'https://api.aliyundrive.com/v2/file/get_share_link_video_preview_play_info'
  863. data = self.postJson(url, json=params, headers=header, verify=False, timeout=5).json()
  864. quality = ['UHD', 'QHD', 'FHD', 'HD', 'SD']
  865. videoList = data['video_preview_play_info']['live_transcoding_task_list']
  866. url = ''
  867. for q in quality:
  868. if len(url) > 0:
  869. break
  870. for video in videoList:
  871. if video['template_id'] == q:
  872. url = video['url']
  873. break
  874. r = self.fetch(url, headers=self.header, verify=False, timeout=5)
  875. host = '/'.join(url.split('/')[0:-1]) + '/'
  876. m3u8List = []
  877. m3u8Infos = {}
  878. slices = r.text.split("\n")
  879. count = 0
  880. deadlineList = []
  881. for mediaSlice in slices:
  882. if 'auth_key' in mediaSlice or 'x-oss-expires' in mediaSlice:
  883. try:
  884. if 'auth_key=' in mediaSlice:
  885. deadline = int(self.regStr(reg="auth_key=(\d+)-", src=mediaSlice))
  886. elif 'x-oss-expires=' in mediaSlice:
  887. deadline = int(self.regStr(reg="x-oss-expires=(\d+)", src=mediaSlice))
  888. else:
  889. deadline = int(time.time()) + 660
  890. except:
  891. deadline = int(time.time()) + 660
  892. deadlineList.append(deadline)
  893. count += 1
  894. m3u8Infos[str(count)] = host + mediaSlice
  895. mediaSlice = f"http://127.0.0.1:UndCover/proxy?do=py&type=ts&shareId={shareId}&fileId={fileId}&token={token}&mediaId={count}"
  896. m3u8List.append(mediaSlice)
  897. expiresAt = min(deadlineList) - 60
  898. content = '\n'.join(m3u8List).strip()
  899. self.setCache(key, {'content': content, 'm3u8Infos': m3u8Infos, 'expiresAt': expiresAt})
  900. return content, m3u8Infos
  901. def getshareToken(self, shareId, sharePwd):
  902. key = f'shareToken_{shareId}'
  903. data = self.getCache(key)
  904. if data:
  905. return data['share_token']
  906. params = {
  907. 'share_id': shareId,
  908. 'share_pwd': sharePwd
  909. }
  910. url = 'https://api.aliyundrive.com/v2/share_link/get_share_token'
  911. data = self.postJson(url, json=params, headers=self.header, verify=False, timeout=5).json()
  912. ShareToken = data['share_token']
  913. self.setCache(key, {"share_token": ShareToken, "expiresAt": int(time.time()) + data['expires_in'] - 60})
  914. return ShareToken
  915. def listFiles(self, resultDict, shareId, fileId, shareToken, dirName='', nextMaker='', subtDict={}, folderList=[]):
  916. url = 'https://api.aliyundrive.com/adrive/v3/file/list'
  917. header = self.header.copy()
  918. header['x-share-token'] = shareToken
  919. params = {
  920. 'limit': 200,
  921. 'marker': nextMaker,
  922. 'share_id': shareId,
  923. 'order_by': 'updated_at',
  924. 'parent_file_id': fileId,
  925. 'order_direction': 'DESC',
  926. 'image_url_process': 'image/resize,w_1920/format,jpeg',
  927. 'image_thumbnail_process': 'image/resize,w_160/format,jpeg',
  928. 'video_thumbnail_process': 'video/snapshot,t_1000,f_jpg,ar_auto,w_300'
  929. }
  930. retry = 0
  931. while retry <= 5:
  932. r = self.postJson(url, json=params, headers=header, verify=False, timeout=5)
  933. if r.status_code == 200:
  934. break
  935. retry += 1
  936. data = r.json()
  937. nextMaker = data['next_marker']
  938. if dirName != '':
  939. dirName = '[' + dirName + ']|'
  940. pos = 0
  941. itemsList = sorted(data['items'], key=lambda x: x['name'])
  942. for item in itemsList:
  943. try:
  944. fileExtension = item['file_extension']
  945. except:
  946. fileExtension = ''
  947. if item['type'] == 'folder':
  948. folder = item['file_id'] + '&&&' + item['name']
  949. folderList.append(folder)
  950. else:
  951. if 'video' in item['mime_type'] or 'video' in item['category']:
  952. pos += 1
  953. remark = self.getSize(item['size'])
  954. resultDictKey = dirName + item['name'].replace("#", "_").replace("$", "_") + remark
  955. resultDict[resultDictKey] = str(pos) + '---' + shareId + "+" + shareToken + "+" + item['file_id'] + "+" + item['category'] + "+"
  956. elif 'others' == item['category'] and item['file_extension'] in ['srt', 'ass', 'ssa', 'vtt']:
  957. remark = self.getSize(item['size'])
  958. subtDictKey = dirName + item['name'].replace("#", "_").replace("$", "_") + remark
  959. subtDict[subtDictKey] = item['file_id']
  960. if len(nextMaker) > 0:
  961. self.listFiles(resultDict, shareId, fileId, shareToken, dirName, nextMaker, subtDict, folderList)
  962. for folder in folderList:
  963. folderList.remove(folder)
  964. if '&&&' in folder:
  965. folderInfos = folder.split('&&&')
  966. fileId = folderInfos[0]
  967. dirName = folderInfos[1]
  968. return self.listFiles(resultDict, shareId, fileId, shareToken, dirName, nextMaker, subtDict, folderList)
  969. for vkey in resultDict.keys():
  970. for sKey in subtDict.keys():
  971. if ']|' in sKey:
  972. subKey = sKey.split(']|')[1].split('/[')[0]
  973. else:
  974. subKey = sKey.split('/[')[0]
  975. if subKey + '###' + subtDict[sKey] + '&&&' not in resultDict[vkey]:
  976. resultDict[vkey] = resultDict[vkey] + subKey + '###' + subtDict[sKey] + '&&&'
  977. return resultDict
  978. def getSize(self, size):
  979. size = int(size)
  980. if size > 1024 * 1024 * 1024 * 1024.0:
  981. fs = "TB"
  982. sz = round(size / (1024 * 1024 * 1024 * 1024.0), 2)
  983. elif size > 1024 * 1024 * 1024.0:
  984. fs = "GB"
  985. sz = round(size / (1024 * 1024 * 1024.0), 2)
  986. elif size > 1024 * 1024.0:
  987. fs = "MB"
  988. sz = round(size / (1024 * 1024.0), 2)
  989. elif size > 1024.0:
  990. fs = "KB"
  991. sz = round(size / (1024.0), 2)
  992. else:
  993. fs = "KB"
  994. sz = round(size / (1024.0), 2)
  995. remark = '/[' + str(sz) + fs + ']'
  996. return remark
  997. def getToken(self, token, getOpen=True):
  998. if token.startswith('http'):
  999. token = unquote(token)
  1000. header = {"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"}
  1001. r = self.fetch(token, headers=header, verify=False, timeout=5)
  1002. if 'secret=' in token:
  1003. return r.json()
  1004. else:
  1005. token = r.text.strip()
  1006. tokenDict = self.getCache('aliToken')
  1007. if tokenDict:
  1008. return tokenDict['tokenDict']
  1009. tokenDict = {}
  1010. header = self.header.copy()
  1011. data = self.postJson(url='https://auth.aliyundrive.com/v2/account/token',
  1012. json={'grant_type': 'refresh_token', 'refresh_token': token},
  1013. headers=header,
  1014. verify=False,
  1015. timeout=5).json()
  1016. tokenDict['token'] = data['refresh_token']
  1017. tokenDict['authorization'] = f"{data['token_type']} {data['access_token']}"
  1018. tokenDict['user_id'] = data['user_id']
  1019. tokenDict['drive_id'] = data['default_drive_id']
  1020. tokenDict['device_id'] = data['device_id']
  1021. tokenDict['export_in'] = data['expires_in']
  1022. header['authorization'] = tokenDict['authorization']
  1023. # 获取 opentoken
  1024. if getOpen:
  1025. try:
  1026. header['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) aDrive/4.1.0 Chrome/108.0.5359.215 Electron/22.3.1 Safari/537.36'
  1027. r = self.postJson(
  1028. url='https://open.aliyundrive.com/oauth/users/authorize?client_id=76917ccccd4441c39457a04f6084fb2f&redirect_uri=https://alist.nn.ci/tool/aliyundrive/callback&scope=user:base,file:all:read,file:all:write&state=',
  1029. json={
  1030. 'authorize': 1,
  1031. 'scope': 'user:base,file:all:read,file:all:write'
  1032. },
  1033. headers=header,
  1034. verify=False,
  1035. timeout=5)
  1036. code = self.regStr(r.text, 'code=(.*?)\"')
  1037. data = self.postJson(url='https://api-cf.nn.ci/alist/ali_open/code',
  1038. json={
  1039. 'code': code,
  1040. 'grant_type': 'authorization_code'
  1041. },
  1042. headers=header,
  1043. verify=False,
  1044. timeout=5).json()
  1045. openExportIn = data['expires_in']
  1046. openToken = data['refresh_token']
  1047. opAuthorization = f"{data['token_type']} {data['access_token']}"
  1048. except:
  1049. openToken = ''
  1050. opAuthorization = ''
  1051. openExportIn = 7200
  1052. else:
  1053. openToken = ''
  1054. opAuthorization = ''
  1055. openExportIn = 7200
  1056. tokenDict['open_token'] = openToken
  1057. tokenDict['open_authorization'] = opAuthorization
  1058. tokenDict['expires_at'] = int(int(time.time()) + min(tokenDict['export_in'], openExportIn) / 2)
  1059. # 获取 signature 和 public_key
  1060. params = {"user_id": tokenDict['user_id'], "device_id": tokenDict['device_id']}
  1061. data = self.fetch(f"https://api-lmteam.koyeb.app/proxy?spider=apifan&function=aliSignature&params={quote(json.dumps(params))}").json()
  1062. tokenDict['public_key'] = data['public_key']
  1063. tokenDict['signature'] = data['signature']
  1064. self.setCache('aliToken', {"tokenDict": tokenDict, "expiresAt": tokenDict['expires_at']})
  1065. return tokenDict
  1066. def getDanmaku(self, name, pos):
  1067. info = []
  1068. pos = int(pos)
  1069. pos = pos - 1
  1070. if pos < 0:
  1071. pos = 0
  1072. try:
  1073. url = f'https://api.so.360kan.com/index?force_v=1&kw={name}&from=&pageno=1&v_ap=1&tab=all'
  1074. header = {
  1075. 'Referer': 'https://so.360kan.com/',
  1076. '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'}
  1077. r = self.fetch(url, headers=header, timeout=15)
  1078. diffList = []
  1079. vodList = r.json()['data']['longData']['rows']
  1080. for vod in vodList:
  1081. diffList.append(SequenceMatcher(None, vod['titleTxt'], name).ratio())
  1082. diffList.sort(reverse=True)
  1083. for i in range(0, len(diffList)):
  1084. infos = vodList[i]
  1085. enId = infos['en_id']
  1086. catId = infos['cat_id']
  1087. videoType = infos['cat_name']
  1088. if videoType in ["电影", "电视剧"]:
  1089. if 'seriesPlaylinks' in infos and len(infos['seriesPlaylinks']) != 0:
  1090. if type(infos['seriesPlaylinks'][-1]) == str:
  1091. info = infos['seriesPlaylinks'][:-1]
  1092. info.append({'url': infos['seriesPlaylinks'][-1]})
  1093. else:
  1094. info = infos['seriesPlaylinks']
  1095. else:
  1096. site = list(infos['playlinks'].keys())[0]
  1097. if type(infos['playlinks'][site]) == str:
  1098. info = [{'url': infos['playlinks'][site]}]
  1099. else:
  1100. info = infos['playlinks'][site]
  1101. elif videoType == '动漫':
  1102. site = list(infos['playlinks'].keys())[0]
  1103. s = quote(f'[{{\"cat_id\": \"{catId}\", \"ent_id\": \"{enId}\", \"site\": \"{site}\"}}]')
  1104. r = self.fetch(f'https://api.so.360kan.com/episodesv2?v_ap=1&s={s}', headers=header, timeout=15)
  1105. data = r.json()['data'][0]['seriesHTML']
  1106. if 'seriesPlaylinks' in data and len(data['seriesPlaylinks']) != 0:
  1107. if type(data['seriesPlaylinks'][-1]) == str:
  1108. info = data['seriesPlaylinks'][:-1]
  1109. info.append({'url': data['seriesPlaylinks'][-1]})
  1110. else:
  1111. info = data['seriesPlaylinks']
  1112. else:
  1113. if type(data['playlinks'][site]) == str:
  1114. info = [{'url': data['playlinks'][site]}]
  1115. else:
  1116. info = data['playlinks'][site]
  1117. retry = 0
  1118. while enId != data['en_id'] and retry < 10:
  1119. retry += 1
  1120. site = list(infos['playlinks'].keys())[0]
  1121. s = quote(f'[{{\"cat_id\": \"{catId}\", \"ent_id\": \"{enId}\", \"site\": \"{site}\"}}]')
  1122. r = self.fetch(f'https://api.so.360kan.com/episodesv2?v_ap=1&s={s}', headers=header, timeout=15)
  1123. data = r.json()['data'][0]['seriesHTML']
  1124. enId = data['en_id']
  1125. if 'seriesPlaylinks' in data and len(data['seriesPlaylinks']) != 0:
  1126. if type(data['seriesPlaylinks'][-1]) == str:
  1127. info.append(data['seriesPlaylinks'][:-1])
  1128. info.append({'url': data['seriesPlaylinks'][-1]})
  1129. else:
  1130. info.append(data['seriesPlaylinks'])
  1131. else:
  1132. site = list(data['playlinks'].keys())[0]
  1133. if type(data['playlinks'][site]) == str:
  1134. info.append([{'url': data['playlinks'][site]}])
  1135. else:
  1136. info.append(data['playlinks'][site])
  1137. elif videoType == '综艺':
  1138. site = list(infos['playlinks'].keys())[0]
  1139. enTid = infos['id']
  1140. year = infos['year']
  1141. offset = int(infos['playlinks_total'][site]) - 1 - pos
  1142. if offset >= 5:
  1143. r = self.fetch(f'https://api.so.360kan.com/episodeszongyi?site={site}&y={year}&entid={enTid}&offset={offset}&count=8', headers=header, timeout=15)
  1144. data = r.json()['data']['list']
  1145. if data:
  1146. pos = 0
  1147. info = [{'url': data[0]['url']}]
  1148. else:
  1149. if 'seriesPlaylinks' in infos and len(infos['seriesPlaylinks']) != 0:
  1150. if type(infos['seriesPlaylinks'][-1]) == str:
  1151. info = infos['seriesPlaylinks'][:-1]
  1152. info.append({'url': infos['seriesPlaylinks'][-1]})
  1153. else:
  1154. info = infos['seriesPlaylinks']
  1155. else:
  1156. if type(infos['playlinks'][site]) == str:
  1157. info = [{'url': infos['playlinks'][site]}]
  1158. else:
  1159. info = infos['playlinks'][site]
  1160. try:
  1161. url = info[pos]['url']
  1162. break
  1163. except:
  1164. pass
  1165. if 'qq.com' in url:
  1166. params = {'platform': 'qq', 'url': url}
  1167. elif 'mgtv.com' in url:
  1168. params = {'platform': 'mgtv', 'url': url}
  1169. elif 'iqiyi.com' in url:
  1170. params = {'platform': 'iqiyi', 'url': url}
  1171. elif 'youku.com' in url:
  1172. params = {'platform': 'youku', 'url': url}
  1173. elif 'bilibili.com' in url:
  1174. params = {'platform': 'bilibili', 'url': url}
  1175. else:
  1176. return None
  1177. return params
  1178. except:
  1179. pass
  1180. def getContent(self, params, header={}):
  1181. pf = params['pf']
  1182. try:
  1183. if pf == 'cz':
  1184. header = {
  1185. 'Referer': 'https://www.czzy88.com/',
  1186. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36',
  1187. }
  1188. url = params['url']
  1189. data = self.getCache('czCookie')
  1190. if data:
  1191. cookie = data['cookieDict'].copy()
  1192. r = self.fetch(params['url'], headers=header, verify=False, cookies=cookie, timeout=5)
  1193. if 'huadong' in r.text or 'renji' in r.text or 'btwaf' in r.text:
  1194. self.delCache('czCookie')
  1195. return self.getContent(params, header)
  1196. return r
  1197. from requests import session
  1198. session = session()
  1199. r = session.get(url, headers=header, verify=False, timeout=5)
  1200. content = r.content.decode()
  1201. cookie = session.cookies
  1202. if 'huadong' in content or 'renji' in content:
  1203. url = 'https://www.czzy88.com' + self.regStr(content, 'src=\"(.*?)\"')
  1204. r = session.get(url, headers=header, verify=False, timeout=5)
  1205. if 'huadong' in url:
  1206. key = self.regStr(r.text, 'key=\"(.*?)\"')
  1207. value = self.regStr(r.text, 'value=\"(.*?)\"')
  1208. val = ""
  1209. for i in range(len(value)):
  1210. code = ord(value[i])
  1211. val += str(code + 1)
  1212. value = hashlib.md5(val.encode()).hexdigest()
  1213. url = 'https://www.czzy88.com{}&key={}&value={}'.format(self.regStr(r.text, 'c.get\(\"(\S+\?type=\S+)&key='), key, value)
  1214. session.get(url, headers=header, verify=False, timeout=5)
  1215. cookie = session.cookies
  1216. elif 'renji' in url:
  1217. key = self.regStr(r.text, 'var key=\"(.*?)\"')
  1218. value = self.regStr(r.text, 'value=\"(.*?)\"')
  1219. val = ''
  1220. for i in range(0, len(value)):
  1221. code = ord(value[i])
  1222. val += str(code)
  1223. value = hashlib.md5(val.encode()).hexdigest()
  1224. url = 'https://www.czzy88.com{}&key={}&value={}'.format(self.regStr(r.text, 'c.get\(\"(\S+\?type=\S+)&key='), key, value)
  1225. session.get(url, headers=header, verify=False, timeout=5)
  1226. cookie = session.cookies
  1227. r = session.get(params['url'], headers=header, verify=False, cookies=cookie, timeout=5)
  1228. elif 'btwaf' in content:
  1229. imgData = session.get('https://www.czzy88.com/get_btwaf_captcha_base64?captcha={}'.format(int(time.time())), timeout=5).json()['msg']
  1230. code = self.postJson('https://api-lmteam.koyeb.app/ocr', json={'imgList': [imgData], 'lenth': 4}).json()['result']
  1231. session.get(f'https://www.czzy88.com/Verification_auth_btwaf?captcha={code}', headers=header, timeout=5)
  1232. cookie = session.cookies
  1233. r = session.get(params['url'], headers=header, verify=False, cookies=cookie, timeout=5)
  1234. else:
  1235. r._content = content.encode('utf-8')
  1236. r.cookies = session.cookies
  1237. r.url = url
  1238. try:
  1239. result = int(self.regStr(r.text, 'method=\"post\">(\d+) \+ (\d+) =', 1)) + int(self.regStr(r.text, 'method=\"post\">(\d+) \+ (\d+) =', 2))
  1240. cookie.set('result', str(result))
  1241. cookie.set('esc_search_captcha', '1')
  1242. r = session.get(params['url'], headers=header, verify=False, cookies=cookie, timeout=5)
  1243. session.close()
  1244. except:
  1245. session.close()
  1246. self.setCache('czCookie', {'cookieDict': cookie.get_dict(), 'expiresAt': int(time.time()) + 5400})
  1247. return r
  1248. else:
  1249. return None
  1250. except:
  1251. return None
  1252. def getCache(self, key):
  1253. # value = self.fetch(f'http://192.168.1.254:9978/cache?do=get&key={key}', timeout=5).text
  1254. value = self.fetch(f'http://127.0.0.1:9978/cache?do=get&key={key}', timeout=5).text
  1255. if len(value) > 0:
  1256. if value.startswith('{') and value.endswith('}') or value.startswith('[') and value.endswith(']'):
  1257. value = json.loads(value)
  1258. if type(value) == dict:
  1259. if not 'expiresAt' in value or value['expiresAt'] >= int(time.time()):
  1260. return value
  1261. else:
  1262. self.delCache(key)
  1263. return None
  1264. return value
  1265. else:
  1266. return None
  1267. def setCache(self, key, value):
  1268. if len(value) > 0:
  1269. if type(value) == dict or type(value) == list:
  1270. value = json.dumps(value, ensure_ascii=False)
  1271. # self.post(f'http://192.168.1.254:9978/cache?do=set&key={key}', data={"value": value}, timeout=5)
  1272. self.post(f'http://127.0.0.1:9978/cache?do=set&key={key}', data={"value": value}, timeout=5)
  1273. def delCache(self, key):
  1274. self.fetch(f'http://127.0.0.1:9978/cache?do=del&key={key}', timeout=5)