py_alist.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  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. class Spider(Spider): # 元类 默认的元类 type
  10. def getName(self):
  11. return "Alist"
  12. def init(self, extend=""):
  13. print("============{0}============".format(extend))
  14. pass
  15. def isVideoFormat(self, url):
  16. pass
  17. def manualVideoCheck(self):
  18. pass
  19. def homeContent(self, filter):
  20. result = {}
  21. cateManual = {
  22. "老蹦跶":"https://alist-xyabb.run.goorm.site",
  23. "资源小站": "https://960303.xyz/",
  24. "菊花盘": "https://pan.142856.xyz",
  25. "轻弹浅唱": "https://g.xiang.lol",
  26. "🚆资源小站":"https://pan.142856.xyz",
  27. "🌤晴园的宝藏库":"https://alist.52qy.repl.co",
  28. "米奇妙妙屋":"https://anime.mqmmw.ga",
  29. "小兵组网盘影视":"https://6vv.app",
  30. "🐋一只鱼":"https://alist.youte.ml",
  31. "七米蓝":"https://al.chirmyram.com",
  32. "🥼帅盘":"https://hi.shuaipeng.wang",
  33. "🐉神族九帝":"https://alist.shenzjd.com",
  34. "大人":"https://drive.9t.ee",
  35. "大人番":"https://www.kugutsu.ml"
  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": "False"},{"n": "反序", "v": "True"}]},{"key": "sz", "name": "大 小", "value": [{"n": "升序", "v": "False"},{"n": "降序", "v": "True"}]},{"key": "tp", "name": "类 型", "value": [{"n": "升序", "v": "False"},{"n": "降序", "v": "True"}]},{"key": "tm", "name": "修改时间", "value": [{"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:
  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:
  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:
  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:
  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. substr = str(re.findall(r"\'name\': \'(.*?)\'", svodList))
  142. foldernum = svodList.count('\'type\': 1')
  143. filenum = lenvodList - foldernum
  144. for vod in vodList:
  145. if ver == 2:
  146. img = vod['thumbnail']
  147. elif ver == 3:
  148. img = vod['thumb']
  149. if len(img) == 0:
  150. if vod['type'] == 1:
  151. img = "http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png"
  152. if pat != '':
  153. aid = pat + '/'
  154. else:
  155. aid = pat
  156. if vod['type'] == 1:
  157. tag = "folder"
  158. remark = "文件夹"
  159. cid = baseurl + aid + vod['name']
  160. #计算文件大小
  161. else:
  162. size = vod['size']
  163. if size > 1024 * 1024 * 1024 * 1024.0:
  164. fs = "TB"
  165. sz = round(size / (1024 * 1024 * 1024 * 1024.0), 2)
  166. elif size > 1024 * 1024 * 1024.0:
  167. fs = "GB"
  168. sz = round(size / (1024 * 1024 * 1024.0), 2)
  169. elif size > 1024 * 1024.0:
  170. fs = "MB"
  171. sz = round(size / (1024 * 1024.0), 2)
  172. elif size > 1024.0:
  173. fs = "KB"
  174. sz = round(size / (1024.0), 2)
  175. else:
  176. fs = "KB"
  177. sz = round(size / (1024.0), 2)
  178. tag = "file"
  179. remark = str(sz) + fs
  180. cid = baseurl + aid + vod['name']
  181. # 开始爬视频与字幕
  182. if filenum < 150:
  183. if 'mp4' in vod['name'] or 'mkv' in vod['name'] or 'TS' in vod['name'] or 'flv' in vod['name'] or 'rmvb' in vod['name'] or 'mp3' in vod['name'] or 'flac' in vod['name'] or 'wav' in vod['name'] or 'wma' in vod['name'] or 'dff' in vod['name']:
  184. vodurl = vod['name']
  185. # 开始爬字幕
  186. cid = '###'
  187. subname = re.findall(r"(.*)\.", vod['name'])[0]
  188. if filenum == 2:
  189. if '.ass' in substr:
  190. sub = re.findall(r"'(.*)\.ass", substr)[0]
  191. subt = '@@@' + sub + '.ass'
  192. if ',' in sub:
  193. sub = re.findall(r"', '(.*)\.ass", substr)[0]
  194. subt = '@@@' + sub + '.ass'
  195. if '.srt' in substr:
  196. sub = re.findall(r"'(.*)\.srt", substr)[0]
  197. subt = '@@@' + sub + '.srt'
  198. if ',' in sub:
  199. sub = re.findall(r"', '(.*)\.srt", substr)[0]
  200. subt = '@@@' + sub + '.srt'
  201. else:
  202. if '.ass' in substr:
  203. if '(' in subname or ')' in subname or '[' in subname or ']' in subname:
  204. subname = subname.replace("(","\(").replace(")","\)").replace("[","\[").replace("]","\]")
  205. sub = re.findall(r"{0}.*?\.ass".format(subname), substr)
  206. if len(sub) != 0:
  207. sub = sub[0]
  208. else:
  209. sub = ''
  210. if ',' in sub:
  211. lsub = sub.replace('\'',"").split(', ')
  212. sub = lsub[len(lsub)-1]
  213. if '(' in subname or ')' in subname or '[' in subname or ']' in subname:
  214. ssubname = subname.replace("\(","(").replace("\)",")").replace("\[","[").replace("\]","]")
  215. if subname in sub:
  216. subt = '@@@' + sub
  217. elif '.srt' in substr:
  218. if '(' in subname or ')' in subname or '[' in subname or ']' in subname:
  219. subname = subname.replace("(","\(").replace(")","\)").replace("[","\[").replace("]","\]")
  220. sub = re.findall(r'{0}.*?\.srt'.format(subname), substr)
  221. if len(sub) != 0:
  222. sub = sub[0]
  223. else:
  224. sub = ''
  225. if ',' in sub:
  226. lsub = sub.replace('\'',"").split(', ')
  227. sub = lsub[len(lsub)-1]
  228. if '(' in subname or ')' in subname or '[' in subname or ']' in subname:
  229. subname = subname.replace("\(","(").replace("\)",")").replace("\[","[").replace("\]","]")
  230. if subname in sub:
  231. subt = '@@@' + sub
  232. # 合并链接
  233. if 'subt' in locals().keys():
  234. purl = purl + '{0}{1}#'.format(vodurl, subt)
  235. else:
  236. purl = purl + '{0}#'.format(vodurl)
  237. else:
  238. subname = re.findall(r"(.*)\.", vod['name'])[0]
  239. if '.ass' in substr:
  240. if '(' in subname or ')' in subname or '[' in subname or ']' in subname:
  241. subname = subname.replace("(","\(").replace(")","\)").replace("[","\[").replace("]","\]")
  242. sub = re.findall(r"{0}.*?\.ass".format(subname), substr)
  243. if len(sub) != 0:
  244. sub = sub[0]
  245. else:
  246. sub = ''
  247. if ',' in sub:
  248. lsub = sub.replace('\'', "").split(', ')
  249. sub = lsub[len(lsub) - 1]
  250. if '(' in subname or ')' in subname or '[' in subname or ']' in subname:
  251. subname = subname.replace("\(","(").replace("\)",")").replace("\[","[").replace("\]","]")
  252. if subname in sub:
  253. subt = '@@@' + sub
  254. cid = cid + subt
  255. elif '.srt' in substr:
  256. if '(' in subname or ')' in subname or '[' in subname or ']' in subname:
  257. subname = subname.replace("(","\(").replace(")","\)").replace("[","\[").replace("]","\]")
  258. sub = re.findall(r"{0}.*?\.srt".format(subname), substr)
  259. if len(sub) != 0:
  260. sub = sub[0]
  261. else:
  262. sub = ''
  263. if ',' in sub:
  264. lsub = sub.replace('\'', "").split(', ')
  265. sub = lsub[len(lsub) - 1]
  266. if '(' in subname or ')' in subname or '[' in subname or ']' in subname:
  267. subname = subname.replace("\(","(").replace("\)",")").replace("\[","[").replace("\]","]")
  268. if subname in sub:
  269. subt = '@@@' + sub
  270. cid = cid + subt
  271. videos.append({
  272. "vod_id": cid,
  273. "vod_name": vod['name'],
  274. "vod_pic": img,
  275. "vod_tag": tag,
  276. "vod_remarks": remark
  277. })
  278. if 'purl' in locals().keys():
  279. purl = baseurl + aid + '+++' + purl
  280. for i in range(foldernum, lenvodList):
  281. if videos[i]['vod_id'] == '###':
  282. videos[i]['vod_id'] = purl
  283. result['list'] = videos
  284. result['page'] = 1
  285. result['pagecount'] = 1
  286. result['limit'] = 999
  287. result['total'] = 999999
  288. return result
  289. def detailContent(self, array):
  290. id = array[0]
  291. if '+++' in id:
  292. ids = id.split('+++')
  293. durl = ids[0]
  294. vsList = ids[1].strip('#').split('#')
  295. vsurl = ''
  296. for vs in vsList:
  297. if '@@@' in vs:
  298. dvs = vs.split('@@@')
  299. vname = dvs[0]
  300. vurl = durl + dvs[0]
  301. surl = durl + dvs[1]
  302. vsurl = vsurl + '{0}${1}@@@{2}#'.format(vname, vurl, surl)
  303. else:
  304. vurl = durl + vs
  305. vsurl = vsurl + '{0}${1}#'.format(vs, vurl)
  306. url = vsurl
  307. else:
  308. durl = id
  309. if self.ver == '' or self.baseurl == '':
  310. self.getVersion(durl)
  311. baseurl = self.baseurl
  312. if '+++' in id:
  313. vid = durl.replace(baseurl, "").strip('/')
  314. else:
  315. vid = durl.replace(re.findall(r".*/", durl)[0], "")
  316. url = vid + '$' + id
  317. vod = {
  318. "vod_id": vid,
  319. "vod_name": vid,
  320. "vod_pic": '',
  321. "vod_tag": '',
  322. "vod_play_from": "播放",
  323. "vod_play_url": url
  324. }
  325. result = {
  326. 'list': [
  327. vod
  328. ]
  329. }
  330. return result
  331. def searchContent(self, key, quick):
  332. result = {
  333. 'list': []
  334. }
  335. return result
  336. def playerContent(self, flag, id, vipFlags):
  337. result = {}
  338. url = ''
  339. subturl = ''
  340. ifsub = '@@@' in id
  341. if ifsub is True:
  342. ids = id.split('@@@')
  343. if self.ver == '' or self.baseurl == '':
  344. self.getVersion(ids[1])
  345. ver = self.ver
  346. baseurl = self.baseurl
  347. fileName = ids[1].replace(baseurl, "")
  348. vfileName = ids[0].replace(baseurl, "")
  349. param = {
  350. "path": '/' + fileName,
  351. "password": "",
  352. "page_num": 1,
  353. "page_size": 100
  354. }
  355. vparam = {
  356. "path": '/' + vfileName,
  357. "password": "",
  358. "page_num": 1,
  359. "page_size": 100
  360. }
  361. if ver == 2:
  362. rsp = self.postJson(baseurl + 'api/public/path', param)
  363. jo = json.loads(rsp.text)
  364. vodList = jo['data']['files'][0]
  365. subturl = vodList['url']
  366. vrsp = self.postJson(baseurl + 'api/public/path', vparam)
  367. vjo = json.loads(vrsp.text)
  368. vList = vjo['data']['files'][0]
  369. url = vList['url']
  370. elif ver == 3:
  371. rsp = self.postJson(baseurl + 'api/fs/get', param)
  372. jo = json.loads(rsp.text)
  373. vodList = jo['data']
  374. subturl = vodList['raw_url']
  375. vrsp = self.postJson(baseurl + 'api/fs/get', vparam)
  376. vjo = json.loads(vrsp.text)
  377. vList = vjo['data']
  378. url = vList['raw_url']
  379. if subturl.startswith('http') is False:
  380. head = re.findall(r"h.*?:", baseurl)[0]
  381. subturl = head + subturl
  382. if url.startswith('http') is False:
  383. head = re.findall(r"h.*?:", baseurl)[0]
  384. url = head + url
  385. urlfileName = urllib.parse.quote(fileName)
  386. subturl = subturl.replace(fileName, urlfileName)
  387. urlvfileName = urllib.parse.quote(vfileName)
  388. url = url.replace(vfileName, urlvfileName)
  389. result['subt'] = subturl
  390. else:
  391. if self.ver == '' or self.baseurl == '':
  392. self.getVersion(id)
  393. ver = self.ver
  394. baseurl = self.baseurl
  395. vfileName = id.replace(baseurl, "")
  396. vparam = {
  397. "path": '/' + vfileName,
  398. "password": "",
  399. "page_num": 1,
  400. "page_size": 100
  401. }
  402. if ver == 2:
  403. vrsp = self.postJson(baseurl + 'api/public/path', vparam)
  404. vjo = json.loads(vrsp.text)
  405. vList = vjo['data']['files'][0]
  406. driver = vList['driver']
  407. url = vList['url']
  408. elif ver == 3:
  409. vrsp = self.postJson(baseurl + 'api/fs/get', vparam)
  410. vjo = json.loads(vrsp.text)
  411. vList = vjo['data']
  412. url = vList['raw_url']
  413. driver = vList['provider']
  414. if url.startswith('http') is False:
  415. head = re.findall(r"h.*?:", baseurl)[0]
  416. url = head + url
  417. urlvfileName = urllib.parse.quote(vfileName)
  418. url = url.replace(vfileName, urlvfileName)
  419. if driver == 'Baidu.Disk':
  420. result["header"] = {"User-Agent": "pan.baidu.com"}
  421. result["parse"] = 0
  422. result["playUrl"] = ''
  423. result["url"] = url
  424. return result
  425. flurl = ''
  426. config = {
  427. "player": {},
  428. "filter": {}
  429. }
  430. header = {}
  431. def localProxy(self, param):
  432. return [200, "video/MP2T", action, ""]