alist.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. # coding=utf-8
  2. # !/usr/bin/python
  3. import sys
  4. sys.path.append('..')
  5. from base.spider import Spider
  6. import json
  7. import re
  8. import urllib
  9. import difflib
  10. class Spider(Spider): # 元类 默认的元类 type
  11. def getName(self):
  12. return "Alist"
  13. def init(self, extend=""):
  14. print("============{0}============".format(extend))
  15. pass
  16. def isVideoFormat(self, url):
  17. pass
  18. def manualVideoCheck(self):
  19. pass
  20. def homeContent(self, filter):
  21. result = {}
  22. cateManual = {
  23. "七米蓝": "https://al.chirmyram.com",
  24. "杜比": "https://dubi.tk",
  25. "神器云": "https://al.chirmyram.com",
  26. "甜蜜2": "https://alist3.kebedd69.repl.co",
  27. "xiaoya2": "http://myalist.site",
  28. "xiaoya3": "http://alist.xiaoya.pro",
  29. "甜蜜": "https://alist.kebedd69.repl.co",
  30. "梅花盘": "https://pan.142856.xyz/OneDrive",
  31. "触光云盘": "https://pan.ichuguang.com",
  32. "小孟资源": "https://8023.haohanba.cn/小孟丨资源大合集/无损音乐",
  33. "资源小站": "https://960303.xyz/ali",
  34. "轻弹浅唱": "https://g.xiang.lol",
  35. "小兵组网盘视频": "https://6vv.app"
  36. }
  37. classes = []
  38. for k in cateManual:
  39. classes.append({
  40. 'type_name': k,
  41. "type_flag": "1",
  42. 'type_id': cateManual[k]
  43. })
  44. result['class'] = classes
  45. if (filter):
  46. filters = {}
  47. for lk in cateManual:
  48. link = cateManual[lk]
  49. filters.update({
  50. link: [{"key": "nm", "name": "名 称", "value": [{"n": "复位", "v": ""},{"n": "正序", "v": "False"},{"n": "反序", "v": "True"}]},{"key": "sz", "name": "大 小", "value": [{"n": "复位", "v": ""},{"n": "升序", "v": "False"},{"n": "降序", "v": "True"}]},{"key": "tp", "name": "类 型", "value": [{"n": "复位", "v": ""},{"n": "升序", "v": "False"},{"n": "降序", "v": "True"}]},{"key": "tm", "name": "修改时间", "value": [{"n": "复位", "v": ""},{"n": "升序", "v": "False"},{"n": "降序", "v": "True"}]}]
  51. })
  52. result['filters'] = filters
  53. return result
  54. def homeVideoContent(self):
  55. result = {
  56. 'list': []
  57. }
  58. return result
  59. ver = ''
  60. baseurl = ''
  61. def getVersion(self, gtid):
  62. param = {
  63. "path": '/'
  64. }
  65. if gtid.count('/') == 2:
  66. gtid = gtid + '/'
  67. baseurl = re.findall(r"http.*://.*?/", gtid)[0]
  68. ver = self.fetch(baseurl + 'api/public/settings', param)
  69. vjo = json.loads(ver.text)['data']
  70. if type(vjo) is dict:
  71. ver = 3
  72. else:
  73. ver = 2
  74. self.ver = ver
  75. self.baseurl = baseurl
  76. def categoryContent(self, tid, pg, filter, extend):
  77. result = {}
  78. if tid.count('/') == 2:
  79. tid = tid + '/'
  80. nurl = re.findall(r"http.*://.*?/", tid)[0]
  81. if self.ver == '' or self.baseurl != nurl:
  82. self.getVersion(tid)
  83. ver = self.ver
  84. baseurl = self.baseurl
  85. if tid.count('/') == 2:
  86. tid = tid + '/'
  87. pat = tid.replace(baseurl,"")
  88. param = {
  89. "path": '/' + pat
  90. }
  91. if ver == 2:
  92. rsp = self.postJson(baseurl + 'api/public/path', param)
  93. jo = json.loads(rsp.text)
  94. vodList = jo['data']['files']
  95. elif ver == 3:
  96. rsp = self.postJson(baseurl + 'api/fs/list', param)
  97. jo = json.loads(rsp.text)
  98. vodList = jo['data']['content']
  99. ovodList = vodList
  100. if len(extend) != 0:
  101. if 'tp' in extend and extend['tp'] != '':
  102. fl = 'type'
  103. if extend['tp'] == "True":
  104. key = True
  105. if extend['tp'] == "False":
  106. key = False
  107. vodList.sort(key=lambda x: (x['{0}'.format(fl)]), reverse=key)
  108. elif 'sz' in extend and extend['sz'] != '':
  109. fl = 'size'
  110. if extend['sz'] == "True":
  111. key = True
  112. if extend['sz'] == "False":
  113. key = False
  114. vodList.sort(key=lambda x: (x['{0}'.format(fl)]), reverse=key)
  115. elif 'nm' in extend and extend['nm'] != '':
  116. fl = 'name'
  117. if extend['nm'] == "True":
  118. key = True
  119. if extend['nm'] == "False":
  120. key = False
  121. vodList.sort(key=lambda x: (x['{0}'.format(fl)]), reverse=key)
  122. elif 'tm' in extend and extend['tm'] != '':
  123. if ver == 2:
  124. fl = 'updated_at'
  125. elif ver == 3:
  126. fl = 'modified'
  127. if extend['tm'] == "True":
  128. key = True
  129. if extend['tm'] == "False":
  130. key = False
  131. vodList.sort(key=lambda x: (x['{0}'.format(fl)]), reverse=key)
  132. else:
  133. vodList = ovodList
  134. else:
  135. vodList = ovodList
  136. videos = []
  137. cid = ''
  138. purl = ''
  139. svodList = str(vodList)
  140. lenvodList = len(vodList)
  141. nameList = re.findall(r"\'name\': \'(.*?)\'", svodList)
  142. substr = str(nameList)
  143. foldernum = svodList.count('\'type\': 1')
  144. filenum = lenvodList - foldernum
  145. for vod in vodList:
  146. if ver == 2:
  147. img = vod['thumbnail']
  148. elif ver == 3:
  149. img = vod['thumb']
  150. if len(img) == 0:
  151. if vod['type'] == 1:
  152. img = "http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png"
  153. if pat != '':
  154. aid = pat + '/'
  155. else:
  156. aid = pat
  157. if vod['type'] == 1:
  158. tag = "folder"
  159. remark = "文件夹"
  160. cid = baseurl + aid + vod['name']
  161. #计算文件大小
  162. else:
  163. size = vod['size']
  164. if size > 1024 * 1024 * 1024 * 1024.0:
  165. fs = "TB"
  166. sz = round(size / (1024 * 1024 * 1024 * 1024.0), 2)
  167. elif size > 1024 * 1024 * 1024.0:
  168. fs = "GB"
  169. sz = round(size / (1024 * 1024 * 1024.0), 2)
  170. elif size > 1024 * 1024.0:
  171. fs = "MB"
  172. sz = round(size / (1024 * 1024.0), 2)
  173. elif size > 1024.0:
  174. fs = "KB"
  175. sz = round(size / (1024.0), 2)
  176. else:
  177. fs = "KB"
  178. sz = round(size / (1024.0), 2)
  179. tag = "file"
  180. remark = str(sz) + fs
  181. cid = baseurl + aid + vod['name']
  182. # 开始爬视频与字幕
  183. if filenum < 150:
  184. if vod['name'].endswith('.mp4') or vod['name'].endswith('.mkv') or vod['name'].endswith('.ts') or vod['name'].endswith('.TS') or vod['name'].endswith('.avi') or vod['name'].endswith('.flv') or vod['name'].endswith('.rmvb') or vod['name'].endswith('.mp3') or vod['name'].endswith('.flac') or vod['name'].endswith('.wav') or vod['name'].endswith('.wma') or vod['name'].endswith('.dff'):
  185. vodurl = vod['name']
  186. # 开始爬字幕
  187. cid = '###'
  188. subname = re.findall(r"(.*)\.", vod['name'])[0]
  189. if filenum == 2:
  190. if '.ass' in substr:
  191. sub = difflib.get_close_matches('.ass', nameList, 1, cutoff=0.1)
  192. if len(sub) != 0:
  193. sub = sub[0]
  194. else:
  195. sub = ''
  196. if sub.endswith('.ass'):
  197. subt = '@@@' + sub
  198. if '.srt' in substr:
  199. sub = difflib.get_close_matches('.srt', nameList, 1, cutoff=0.1)
  200. if len(sub) != 0:
  201. sub = sub[0]
  202. else:
  203. sub = ''
  204. if sub.endswith('.srt'):
  205. subt = '@@@' + sub
  206. else:
  207. if '.ass' in substr:
  208. sub = difflib.get_close_matches('{0}.ass'.format(subname), nameList, 1, cutoff=0.1)
  209. if len(sub) != 0:
  210. sub = sub[0]
  211. else:
  212. sub = ''
  213. if subname in sub and sub.endswith('.ass'):
  214. subt = '@@@' + sub
  215. elif '.srt' in substr:
  216. sub = difflib.get_close_matches('{0}.srt'.format(subname), nameList, 1, cutoff=0.1)
  217. if len(sub) != 0:
  218. sub = sub[0]
  219. else:
  220. sub = ''
  221. if subname in sub and sub.endswith('.srt'):
  222. subt = '@@@' + sub
  223. # 合并链接
  224. if 'subt' in locals().keys():
  225. purl = purl + '{0}{1}##'.format(vodurl, subt)
  226. else:
  227. purl = purl + '{0}##'.format(vodurl)
  228. else:
  229. subname = re.findall(r"(.*)\.", vod['name'])[0]
  230. if '.ass' in substr:
  231. sub = difflib.get_close_matches('{0}.ass'.format(subname), nameList, 1, cutoff=0.1)
  232. if len(sub) != 0:
  233. sub = sub[0]
  234. else:
  235. sub = ''
  236. if subname in sub and sub.endswith('.ass'):
  237. subt = '@@@' + sub
  238. cid = cid + subt
  239. elif '.srt' in substr:
  240. sub = difflib.get_close_matches('{0}.srt'.format(subname), nameList, 1, cutoff=0.1)
  241. if len(sub) != 0:
  242. sub = sub[0]
  243. else:
  244. sub = ''
  245. if subname in sub and sub.endswith('.srt'):
  246. subt = '@@@' + sub
  247. cid = cid + subt
  248. videos.append({
  249. "vod_id": cid,
  250. "vod_name": vod['name'],
  251. "vod_pic": img,
  252. "vod_tag": tag,
  253. "vod_remarks": remark
  254. })
  255. if 'purl' in locals().keys():
  256. purl = baseurl + aid + '+++' + purl
  257. for i in range(foldernum, lenvodList):
  258. if videos[i]['vod_id'] == '###':
  259. videos[i]['vod_id'] = purl
  260. result['list'] = videos
  261. result['page'] = 1
  262. result['pagecount'] = 1
  263. result['limit'] = lenvodList
  264. result['total'] = lenvodList
  265. return result
  266. def detailContent(self, array):
  267. id = array[0]
  268. if '+++' in id:
  269. ids = id.split('+++')
  270. durl = ids[0]
  271. vsList = ids[1].strip('##').split('##')
  272. vsurl = ''
  273. for vs in vsList:
  274. if '@@@' in vs:
  275. dvs = vs.split('@@@')
  276. vname = dvs[0].replace('#','-')
  277. vurl = durl + dvs[0].replace('#','---')
  278. surl = durl + dvs[1].replace('#','---')
  279. vsurl = vsurl + '{0}${1}@@@{2}#'.format(vname, vurl, surl)
  280. else:
  281. vurl = durl + vs.replace('#','---')
  282. vsurl = vsurl + '{0}${1}#'.format(vs.replace('#','-'), vurl)
  283. url = vsurl
  284. else:
  285. durl = id.replace('#','-')
  286. if self.ver == '' or self.baseurl == '':
  287. self.getVersion(durl)
  288. baseurl = self.baseurl
  289. if '+++' in id:
  290. vid = durl.replace(baseurl, "").strip('/')
  291. else:
  292. vid = durl.replace(re.findall(r".*/", durl)[0], "")
  293. url = vid + '$' + id.replace('#','---')
  294. vod = {
  295. "vod_id": vid,
  296. "vod_name": vid,
  297. "vod_pic": '',
  298. "vod_tag": '',
  299. "vod_play_from": "播放",
  300. "vod_play_url": url
  301. }
  302. result = {
  303. 'list': [
  304. vod
  305. ]
  306. }
  307. return result
  308. def searchContent(self, key, quick):
  309. result = {
  310. 'list': []
  311. }
  312. return result
  313. def playerContent(self, flag, id, vipFlags):
  314. result = {}
  315. url = ''
  316. subturl = ''
  317. id = id.replace('---','#')
  318. ifsub = '@@@' in id
  319. if ifsub is True:
  320. ids = id.split('@@@')
  321. if self.ver == '' or self.baseurl == '':
  322. self.getVersion(ids[1])
  323. ver = self.ver
  324. baseurl = self.baseurl
  325. fileName = ids[1].replace(baseurl, "")
  326. vfileName = ids[0].replace(baseurl, "")
  327. param = {
  328. "path": '/' + fileName,
  329. "password": "",
  330. "page_num": 1,
  331. "page_size": 100
  332. }
  333. vparam = {
  334. "path": '/' + vfileName,
  335. "password": "",
  336. "page_num": 1,
  337. "page_size": 100
  338. }
  339. if ver == 2:
  340. rsp = self.postJson(baseurl + 'api/public/path', param)
  341. jo = json.loads(rsp.text)
  342. vodList = jo['data']['files'][0]
  343. subturl = vodList['url']
  344. vrsp = self.postJson(baseurl + 'api/public/path', vparam)
  345. vjo = json.loads(vrsp.text)
  346. vList = vjo['data']['files'][0]
  347. url = vList['url']
  348. elif ver == 3:
  349. rsp = self.postJson(baseurl + 'api/fs/get', param)
  350. jo = json.loads(rsp.text)
  351. vodList = jo['data']
  352. subturl = vodList['raw_url']
  353. vrsp = self.postJson(baseurl + 'api/fs/get', vparam)
  354. vjo = json.loads(vrsp.text)
  355. vList = vjo['data']
  356. url = vList['raw_url']
  357. if subturl.startswith('http') is False:
  358. head = re.findall(r"h.*?:", baseurl)[0]
  359. subturl = head + subturl
  360. if url.startswith('http') is False:
  361. head = re.findall(r"h.*?:", baseurl)[0]
  362. url = head + url
  363. urlfileName = urllib.parse.quote(fileName)
  364. subturl = subturl.replace(fileName, urlfileName)
  365. urlvfileName = urllib.parse.quote(vfileName)
  366. url = url.replace(vfileName, urlvfileName)
  367. result['subt'] = subturl
  368. else:
  369. if self.ver == '' or self.baseurl == '':
  370. self.getVersion(id)
  371. ver = self.ver
  372. baseurl = self.baseurl
  373. vfileName = id.replace(baseurl, "")
  374. vparam = {
  375. "path": '/' + vfileName,
  376. "password": "",
  377. "page_num": 1,
  378. "page_size": 100
  379. }
  380. if ver == 2:
  381. vrsp = self.postJson(baseurl + 'api/public/path', vparam)
  382. vjo = json.loads(vrsp.text)
  383. vList = vjo['data']['files'][0]
  384. driver = vList['driver']
  385. url = vList['url']
  386. elif ver == 3:
  387. vrsp = self.postJson(baseurl + 'api/fs/get', vparam)
  388. vjo = json.loads(vrsp.text)
  389. vList = vjo['data']
  390. url = vList['raw_url']
  391. driver = vList['provider']
  392. if url.startswith('http') is False:
  393. head = re.findall(r"h.*?:", baseurl)[0]
  394. url = head + url
  395. urlvfileName = urllib.parse.quote(vfileName)
  396. url = url.replace(vfileName, urlvfileName)
  397. if driver == 'Baidu.Disk':
  398. result["header"] = {"User-Agent": "pan.baidu.com"}
  399. result["parse"] = 0
  400. result["playUrl"] = ''
  401. result["url"] = url
  402. return result
  403. flurl = ''
  404. config = {
  405. "player": {},
  406. "filter": {}
  407. }
  408. header = {}
  409. def localProxy(self, param):
  410. return [200, "video/MP2T", action, ""]