py_bilibilimd.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. #coding=utf-8
  2. #!/usr/bin/python
  3. import sys
  4. import json
  5. import time
  6. from datetime import datetime
  7. from difflib import SequenceMatcher
  8. from urllib.parse import quote, unquote
  9. sys.path.append('..')
  10. from base.spider import Spider
  11. class Spider(Spider): # 元类 默认的元类 type
  12. def getName(self):
  13. return "B站番剧"
  14. def init(self, extend):
  15. try:
  16. self.extendDict = json.loads(extend)
  17. except:
  18. self.extendDict = {}
  19. def isVideoFormat(self, url):
  20. pass
  21. def manualVideoCheck(self):
  22. pass
  23. def homeContent(self, filter):
  24. result = {}
  25. cateManual = {
  26. "番剧": "1",
  27. "国创": "4",
  28. "电影": "2",
  29. "综艺": "7",
  30. "电视剧": "5",
  31. }
  32. classes = []
  33. for k in cateManual:
  34. classes.append({
  35. 'type_name': k,
  36. 'type_id': cateManual[k]
  37. })
  38. result['class'] = classes
  39. if filter:
  40. result['filters'] = self.config['filter']
  41. current_year = datetime.now().year
  42. for resultfilter in result['filters']:
  43. for rf in result['filters'][resultfilter]:
  44. yearList = []
  45. if rf['key'] == 'year':
  46. for rfv in rf['value']:
  47. if rfv['n'].isdigit():
  48. if int(rfv['n']) < current_year:
  49. pos = rf['value'].index(rfv)
  50. for year in range(current_year, int(rfv['n']), -1):
  51. yearList.append({'v': '[{},{})'.format(year, year+1), 'n': str(year)})
  52. rf['value'].insert(pos, yearList)
  53. break
  54. else:
  55. break
  56. elif rf['key'] == 'release_date':
  57. for rfv in rf['value']:
  58. if rfv['n'].isdigit():
  59. if int(rfv['n']) < current_year:
  60. pos = rf['value'].index(rfv)
  61. for year in range(current_year, int(rfv['n']), -1):
  62. yearList.append({'v': '[{}-01-01 00:00:00,{}-01-01 00:00:00)'.format(year, year + 1), 'n': str(year)})
  63. rf['value'].insert(pos, yearList)
  64. break
  65. else:
  66. break
  67. return result
  68. def homeVideoContent(self):
  69. return self.categoryContent('1', '1', False, {})
  70. def categoryContent(self, cid, page, filter, ext):
  71. page = int(page)
  72. result = {}
  73. videos = []
  74. cookie, _, _ = self.getCookie('{}')
  75. url = 'https://api.bilibili.com/pgc/season/index/result?order=2&sort=0&pagesize=20&type=1&st={}&season_type={}&page={}'.format(cid, cid, page)
  76. for key in ext:
  77. url += f'&{key}={quote(ext[key])}'
  78. r = self.fetch(url, headers=self.header, cookies=cookie, timeout=5)
  79. data = json.loads(self.cleanText(r.text))
  80. vodList = data['data']['list']
  81. for vod in vodList:
  82. aid = str(vod['season_id']).strip()
  83. title = self.removeHtmlTags(self.cleanText(vod['title']))
  84. img = vod['cover'].strip()
  85. remark = vod['index_show'].strip()
  86. videos.append({
  87. "vod_id": aid,
  88. "vod_name": title,
  89. "vod_pic": img,
  90. "vod_remarks": remark
  91. })
  92. lenvideos = len(videos)
  93. if data['data']['has_next'] == 1:
  94. pagecount = page + 1
  95. else:
  96. pagecount = page
  97. result['list'] = videos
  98. result['page'] = page
  99. result['pagecount'] = pagecount
  100. result['limit'] = lenvideos
  101. result['total'] = lenvideos
  102. return result
  103. def detailContent(self, did):
  104. did = did[0]
  105. url = "http://api.bilibili.com/pgc/view/web/season?season_id={0}".format(did)
  106. r = self.fetch(url, headers=self.header, timeout=10)
  107. data = json.loads(self.cleanText(r.text))
  108. vod = {
  109. "vod_id": did,
  110. "vod_name": self.removeHtmlTags(data['result']['title']),
  111. "vod_pic": data['result']['cover'],
  112. "type_name": data['result']['share_sub_title'],
  113. "vod_actor": data['result']['actors'].replace('\n', ','),
  114. "vod_content": self.removeHtmlTags(data['result']['evaluate'])
  115. }
  116. videoList = data['result']['episodes']
  117. playUrl = ''
  118. for video in videoList:
  119. eid = video['id']
  120. cid = video['cid']
  121. name = self.removeHtmlTags(video['share_copy']).replace("#", "-").replace('$', '*')
  122. remark = time.strftime('%H:%M:%S', time.gmtime(video['duration']/1000))
  123. if remark.startswith('00:'):
  124. remark = remark[3:]
  125. playUrl = playUrl + '[{}]/{}${}_{}#'.format(remark, name, eid, cid)
  126. vod['vod_play_from'] = 'B站番剧'
  127. vod['vod_play_url'] = playUrl.strip('#')
  128. result = {
  129. 'list': [
  130. vod
  131. ]
  132. }
  133. return result
  134. def searchContent(self, key, quick):
  135. return self.searchContentPage(key, quick, '1')
  136. def searchContentPage(self, key, quick, page):
  137. videos = []
  138. cookie = ''
  139. if 'cookie' in self.extendDict:
  140. cookie = self.extendDict['cookie']
  141. if 'json' in self.extendDict:
  142. r = self.fetch(self.extendDict['json'], timeout=10)
  143. if 'cookie' in r.json():
  144. cookie = r.json()['cookie']
  145. if cookie == '':
  146. cookie = '{}'
  147. elif type(cookie) == str and cookie.startswith('http'):
  148. cookie = self.fetch(cookie, timeout=10).text.strip()
  149. try:
  150. if type(cookie) == dict:
  151. cookie = json.dumps(cookie, ensure_ascii=False)
  152. except:
  153. pass
  154. cookie, _, _ = self.getCookie(cookie)
  155. url = f'https://api.bilibili.com/x/web-interface/search/type?search_type=media_bangumi&keyword={key}&page={page}'
  156. r = self.fetch(url, headers=self.header, cookies=cookie, timeout=5)
  157. data = json.loads(self.cleanText(r.text))
  158. if 'result' not in data['data']:
  159. return {'list': videos}, 1
  160. vodList = data['data']['result']
  161. for vod in vodList:
  162. sid = str(vod['season_id']).strip()
  163. title = self.removeHtmlTags(self.cleanText(vod['title']))
  164. if SequenceMatcher(None, title, key).ratio() < 0.6 and key not in title:
  165. continue
  166. img = vod['eps'][0]['cover'].strip()
  167. remark = self.removeHtmlTags(vod['index_show']).strip()
  168. videos.append({
  169. "vod_id": sid,
  170. "vod_name": title,
  171. "vod_pic": img,
  172. "vod_remarks": remark
  173. })
  174. result = {
  175. 'list': videos
  176. }
  177. return result
  178. def playerContent(self, flag, pid, vipFlags):
  179. result = {}
  180. pidList = pid.split("_")
  181. aid = pidList[0]
  182. cid = pidList[1]
  183. url = 'https://api.bilibili.com/pgc/player/web/playurl?ep_id={0}&cid={1}&qn=120&fnval=4048&fnver=0&fourk=1'.format(aid, cid)
  184. cookie = ''
  185. extendDict = self.extendDict
  186. if 'cookie' in extendDict:
  187. cookie = extendDict['cookie']
  188. if 'json' in extendDict:
  189. r = self.fetch(extendDict['json'], timeout=10)
  190. if 'cookie' in r.json():
  191. cookie = r.json()['cookie']
  192. if cookie == '':
  193. cookie = '{}'
  194. elif type(cookie) == str and cookie.startswith('http'):
  195. cookie = self.fetch(cookie, timeout=10).text.strip()
  196. try:
  197. if type(cookie) == dict:
  198. cookie = json.dumps(cookie, ensure_ascii=False)
  199. except:
  200. pass
  201. cookiesDict, _, _ = self.getCookie(cookie)
  202. cookies = quote(json.dumps(cookiesDict))
  203. if 'thread' in extendDict:
  204. thread = str(extendDict['thread'])
  205. else:
  206. thread = '0'
  207. result["parse"] = '0'
  208. result["playUrl"] = ''
  209. result["url"] = f'http://127.0.0.1:UndCover/proxy?do=py&type=mpd&cookies={cookies}&url={quote(url)}&aid={aid}&cid={cid}&thread={thread}'
  210. result["header"] = self.header
  211. result['danmaku'] = 'https://api.bilibili.com/x/v1/dm/list.so?oid={}'.format(cid)
  212. result["format"] = 'application/dash+xml'
  213. return result
  214. def localProxy(self, params):
  215. if params['type'] == "mpd":
  216. return self.proxyMpd(params)
  217. if params['type'] == "media":
  218. return self.proxyMedia(params)
  219. return None
  220. def proxyMpd(self, params):
  221. content, durlinfos, mediaType = self.getDash(params)
  222. if mediaType == 'mpd':
  223. action = {'url': '', 'header': self.header, 'param': '', 'type': 'string'}
  224. return [200, "application/dash+xml", action, content]
  225. else:
  226. url = content
  227. durlinfo = durlinfos['durl'][0]['backup_url']
  228. try:
  229. r = self.fetch(url, headers=self.header, stream=True, timeout=1)
  230. statusCode = r.status_code
  231. try:
  232. r.close()
  233. except:
  234. pass
  235. except:
  236. try:
  237. r.close()
  238. except:
  239. pass
  240. statusCode = 404
  241. for url in durlinfo:
  242. try:
  243. r = self.fetch(url, headers=self.header, stream=True, timeout=1)
  244. statusCode = r.status_code
  245. except:
  246. statusCode = 404
  247. if statusCode == 200:
  248. break
  249. try:
  250. r.close()
  251. except:
  252. pass
  253. if statusCode != 200 and self.retry == 0:
  254. self.retry += 1
  255. self.proxyMedia(params, True)
  256. header = self.header.copy()
  257. if 'range' in params:
  258. header['Range'] = params['range']
  259. if '127.0.0.1:7777' in url:
  260. action = {'url': url, 'header': header, 'param': '', 'type': 'redirect'}
  261. return [302, "video/MP2T", action, url]
  262. action = {'url': content, 'header': header, 'param': '', 'type': 'stream'}
  263. return [206, "application/octet-stream", action, '']
  264. def proxyMedia(self, params, forceRefresh=False):
  265. _, dashinfos, _ = self.getDash(params)
  266. if 'videoid' in params:
  267. videoid = int(params['videoid'])
  268. dashinfo = dashinfos['video'][videoid]
  269. url = dashinfo['baseUrl']
  270. elif 'audioid' in params:
  271. audioid = int(params['audioid'])
  272. dashinfo = dashinfos['audio'][audioid]
  273. url = dashinfo['baseUrl']
  274. else:
  275. return [404, "text/plain", {}, ""]
  276. try:
  277. r = self.fetch(url, headers=params['headers'], stream=True)
  278. statusCode = r.status_code
  279. try:
  280. r.close()
  281. except:
  282. pass
  283. except:
  284. try:
  285. r.close()
  286. except:
  287. pass
  288. statusCode = 404
  289. for url in dashinfo['backupUrl']:
  290. try:
  291. r = self.fetch(url, headers=self.header, stream=True, timeout=1)
  292. statusCode = r.status_code
  293. except:
  294. statusCode = 404
  295. if statusCode == 200:
  296. break
  297. try:
  298. r.close()
  299. except:
  300. pass
  301. if statusCode != 200 and self.retry == 0:
  302. self.retry += 1
  303. self.proxyMedia(params, True)
  304. header = self.header.copy()
  305. if 'range' in params:
  306. header['Range'] = params['range']
  307. action = {'url': url, 'header': header, 'param': '', 'type': 'stream'}
  308. return [206, "application/octet-stream", action, '']
  309. def getDash(self, params, forceRefresh=False):
  310. aid = params['aid']
  311. cid = params['cid']
  312. url = unquote(params['url'])
  313. if 'thread' in params:
  314. thread = params['thread']
  315. else:
  316. thread = 0
  317. header = self.header.copy()
  318. self.setCache('debug', params['cookies'])
  319. cookieDict = json.loads(params['cookies'])
  320. key = f'bilimdmpdCache_{aid}_{cid}'
  321. if forceRefresh:
  322. self.delCache(key)
  323. else:
  324. data = self.getCache(key)
  325. if data:
  326. return data['content'], data['dashinfos'], data['type']
  327. cookies = cookieDict.copy()
  328. r = self.fetch(url, cookies=cookies, headers=header, timeout=5)
  329. data = json.loads(self.cleanText(r.text))
  330. if data['code'] != 0:
  331. return '', {}, ''
  332. if not 'dash' in data['result']:
  333. purl = data['result']['durl'][0]['url']
  334. try:
  335. expiresAt = int(self.regStr(reg='deadline=(\d+)', src=purl).group(1)) - 60
  336. except:
  337. expiresAt = int(time.time()) + 600
  338. if int(thread) > 0:
  339. try:
  340. self.fetch('http://127.0.0.1:7777')
  341. except:
  342. self.fetch('http://127.0.0.1:9978/go')
  343. purl = f'http://127.0.0.1:7777?url={quote(purl)}&thread={thread}'
  344. self.setCache(key, {'content': purl, 'type': 'mp4', 'dashinfos': data['result'], 'expiresAt': expiresAt})
  345. return purl, data['result'], 'mp4'
  346. dashinfos = data['result']['dash']
  347. duration = dashinfos['duration']
  348. minBufferTime = dashinfos['minBufferTime']
  349. videoinfo = ''
  350. videoid = 0
  351. deadlineList = []
  352. # videoList = sorted(dashinfos['video'], key=lambda x: x['bandwidth'], reverse=True)
  353. for video in dashinfos['video']:
  354. try:
  355. deadline = int(self.regStr(reg='deadline=(\d+)', src=video['baseUrl']).group(1))
  356. except:
  357. deadline = int(time.time()) + 600
  358. deadlineList.append(deadline)
  359. codecs = video['codecs']
  360. bandwidth = video['bandwidth']
  361. frameRate = video['frameRate']
  362. height = video['height']
  363. width = video['width']
  364. void = video['id']
  365. vidparams = params.copy()
  366. vidparams['videoid'] = videoid
  367. baseUrl = f'http://127.0.0.1:UndCover/proxy?do=py&type=media&cookies={quote(json.dumps(cookies))}&url={quote(url)}&aid={aid}&cid={cid}&videoid={videoid}'
  368. videoinfo = videoinfo + f""" <Representation bandwidth="{bandwidth}" codecs="{codecs}" frameRate="{frameRate}" height="{height}" id="{void}" width="{width}">
  369. <BaseURL>{baseUrl}</BaseURL>
  370. <SegmentBase indexRange="{video['SegmentBase']['indexRange']}">
  371. <Initialization range="{video['SegmentBase']['Initialization']}"/>
  372. </SegmentBase>
  373. </Representation>\n"""
  374. videoid += 1
  375. audioinfo = ''
  376. audioid = 0
  377. # audioList = sorted(dashinfos['audio'], key=lambda x: x['bandwidth'], reverse=True)
  378. for audio in dashinfos['audio']:
  379. try:
  380. deadline = int(self.regStr(reg='deadline=(\d+)', src=audio['baseUrl']).group(1))
  381. except:
  382. deadline = int(time.time()) + 600
  383. deadlineList.append(deadline)
  384. bandwidth = audio['bandwidth']
  385. codecs = audio['codecs']
  386. aoid = audio['id']
  387. aidparams = params.copy()
  388. aidparams['audioid'] = audioid
  389. baseUrl = f'http://127.0.0.1:UndCover/proxy?do=py&type=media&cookies={quote(json.dumps(cookies))}&url={quote(url)}&aid={aid}&cid={cid}&audioid={audioid}'
  390. audioinfo = audioinfo + f""" <Representation audioSamplingRate="44100" bandwidth="{bandwidth}" codecs="{codecs}" id="{aoid}">
  391. <BaseURL>{baseUrl}</BaseURL>
  392. <SegmentBase indexRange="{audio['SegmentBase']['indexRange']}">
  393. <Initialization range="{audio['SegmentBase']['Initialization']}"/>
  394. </SegmentBase>
  395. </Representation>\n"""
  396. audioid += 1
  397. mpd = f"""<?xml version="1.0" encoding="UTF-8"?>
  398. <MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" mediaPresentationDuration="PT{duration}S" minBufferTime="PT{minBufferTime}S">
  399. <Period>
  400. <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" segmentAlignment="true">
  401. {videoinfo.strip()}
  402. </AdaptationSet>
  403. <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="und">
  404. {audioinfo.strip()}
  405. </AdaptationSet>
  406. </Period>
  407. </MPD>"""
  408. expiresAt = min(deadlineList) - 60
  409. self.setCache(key, {'type': 'mpd', 'content': mpd.replace('&', '&amp;'), 'dashinfos': dashinfos, 'expiresAt': expiresAt})
  410. return mpd.replace('&', '&amp;'), dashinfos, 'mpd'
  411. def getCookie(self, cookie):
  412. if '{' in cookie and '}' in cookie:
  413. cookies = json.loads(cookie)
  414. else:
  415. cookies = dict([co.strip().split('=', 1) for co in cookie.strip(';').split(';')])
  416. bblogin = self.getCache('bblogin')
  417. if bblogin:
  418. imgKey = bblogin['imgKey']
  419. subKey = bblogin['subKey']
  420. return cookies, imgKey, subKey
  421. header = {
  422. "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"
  423. }
  424. r = self.fetch("http://api.bilibili.com/x/web-interface/nav", cookies=cookies, headers=header, timeout=10)
  425. data = json.loads(r.text)
  426. code = data["code"]
  427. if code == 0:
  428. imgKey = data['data']['wbi_img']['img_url'].rsplit('/', 1)[1].split('.')[0]
  429. subKey = data['data']['wbi_img']['sub_url'].rsplit('/', 1)[1].split('.')[0]
  430. self.setCache('bblogin', {'imgKey': imgKey, 'subKey': subKey, 'expiresAt': int(time.time()) + 1200})
  431. return cookies, imgKey, subKey
  432. r = self.fetch("https://www.bilibili.com/", headers=header, timeout=5)
  433. cookies = r.cookies.get_dict()
  434. imgKey = ''
  435. subKey = ''
  436. return cookies, imgKey, subKey
  437. def removeHtmlTags(self, src):
  438. from re import sub, compile
  439. clean = compile('<.*?>')
  440. return sub(clean, '', src)
  441. def getCache(self, key):
  442. value = self.fetch(f'http://127.0.0.1:9978/cache?do=get&key={key}', timeout=5).text
  443. if len(value) > 0:
  444. if value.startswith('{') and value.endswith('}') or value.startswith('[') and value.endswith(']'):
  445. value = json.loads(value)
  446. if type(value) == dict:
  447. if not 'expiresAt' in value or value['expiresAt'] >= int(time.time()):
  448. return value
  449. else:
  450. self.delCache(key)
  451. return None
  452. return value
  453. else:
  454. return None
  455. def setCache(self, key, value):
  456. if len(value) > 0:
  457. if type(value) == dict or type(value) == list:
  458. value = json.dumps(value, ensure_ascii=False)
  459. self.post(f'http://127.0.0.1:9978/cache?do=set&key={key}', data={"value": value}, timeout=5)
  460. def delCache(self, key):
  461. self.fetch(f'http://127.0.0.1:9978/cache?do=del&key={key}', timeout=5)
  462. retry = 0
  463. header = {
  464. "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",
  465. "Referer": "https://www.bilibili.com"
  466. }
  467. config = {
  468. "filter": {"1":[{"key":"season_version","name":"类型","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"正片"},{"v":'2',"n":"电影"},{"v":'3',"n":"其他"}]},{"key":"area","name":"地区","value":[{"v":'-1',"n":"全部"},{"v":'2',"n":"日本"},{"v":'3',"n":"美国"},{"v":"1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70","n":"其他"}]},{"key":"is_finish","name":"状态","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"完结"},{"v":'0',"n":"连载"}]},{"key":"copyright","name":"版权","value":[{"v":'-1',"n":"全部"},{"v":'3',"n":"独家"},{"v":"1,2,4","n":"其他"}]},{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"season_month","name":"季度","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"1月"},{"v":'4',"n":"4月"},{"v":'7',"n":"7月"},{"v":'10',"n":"10月"}]},{"key":"year","name":"年份","value":[{"v":'-1',"n":"全部"},{"v":"[2023,2024)","n":"2023"},{"v":"[2022,2023)","n":"2022"},{"v":"[2021,2022)","n":"2021"},{"v":"[2020,2021)","n":"2020"},{"v":"[2019,2020)","n":"2019"},{"v":"[2018,2019)","n":"2018"},{"v":"[2017,2018)","n":"2017"},{"v":"[2016,2017)","n":"2016"},{"v":"[2015,2016)","n":"2015"},{"v":"[2010,2015)","n":"2014-2010"},{"v":"[2005,2010)","n":"2009-2005"},{"v":"[2000,2005)","n":"2004-2000"},{"v":"[1990,2000)","n":"90年代"},{"v":"[1980,1990)","n":"80年代"},{"v":"[,1980)","n":"更早"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10010',"n":"原创"},{"v":'10011',"n":"漫画改"},{"v":'10012',"n":"小说改"},{"v":'10013',"n":"游戏改"},{"v":'10102',"n":"特摄"},{"v":'10015',"n":"布袋戏"},{"v":'10016',"n":"热血"},{"v":'10017',"n":"穿越"},{"v":'10018',"n":"奇幻"},{"v":'10020',"n":"战斗"},{"v":'10021',"n":"搞笑"},{"v":'10022',"n":"日常"},{"v":'10023',"n":"科幻"},{"v":'10024',"n":"萌系"},{"v":'10025',"n":"治愈"},{"v":'10026',"n":"校园"},{"v":'10027',"n":"少儿"},{"v":'10028',"n":"泡面"},{"v":'10029',"n":"恋爱"},{"v":'10030',"n":"少女"},{"v":'10031',"n":"魔法"},{"v":'10032',"n":"冒险"},{"v":'10033',"n":"历史"},{"v":'10034',"n":"架空"},{"v":'10035',"n":"机战"},{"v":'10036',"n":"神魔"},{"v":'10037',"n":"声控"},{"v":'10038',"n":"运动"},{"v":'10039',"n":"励志"},{"v":'10040',"n":"音乐"},{"v":'10041',"n":"推理"},{"v":'10042',"n":"社团"},{"v":'10043',"n":"智斗"},{"v":'10044',"n":"催泪"},{"v":'10045',"n":"美食"},{"v":'10046',"n":"偶像"},{"v":'10047',"n":"乙女"},{"v":'10048',"n":"职场"}]}],"4":[{"key":"season_version","name":"类型","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"正片"},{"v":'2',"n":"电影"},{"v":'3',"n":"其他"}]},{"key":"area","name":"地区","value":[{"v":'-1',"n":"全部"},{"v":'2',"n":"日本"},{"v":'3',"n":"美国"},{"v":"1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70","n":"其他"}]},{"key":"is_finish","name":"状态","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"完结"},{"v":'0',"n":"连载"}]},{"key":"copyright","name":"版权","value":[{"v":'-1',"n":"全部"},{"v":'3',"n":"独家"},{"v":"1,2,4","n":"其他"}]},{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"year","name":"年份","value":[{"v":'-1',"n":"全部"},{"v":"[2023,2024)","n":"2023"},{"v":"[2022,2023)","n":"2022"},{"v":"[2021,2022)","n":"2021"},{"v":"[2020,2021)","n":"2020"},{"v":"[2019,2020)","n":"2019"},{"v":"[2018,2019)","n":"2018"},{"v":"[2017,2018)","n":"2017"},{"v":"[2016,2017)","n":"2016"},{"v":"[2015,2016)","n":"2015"},{"v":"[2010,2015)","n":"2014-2010"},{"v":"[2005,2010)","n":"2009-2005"},{"v":"[2000,2005)","n":"2004-2000"},{"v":"[1990,2000)","n":"90年代"},{"v":"[1980,1990)","n":"80年代"},{"v":"[,1980)","n":"更早"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10010',"n":"原创"},{"v":'10011',"n":"漫画改"},{"v":'10012',"n":"小说改"},{"v":'10013',"n":"游戏改"},{"v":'10014',"n":"动态漫"},{"v":'10015',"n":"布袋戏"},{"v":'10016',"n":"热血"},{"v":'10018',"n":"奇幻"},{"v":'10019',"n":"玄幻"},{"v":'10020',"n":"战斗"},{"v":'10021',"n":"搞笑"},{"v":'10078',"n":"武侠"},{"v":'10022',"n":"日常"},{"v":'10023',"n":"科幻"},{"v":'10024',"n":"萌系"},{"v":'10025',"n":"治愈"},{"v":'10057',"n":"悬疑"},{"v":'10026',"n":"校园"},{"v":'10027',"n":"少儿"},{"v":'10028',"n":"泡面"},{"v":'10029',"n":"恋爱"},{"v":'10030',"n":"少女"},{"v":'10031',"n":"魔法"},{"v":'10033',"n":"历史"},{"v":'10035',"n":"机战"},{"v":'10036',"n":"神魔"},{"v":'10037',"n":"声控"},{"v":'10038',"n":"运动"},{"v":'10039',"n":"励志"},{"v":'10040',"n":"音乐"},{"v":'10041',"n":"推理"},{"v":'10042',"n":"社团"},{"v":'10043',"n":"智斗"},{"v":'10044',"n":"催泪"},{"v":'10045',"n":"美食"},{"v":'10046',"n":"偶像"},{"v":'10047',"n":"乙女"},{"v":'10048',"n":"职场"},{"v":'10049',"n":"古风"}]}],"2":[{"key":"area","name":"地区","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"中国大陆"},{"v":"6,7","n":"中国港台"},{"v":'3',"n":"美国"},{"v":'2',"n":"日本"},{"v":'8',"n":"韩国"},{"v":'9',"n":"法国"},{"v":'4',"n":"英国"},{"v":'15',"n":"德国"},{"v":'10',"n":"泰国"},{"v":'35',"n":"意大利"},{"v":'13',"n":"西班牙"},{"v":"5,11,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70","n":"其他"}]},{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10104',"n":"短片"},{"v":'10050',"n":"剧情"},{"v":'10051',"n":"喜剧"},{"v":'10052',"n":"爱情"},{"v":'10053',"n":"动作"},{"v":'10054',"n":"恐怖"},{"v":'10023',"n":"科幻"},{"v":'10055',"n":"犯罪"},{"v":'10056',"n":"惊悚"},{"v":'10057',"n":"悬疑"},{"v":'10018',"n":"奇幻"},{"v":'10058',"n":"战争"},{"v":'10059',"n":"动画"},{"v":'10060',"n":"传记"},{"v":'10061',"n":"家庭"},{"v":'10062',"n":"歌舞"},{"v":'10033',"n":"历史"},{"v":'10032',"n":"冒险"},{"v":'10063',"n":"纪实"},{"v":'10064',"n":"灾难"},{"v":'10011',"n":"漫画改"},{"v":'10012',"n":"小说改"}]},{"key":"release_date","name":"年份","value":[{"v":'-1',"n":"全部"},{"v":"[2023-01-01 00:00:00,2024-01-01 00:00:00)","n":"2023"},{"v":"[2022-01-01 00:00:00,2023-01-01 00:00:00)","n":"2022"},{"v":"[2021-01-01 00:00:00,2022-01-01 00:00:00)","n":"2021"},{"v":"[2020-01-01 00:00:00,2021-01-01 00:00:00)","n":"2020"},{"v":"[2019-01-01 00:00:00,2020-01-01 00:00:00)","n":"2019"},{"v":"[2018-01-01 00:00:00,2019-01-01 00:00:00)","n":"2018"},{"v":"[2017-01-01 00:00:00,2018-01-01 00:00:00)","n":"2017"},{"v":"[2016-01-01 00:00:00,2017-01-01 00:00:00)","n":"2016"},{"v":"[2010-01-01 00:00:00,2016-01-01 00:00:00)","n":"2015-2010"},{"v":"[2005-01-01 00:00:00,2010-01-01 00:00:00)","n":"2009-2005"},{"v":"[2000-01-01 00:00:00,2005-01-01 00:00:00)","n":"2004-2000"},{"v":"[1990-01-01 00:00:00,2000-01-01 00:00:00)","n":"90年代"},{"v":"[1980-01-01 00:00:00,1990-01-01 00:00:00)","n":"80年代"},{"v":"[,1980-01-01 00:00:00)","n":"更早"}]}],"5":[{"key":"area","name":"地区","value":[{"v":'-1',"n":"全部"},{"v":"1,6,7","n":"中国"},{"v":'2',"n":"日本"},{"v":'3',"n":"美国"},{"v":'4',"n":"英国"},{"v":'10',"n":"泰国"},{"v":"5,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70","n":"其他"}]},{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10021',"n":"搞笑"},{"v":'10018',"n":"奇幻"},{"v":'10058',"n":"战争"},{"v":'10078',"n":"武侠"},{"v":'10079',"n":"青春"},{"v":'10103',"n":"短剧"},{"v":'10080',"n":"都市"},{"v":'10081',"n":"古装"},{"v":'10082',"n":"谍战"},{"v":'10083',"n":"经典"},{"v":'10084',"n":"情感"},{"v":'10057',"n":"悬疑"},{"v":'10039',"n":"励志"},{"v":'10085',"n":"神话"},{"v":'10017',"n":"穿越"},{"v":'10086',"n":"年代"},{"v":'10087',"n":"农村"},{"v":'10088',"n":"刑侦"},{"v":'10050',"n":"剧情"},{"v":'10061',"n":"家庭"},{"v":'10033',"n":"历史"},{"v":'10089',"n":"军旅"},{"v":'10023',"n":"科幻"}]},{"key":"release_date","name":"年份","value":[{"v":'-1',"n":"全部"},{"v":"[2023-01-01 00:00:00,2024-01-01 00:00:00)","n":"2023"},{"v":"[2022-01-01 00:00:00,2023-01-01 00:00:00)","n":"2022"},{"v":"[2021-01-01 00:00:00,2022-01-01 00:00:00)","n":"2021"},{"v":"[2020-01-01 00:00:00,2021-01-01 00:00:00)","n":"2020"},{"v":"[2019-01-01 00:00:00,2020-01-01 00:00:00)","n":"2019"},{"v":"[2018-01-01 00:00:00,2019-01-01 00:00:00)","n":"2018"},{"v":"[2017-01-01 00:00:00,2018-01-01 00:00:00)","n":"2017"},{"v":"[2016-01-01 00:00:00,2017-01-01 00:00:00)","n":"2016"},{"v":"[2010-01-01 00:00:00,2016-01-01 00:00:00)","n":"2015-2010"},{"v":"[2005-01-01 00:00:00,2010-01-01 00:00:00)","n":"2009-2005"},{"v":"[2000-01-01 00:00:00,2005-01-01 00:00:00)","n":"2004-2000"},{"v":"[1990-01-01 00:00:00,2000-01-01 00:00:00)","n":"90年代"},{"v":"[1980-01-01 00:00:00,1990-01-01 00:00:00)","n":"80年代"},{"v":"[,1980-01-01 00:00:00)","n":"更早"}]}],"7":[{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10040',"n":"音乐"},{"v":'10090',"n":"访谈"},{"v":'10091',"n":"脱口秀"},{"v":'10092',"n":"真人秀"},{"v":'10094',"n":"选秀"},{"v":'10045',"n":"美食"},{"v":'10095',"n":"旅游"},{"v":'10098',"n":"晚会"},{"v":'10096',"n":"演唱会"},{"v":'10084',"n":"情感"},{"v":'10051',"n":"喜剧"},{"v":'10097',"n":"亲子"},{"v":'10100',"n":"文化"},{"v":'10048',"n":"职场"},{"v":'10069',"n":"萌宠"},{"v":'10099',"n":"养成"}]}]}
  469. }