py_bilibili.py 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310
  1. Cv='Referer'
  2. Cu='application/dash+xml'
  3. Ct='interaction'
  4. Cs='subtitle'
  5. Cr='mimeType'
  6. Cq='192000'
  7. Cp='media_ft'
  8. Co='media_bangumi'
  9. Cn='stream'
  10. Cm='playurl_info'
  11. Cl='vod_actor'
  12. Ck='\u3000👥 '
  13. Cj='setting'
  14. Ci='message'
  15. Ch='totalrank'
  16. Cg='room_id'
  17. Cf='favorite'
  18. Ce='attention'
  19. Cd='videos'
  20. Cc=' 个人主页'
  21. Cb='vod_pc'
  22. Ca='series'
  23. CZ='oldest'
  24. CY='description'
  25. CX='user_cover'
  26. CW='roomid'
  27. CV='text_small'
  28. CU='watched_show'
  29. CT='live_status'
  30. CS='查看直播细化标签'
  31. CR='https:'
  32. CQ='fav_list'
  33. CP='https://api.bilibili.com/x/web-interface/nav'
  34. CO='bangumi_pay_parse'
  35. CN='bangumi_vip_parse'
  36. CM='raw_cookie_vip'
  37. CL='raw_cookie_line'
  38. CJ='contentType'
  39. CI='header'
  40. CH='mpd'
  41. CG='codecid'
  42. CF='playurl'
  43. CE='season_title'
  44. CD='edgeid'
  45. CC='vod_list'
  46. CB='AllPt'
  47. CA='vod_year'
  48. C9='title_type'
  49. C8='bangumi'
  50. C7='bili_user'
  51. C6='seasons'
  52. C5='sort'
  53. C4='season_status'
  54. C3='all'
  55. C2='special'
  56. C1='悄悄关注'
  57. C0='最近关注'
  58. B_='like_num'
  59. Bz='crname'
  60. By='part'
  61. Bx='play'
  62. Bw='%H:%M:%S'
  63. Bv='module_author'
  64. Bu='isVIP'
  65. Bt='isLogin'
  66. Bs='https://'
  67. Br='utf-8'
  68. Bq='排行榜'
  69. Bp='showLiveFilterTag'
  70. Bo='vodDefaultCodec'
  71. Bn='vodDefaultQn'
  72. Bm='favMode'
  73. Bl='maxHomeVideoContent'
  74. Bf='deadline'
  75. Be='durl'
  76. Bd='csrf'
  77. Bc='codec'
  78. Bb='AllPu'
  79. Ba='🆙 '
  80. BZ='vod_director'
  81. BY='fromep'
  82. BX='@thisepisode@'
  83. BW='预告'
  84. BV='000'
  85. BU='最近访问'
  86. BT='最常访问'
  87. BS='coin'
  88. BR='danmaku'
  89. BQ='稍后再看'
  90. BP='vod_count'
  91. BO='episodes'
  92. BN='view'
  93. BM='stat'
  94. BL=' ▶'
  95. BK='archive'
  96. BJ='UP主'
  97. BI='modules'
  98. BH='type_name'
  99. BG=None
  100. BF='历史'
  101. BE='关注'
  102. BD='rankingLis'
  103. BC='tuijianLis'
  104. BB='cateManual'
  105. BA='heartbeatInterval'
  106. B9=float
  107. B7='s_title'
  108. B6='graph_version'
  109. B5='ssid'
  110. B4='pages'
  111. B3='ugc_season'
  112. B2='parse'
  113. B1='特别关注'
  114. B0='正在直播'
  115. A_='[/a]'
  116. Az='"}/]'
  117. Ay='pubdate'
  118. Ax='new_ep'
  119. Aw='index_show'
  120. Av='content'
  121. Au='pic'
  122. At='keyword'
  123. As='登录'
  124. Ar='userid'
  125. Aq='搜索'
  126. Ap='vodDefaultAudio'
  127. Ao='@@@'
  128. An='\n'
  129. Am='like'
  130. Al='desc'
  131. Ak='[a=cr:{"id": "'
  132. Aj='fans'
  133. Ai='up'
  134. Ah='owner'
  135. Ag=' 🆙'
  136. Af='mlid'
  137. Ae='收藏'
  138. Ad='直播'
  139. Ac='影视'
  140. Ab=True
  141. Aa=type
  142. AZ='audio'
  143. AY='qn'
  144. AX='format'
  145. AW='vod_content'
  146. AV='redirect_url'
  147. AU='\u3000'
  148. AT='ep'
  149. AS='following'
  150. AR='/'
  151. AQ='4'
  152. AP='User-Agent'
  153. AO='cateLive'
  154. AN='动态'
  155. AM='推荐'
  156. AL='3'
  157. AK=round
  158. AJ='﹩'
  159. AI='this_array'
  160. AH='\\"'
  161. AG='live'
  162. AF='vip'
  163. AE='cookies_dic'
  164. AD='_tmp'
  165. AC='vod_play_url'
  166. AB='vod_play_from'
  167. AA='"'
  168. A9='ss'
  169. A8='season_id'
  170. A7=' '
  171. A6='uname'
  172. A5='face'
  173. A4='cateManualLiveExtra'
  174. A3='热门'
  175. A2='﹟'
  176. A1='tid'
  177. A0='2'
  178. z=list
  179. w='$'
  180. v='cid'
  181. u='result'
  182. t='id'
  183. s='mid'
  184. r='cateManualLive'
  185. q='order'
  186. p='video'
  187. o='epid'
  188. n='duration'
  189. m='av'
  190. l='filter'
  191. k='type'
  192. j='users'
  193. i='$$$'
  194. h='cover'
  195. g='limit'
  196. f='pagecount'
  197. e='master'
  198. d=dict
  199. c='total'
  200. b='url'
  201. a='page'
  202. Z='page_size'
  203. Y='vod_remarks'
  204. W='key'
  205. V='1'
  206. U=len
  207. T='aid'
  208. S='vod_pic'
  209. R='vod_id'
  210. Q='fake'
  211. P='title'
  212. O='vod_name'
  213. N='_'
  214. M='code'
  215. L='0'
  216. K='value'
  217. J=map
  218. I='#'
  219. H='name'
  220. G='list'
  221. F=int
  222. E='data'
  223. D='n'
  224. C='v'
  225. B=''
  226. A=str
  227. import sys,os,json as Bg,threading as x,hashlib,time as X,random as B8
  228. from base.spider import Spider
  229. from requests import session as Bh,utils as Bi,head
  230. from requests.adapters import HTTPAdapter as Cw,Retry
  231. from concurrent.futures import ThreadPoolExecutor as Cx,as_completed as Bj
  232. from functools import reduce
  233. from urllib.parse import quote as CK,urlencode as Bk
  234. sys.path.append('..')
  235. y,Cy=os.path.split(os.path.abspath(__file__))
  236. if y.startswith('/data/'):y=os.path.abspath(os.path.join(y,'..'));y=os.path.abspath(os.path.join(y,'..'));y=f"{y}/files"
  237. sys.path.append(y)
  238. class Spider(Spider):
  239. defaultConfig={'currentVersion':'20240815_1',CL:B,CM:B,Bl:AL,Bm:L,Z:12,BA:'15',Bn:'80',Bo:'7',Ap:'30280',CN:Ab,CO:Ab,Bp:L,BB:[AM,Ac,Ad,AN,Ae,BE,BF,Aq],BC:[A3,Bq,'每周必看','入站必刷','番剧时间表','国创时间表'],BD:['动画','音乐','舞蹈','游戏','鬼畜','知识','科技','运动','生活','美食','动物','汽车','时尚','娱乐',Ac,'原创','新人']};focus_on_up_list=[];focus_on_search_key=[]
  240. def getName(A):return'哔哩哔哩'
  241. def load_config(A):
  242. try:
  243. with open(f"{y}/config.json",encoding=Br)as C:A.userConfig=Bg.load(C)
  244. B=A.userConfig.get(j,{})
  245. if B.get(e)and B[e].get(AE):A.session_master.cookies=Bi.cookiejar_from_dict(B[e][AE]);A.userid=B[e][Ar]
  246. if B.get(Q)and B[Q].get(AE):A.session_fake.cookies=Bi.cookiejar_from_dict(B[Q][AE])
  247. except:A.userConfig={}
  248. A.userConfig={**A.defaultConfig,**A.userConfig}
  249. dump_config_lock=x.Lock()
  250. def dump_config(A):
  251. F=[j,AO,r,A4];C={}
  252. for(B,D)in A.userConfig.items():
  253. E=A.defaultConfig.get(B)
  254. if E!=BG and D!=E or B in F:C[B]=D
  255. A.dump_config_lock.acquire()
  256. with open(f"{y}/config.json",'w',encoding=Br)as G:H=Bg.dumps(C,indent=1,ensure_ascii=False);G.write(H)
  257. A.dump_config_lock.release()
  258. pool=Cx(max_workers=8);task_pool=[]
  259. def homeContent(A,filter):
  260. A.pool.submit(A.add_live_filter);A.pool.submit(A.add_search_key);A.pool.submit(A.add_focus_on_up_filter);A.pool.submit(A.get_tuijian_filter);A.pool.submit(A.add_fav_filter);F=[AN,Ae,BE,BF];B=A.userConfig[BB]
  261. if not A.userid and not As in B:B+=[As]
  262. D=[]
  263. for C in B:
  264. if C in F and not A.userid:continue
  265. D.append({BH:C,'type_id':C})
  266. E={'class':D};A.add_focus_on_up_filter_event.wait();A.add_live_filter_event.wait();A.add_fav_filter_event.wait();A.add_search_key_event.wait()
  267. if filter:E['filters']=A.config[l]
  268. A.pool.submit(A.dump_config);return E
  269. userid=csrf=B;session_master=Bh();session_vip=Bh();session_fake=Bh();con=x.Condition();getCookie_event=x.Event();retries=Retry(total=5,backoff_factor=.1);adapter=Cw(max_retries=retries);session_master.mount(Bs,adapter);session_vip.mount(Bs,adapter);session_fake.mount(Bs,adapter)
  270. def getCookie_dosth(B,co):
  271. A=co.strip().split('=',1)
  272. if not'%'in A[1]:A[1]=CK(A[1])
  273. return A
  274. def getCookie(A,_type=e):
  275. D=_type;G=CL
  276. if D==AF:G=CM
  277. G=A.userConfig.get(G);K=A.userConfig.get(j,{});C=K.get(D,{})
  278. if not G and not C:
  279. if D==e:A.getCookie_event.set()
  280. with A.con:A.con.notifyAll()
  281. return
  282. I=C.get(AE,{})
  283. if G:I=d(J(A.getCookie_dosth,G.split(';')))
  284. L=Bi.cookiejar_from_dict(I);N=CP;O=A.fetch(N,headers=A.header,cookies=L);H=Bg.loads(O.text);C[Bt]=0
  285. if H[M]==0:
  286. C[Bt]=1;C[Ar]=H[E][s];C[A5]=H[E][A5];C[A6]=H[E][A6];C[AE]=I;C[Bu]=F(H[E]['vipStatus'])
  287. if D==e:A.session_master.cookies=L;A.userid=C[Ar];A.csrf=I['bili_jct']
  288. if C[Bu]:A.session_vip.cookies=L
  289. else:A.userid=B
  290. K[D]=C
  291. with A.con:
  292. if U(C)>1:A.userConfig.update({j:K})
  293. if D==e:A.getCookie_event.set()
  294. getFakeCookie_event=x.Event()
  295. def getFakeCookie(A,fromSearch=BG):
  296. if A.session_fake.cookies:A.getFakeCookie_event.set()
  297. C={};C[AP]=A.header[AP];B=A.fetch('https://space.bilibili.com/2/video',headers=C);A.session_fake.cookies=B.cookies;A.getFakeCookie_event.set()
  298. with A.con:D=A.userConfig.get(j,{});D[Q]={AE:d(B.cookies)};A.userConfig.update({j:D})
  299. if not fromSearch:
  300. A.getCookie_event.wait()
  301. if not A.session_master.cookies:A.session_master.cookies=B.cookies
  302. add_fav_filter_event=x.Event()
  303. def add_fav_filter(B):
  304. N=B.userConfig.get(j,{})
  305. if N.get(e)and N[e].get(Ar):F=B.userConfig[j][e][Ar]
  306. else:B.getCookie_event.wait();F=B.userid
  307. I=[]
  308. if F:
  309. Q='https://api.bilibili.com/x/v3/fav/folder/created/list-all?up_mid=%s&jsonp=jsonp'%A(F);L=B._get_sth(Q).json()
  310. if L[M]==0 and L.get(E):R=L[E].get(G);I=z(J(lambda x:{D:B.cleanCharacters(x[P].strip()),C:x[t]},R))
  311. S=[{D:'追番',C:V},{D:'追剧',C:A0}];O=B.config[l].get(Ae)
  312. if O:O.insert(0,{W:Af,H:'分区',K:S+I})
  313. B.add_fav_filter_event.set();B.userConfig[CQ]=I
  314. add_focus_on_up_filter_event=x.Event()
  315. def add_focus_on_up_filter(B):
  316. F=B.focus_on_up_list
  317. if not B.session_master.cookies:B.getCookie_event.wait()
  318. L=z(J(lambda x:x[C],F))
  319. if B.session_master.cookies:
  320. N='https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all?timezone_offset=-480&type=video&page=1';G=B._get_sth(N).json()
  321. if G[M]==0 and G.get(E):
  322. O=G[E].get('items',[])
  323. for I in J(lambda x:{D:x[BI][Bv][H],C:A(x[BI][Bv][s])},O):
  324. if not I in F and not I[C]in L:F.append(I)
  325. P=[{D:'登录与设置',C:As}];F+=P;B.config[l][AN]=Q=[B.config[l].get(AN,[])[-1]];Q.insert(0,{W:s,H:BJ,K:F});B.add_focus_on_up_filter_event.set()
  326. def get_live_parent_area_list(O,parent_area):B=parent_area;E=B[H];id=A(B[t]);F=B[G];I=z(J(lambda area:{D:area[H],C:A(area['parent_id'])+N+A(area[t])},F));L={W:A1,H:E,K:I};M={t:id+'_0',K:L};return E,M
  327. def get_live_list(A):
  328. C='https://api.live.bilibili.com/xlive/web-interface/v1/index/getWebAreaList?source_id=2';B=A._get_sth(C,Q).json()
  329. if B[M]==0:D=B[E][E];A.userConfig[AO]=d(J(A.get_live_parent_area_list,D))
  330. return A.userConfig[AO]
  331. def set_default_cateManualLive(A):
  332. B=[{D:AM,C:AM}]
  333. for E in A.userConfig[AO]:F={D:E,C:A.userConfig[AO][E][t]};B.append(F)
  334. A.defaultConfig[r]=B;return B
  335. add_live_filter_event=x.Event()
  336. def add_live_filter(A):
  337. C=A.userConfig.get(AO,{});G=A.pool.submit(A.get_live_list)
  338. if not C:C=G.result()
  339. I=A.pool.submit(A.set_default_cateManualLive);A.config[l][Ad]=D=[];B=A.userConfig.get(r,[])
  340. if not B:B=I.result()
  341. if B:J={W:A1,H:'分区',K:B};D.append(J)
  342. if F(A.userConfig[Bp]):
  343. for E in C.values():
  344. if U(E[K][K])>1:D.append(E[K])
  345. A.add_live_filter_event.set()
  346. add_search_key_event=x.Event()
  347. def add_search_key(A):
  348. B=A.focus_on_search_key;L='https://api.bilibili.com/x/web-interface/search/square?limit=10&platform=web';F=A._get_sth(L,Q).json();P={}
  349. if F[M]==0:N=F[E]['trending'].get(G,[]);B+=z(J(lambda x:x[At],N))
  350. I={W:At,H:'搜索词',K:[]};I[K]=z(J(lambda i:{D:i,C:i},B));A.config[l][Aq]=O=A.config[l][Aq][-3:];O.insert(0,I);A.add_search_key_event.set()
  351. def get_tuijian_filter(E):
  352. I={'番剧时间表':'10001','国创时间表':'10004',Bq:L,'动画':V,'音乐':AL,'舞蹈':'129','游戏':AQ,'鬼畜':'119','知识':'36','科技':'188','运动':'234','生活':'160','美食':'211','动物':'217','汽车':'223','时尚':'155','娱乐':'5',Ac:'181','原创':'origin','新人':'rookie'};J=[{D:BC,C:'分区'},{D:BD,C:Bq}];E.config[l][AM]=M=[]
  353. for F in J:
  354. G={W:A1,H:F[C],K:[]};N=E.userConfig.get(F[D],[])
  355. for A in N:
  356. B=I.get(A)
  357. if not B:B=A
  358. O={D:A,C:B};G[K].append(O)
  359. M.append(G)
  360. def __init__(A):A.load_config();A.pool.submit(A.getCookie);A.pool.submit(A.getFakeCookie);A.pool.submit(A.getCookie,AF);B=AK(X.time());C=X.gmtime(B).tm_hour;A.pool.submit(A.get_wbiKey,C)
  361. def init(A,extend=B):print('============{0}============'.format(extend))
  362. def isVideoFormat(A,url):0
  363. def manualVideoCheck(A):0
  364. def destroy(A):0
  365. def format_img(B,img):
  366. A=img;A+='@672w_378h_1c.webp'
  367. if not A.startswith('http'):A=CR+A
  368. return A
  369. def pagination(A,array,pg):B=A.userConfig[Z]*F(pg);C=B-A.userConfig[Z];return array[C:B]
  370. def zh(D,num):
  371. C=num
  372. if F(C)>=100000000:B=AK(B9(C)/B9(100000000),1);B=A(B)+'亿'
  373. elif F(C)>=10000:B=AK(B9(C)/B9(10000),1);B=A(B)+'万'
  374. else:B=A(C)
  375. return B
  376. def second_to_time(D,a):
  377. a=F(a)
  378. if a<3600:C=X.strftime('%M:%S',X.gmtime(a))
  379. else:C=X.strftime(Bw,X.gmtime(a))
  380. if A(C).startswith(L):C=A(C).replace(L,B,1)
  381. return C
  382. def str2sec(E,x):
  383. x=A(x)
  384. try:D,B,C=x.strip().split(':');return F(D)*3600+F(B)*60+F(C)
  385. except:B,C=x.strip().split(':');return F(B)*60+F(C)
  386. def find_bangumi_id(C,url):
  387. B=A(url).split(AR)[-1]
  388. if not B:B=A(url).split(AR)[-2]
  389. B=B.split('?')[0];return B
  390. def get_Login_qrcode(H,pg):
  391. N='https://www.bilibili.com/favicon.ico';K='setting_login_';A={}
  392. if F(pg)!=1:return A
  393. D=[{R:'setting_tab&filter',O:'标签与筛选',S:N},{R:'setting_liveExtra',O:CS,S:N}];I='https://passport.bilibili.com/x/passport-login/web/qrcode/generate';J=H._get_sth(I,Q).json()
  394. if J[M]==0:
  395. id=J[E]['qrcode_key'];I=J[E][b];P={e:'主账号',AF:'副账号'};T={0:'未登录',1:'已登录'};U={0:B,1:'👑'};V=H.userConfig.get(j,{})
  396. for(W,X)in P.items():
  397. C=V.get(W)
  398. if C:D.append({R:K+id,O:C[A6],S:H.format_img(C[A5]),Y:U[C[Bu]]+X+A7+T[C[Bt]]})
  399. L={E:I,'quietzone':'208','codepage':'UTF8','quietunit':'px','errorcorrection':'M','size':'small'};D.append({R:K+id,S:'http://jm92swf.s1002.xrea.com/?'+Bk(L)});D.append({R:K+id,S:'https://bili.ming1992.xyz/API/QRCode?'+Bk(L)})
  400. A[G]=D;A[a]=1;A[f]=1;A[g]=1;A[c]=1;return A
  401. time_diff1={V:[0,300],A0:[300,900],AL:[900,1800],AQ:[1800,3600],'5':[3600,0x4ee2d6d415b85acef80ffffffff]};time_diff=L;dynamic_offset=B
  402. def get_dynamic(C,pg,mid,order):
  403. if mid==L:
  404. D={}
  405. if F(pg)==1:C.dynamic_offset=B
  406. Q='https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all?timezone_offset=-480&type=video&offset=%s&page=%s'%(C.dynamic_offset,pg);J=C._get_sth(Q).json()
  407. if J[M]==0:
  408. C.dynamic_offset=J[E].get('offset');K=[];U=J[E]['items']
  409. for N in U:V=N[BI][Bv][H];I=N[BI]['module_dynamic']['major'][BK];W=A(I[T]).strip();X=C.cleanCharacters(I[P].strip());Z=I[h].strip();b=A(C.second_to_time(C.str2sec(I['duration_text']))).strip()+Ag+A(V).strip();K.append({R:m+W,O:X,S:C.format_img(Z),Y:b})
  410. D[G]=K;D[a]=pg;D[f]=9999;D[g]=99;D[c]=999999
  411. return D
  412. else:return C.get_up_videos(mid=mid,pg=pg,order=order)
  413. def get_found_vod(G,vod):
  414. C=vod;D=C.get(T,B)
  415. if not D:D=C.get(t,B)
  416. E=C.get('goto',B)
  417. if not E or E and E==m:D=m+A(D).strip()
  418. elif E=='ad':return[]
  419. N=C[P].strip();Q=C[Au].strip();U=C.get('is_followed')
  420. if E==AG:
  421. L=C['room_info'];I=B;V=L.get(CT,B)
  422. if V:I='直播中 '
  423. else:return[]
  424. I+='👁'+L[CU][CV]+Ag+C[Ah][H].strip()
  425. else:
  426. K=C.get('rcmd_reason',B)
  427. if K and Aa(K)==d and K.get(Av):
  428. F=' 🔥'+K[Av].strip()
  429. if'人气飙升'in F:F=' 🔥人气飙升'
  430. elif U:F=' 已关注'
  431. else:F=Ag+C[Ah][H].strip()
  432. I=A(G.second_to_time(C[n])).strip()+BL+G.zh(C[BM][BN])+F
  433. M=[{R:D,O:N,S:G.format_img(Q),Y:I}]
  434. for W in J(G.get_found_vod,C.get('others',[])):M.extend(W)
  435. return M
  436. _popSeriesInit=0
  437. def get_found(A,tid,rid,pg):
  438. H=tid;C=pg;D={};K=1
  439. if H==AM:O=A.encrypt_wbi(fresh_type=4,feed_version='V8',brush=1,fresh_idx=C,fresh_idx_1h=C,ps=A.userConfig[Z])[0];B='https://api.bilibili.com/x/web-interface/wbi/index/top/feed/rcmd?'+O;K=99
  440. elif H==A3:B='https://api.bilibili.com/x/web-interface/popular?pn={0}&ps={1}'.format(C,A.userConfig[Z]);K=99
  441. elif H=='入站必刷':B='https://api.bilibili.com/x/web-interface/popular/precious'
  442. elif H=='每周必看':
  443. if F(C)==1:B='https://api.bilibili.com/x/web-interface/popular/series/list';I=A._get_sth(B,Q).json();A._popSeriesInit=F(I[E][G][0]['number'])
  444. P=A._popSeriesInit-F(C)+1;K=A._popSeriesInit;B=f"https://api.bilibili.com/x/web-interface/popular/series/one?number={P}"
  445. else:B='https://api.bilibili.com/x/web-interface/ranking/v2?rid={0}&type={1}'.format(rid,H)
  446. I=A._get_sth(B).json()
  447. if I[M]==0:
  448. N=[];L=I[E].get('item')
  449. if not L:L=I[E][G]
  450. for R in J(A.get_found_vod,L):N.extend(R)
  451. D[G]=N;D[a]=C;D[f]=K;D[g]=99;D[c]=999999
  452. return D
  453. def get_bangumi(D,tid,pg,order,season_status):
  454. X='first_ep';W='first_ep_info';T=order;I=tid;H={}
  455. if T=='追番剧':J='https://api.bilibili.com/x/space/bangumi/follow/list?type={0}&vmid={1}&pn={2}&ps={3}'.format(I,D.userid,pg,D.userConfig[Z]);K=D._get_sth(J).json()
  456. else:
  457. J='https://api.bilibili.com/pgc/season/index/result?type=1&season_type={0}&page={1}&order={2}&season_status={3}&pagesize={4}'.format(I,pg,T,season_status,D.userConfig[Z])
  458. if T==A3:
  459. if I==V:J='https://api.bilibili.com/pgc/web/rank/list?season_type={0}&day=3'.format(I)
  460. else:J='https://api.bilibili.com/pgc/season/rank/web/list?season_type={0}&day=3'.format(I)
  461. K=D._get_sth(J,Q).json()
  462. if K[M]==0:
  463. if E in K:L=K[E][G]
  464. else:L=K[u][G]
  465. if U(L)>D.userConfig[Z]:L=D.pagination(L,pg)
  466. b=[]
  467. for C in L:
  468. e=A(C[A8]).strip();i=C[P];N=C.get('ss_horizontal_cover')
  469. if not N:
  470. if C.get(W)and h in C[W]:N=C[W][h]
  471. elif C.get(X)and h in C[X]:N=C[X][h]
  472. else:N=C[h].strip()
  473. F=C.get(Aw,B)
  474. if not F and C.get(Ax)and C[Ax].get(Aw):F=C[Ax][Aw]
  475. F=F.replace('更新至','🆕');d=C.get(BM)
  476. if d:F='▶'+D.zh(d.get(BN))+' '+F
  477. b.append({R:A9+e,O:i,S:D.format_img(N),Y:F})
  478. H[G]=b;H[a]=pg;H[f]=9999;H[g]=90;H[c]=999999
  479. return H
  480. def get_timeline(E,tid,pg):
  481. b='pub_index';Z='ep_cover';D={};d='https://api.bilibili.com/pgc/web/timeline/v2?season_type={0}&day_before=2&day_after=4'.format(tid);F=E._get_sth(d,Q).json()
  482. if F[M]==0:
  483. T=[];H=F[u]['latest']
  484. for C in H:I=A(C[A8]).strip();J=C[P].strip();K=C[Z].strip();N='🆕'+C[b]+' ❤ '+C['follows'].replace('系列',B).replace('追番',B);T.append({R:A9+I,O:J,S:E.format_img(K),Y:N})
  485. V=[];W=F[u]['timeline']
  486. for e in range(U(W)):
  487. H=W[e][BO]
  488. for C in H:
  489. if A(C['published'])==L:I=A(C[A8]).strip();J=A(C[P]).strip();K=A(C[Z]).strip();h=A(X.strftime('%m-%d %H:%M',X.localtime(C['pub_ts'])));N=h+' '+C[b];V.append({R:A9+I,O:J,S:E.format_img(K),Y:N})
  490. D[G]=V+T;D[a]=1;D[f]=1;D[g]=90;D[c]=999999
  491. return D
  492. def get_live(F,pg,parent_area_id,area_id):
  493. N='recommend_room_list';I=parent_area_id;C={}
  494. if I==AM:H='https://api.live.bilibili.com/xlive/web-interface/v1/webMain/getList?platform=web&page=%s'%pg;J=F._get_sth(H).json()
  495. else:
  496. H='https://api.live.bilibili.com/xlive/web-interface/v1/second/getList?platform=web&parent_area_id=%s&area_id=%s&sort_type=online&page=%s'%(I,area_id,pg)
  497. if I==A3:H='https://api.live.bilibili.com/room/v1/room/get_user_recommend?page=%s&page_size=%s'%(pg,F.userConfig[Z])
  498. J=F._get_sth(H,Q).json()
  499. if J[M]==0:
  500. L=[];B=J[E]
  501. if N in B:B=B[N]
  502. elif G in B:B=B[G]
  503. for D in B:
  504. T=A(D[CW]).strip();U=F.cleanCharacters(D[P]);K=D.get(CX)
  505. if not K:K=D.get(h)
  506. V='👁'+D[CU][CV].strip()+Ag+D[A6].strip();L.append({R:T,O:U,S:F.format_img(K),Y:V})
  507. C[G]=L;C[a]=pg;C[f]=9999;C[g]=99;C[c]=999999
  508. return C
  509. def get_up_series(I,mid,pg):
  510. C={};N='https://api.bilibili.com/x/polymer/web-space/seasons_series_list?mid=%s&page_num=%s&page_size=%s'%(mid,pg,I.userConfig[Z]);D=I._get_sth(N,Q).json()
  511. if D[M]==0:
  512. K=[];D=D[E]['items_lists'];P=D['seasons_list']+D['series_list']
  513. for L in P:
  514. F=L.get('meta');J=A(F.get(A8,B)).strip()
  515. if J:J=m+A(L['recent_aids'][0])
  516. else:J='list_'+A(mid)+'_series_'+A(F.get('series_id',B)).strip()
  517. T=I.cleanCharacters(F[H]);U=F.get(h);V=F.get(CY,B).strip();K.append({R:J,O:T,S:I.format_img(U),Y:V})
  518. C[G]=K;C[a]=pg;C[f]=9999;C[g]=99;C[c]=999999
  519. return C
  520. get_up_videos_result=d()
  521. def get_up_videos(C,mid,pg,order):
  522. L=order;K=pg;D=mid;I={}
  523. if not D in C.up_info or F(K)==1:C.get_up_info_event.clear();C.pool.submit(C.get_up_info,D)
  524. V=W=B
  525. if L==CZ:W=L;L=Ay
  526. elif L=='quicksearch':
  527. V='投稿: ';J=C.get_up_videos_result.get(D,[])
  528. if J:I[G]=J;return I
  529. elif L==Ca:return C.get_up_series(mid=D,pg=K)
  530. X=K
  531. if W:C.get_up_info_event.wait();X=C.up_info[D][Cb]-F(K)+1
  532. h=C.encrypt_wbi(mid=D,pn=X,ps=C.userConfig[Z],order=L)[0];i=f"https://api.bilibili.com/x/space/wbi/arc/search?{h}";b=C._get_sth(i,Q).json();J=[]
  533. if b[M]==0:
  534. j=b[E][G]['vlist']
  535. for N in j:
  536. k=A(N[T]).strip();l=C.cleanCharacters(N[P].strip());n=N[Au].strip();d=C.second_to_time(C.str2sec(A(N['length']).strip()))+BL+C.zh(N[Bx])
  537. if not V:d+=' 💬'+C.zh(N['video_review'])
  538. J.append({R:m+k,O:V+l,S:C.format_img(n),Y:d})
  539. if W:J.reverse()
  540. if F(K)==1:
  541. C.get_up_info_event.wait();U=C.up_info[D];e=U[H]+Cc
  542. if V:e='UP: '+U[H]
  543. o={R:Ai+A(D),O:e,S:C.format_img(U[A5]),Y:U[AS]+' 👥'+U[Aj]+' 🎬'+A(U[BP])};J.insert(0,o)
  544. if V:C.get_up_videos_result[D]=J
  545. I[G]=J;I[a]=K;I[f]=99;I[g]=99;I[c]=999999
  546. return I
  547. history_view_at=0
  548. def get_history(D,type,pg):
  549. W='progress';H={}
  550. if F(pg)==1:D.history_view_at=0
  551. X='https://api.bilibili.com/x/web-interface/history/cursor?ps={0}&view_at={1}&type={2}'.format(D.userConfig[Z],D.history_view_at,type)
  552. if type==BQ:X='https://api.bilibili.com/x/v2/history/toview'
  553. U=D._get_sth(X).json()
  554. if U[M]==0:
  555. b=[];V=U[E].get(G,[])
  556. if type==BQ:V=D.pagination(V,pg)
  557. else:D.history_view_at=U[E]['cursor']['view_at']
  558. for C in V:
  559. I=C.get('history',B)
  560. if I:J=I['business'];K=A(I['oid']).strip();d=C[h].strip();Q=A(I[By]).strip()
  561. else:J=BK;K=A(C[T]).strip();d=C[Au].strip();Q=A(C[a][By]).strip()
  562. if J=='article':continue
  563. elif J=='pgc':K=AT+A(I[o]);e=C[c];Q=C.get('show_title')
  564. elif J==BK:K=m+K;e=C[Cd]
  565. i=D.cleanCharacters(C[P])
  566. if J==AG:j=C.get('badge',B);N=j+Ag+C['author_name'].strip()
  567. else:
  568. if A(C[W])=='-1':N='已看完'
  569. elif A(C[W])==L:N='刚开始看'
  570. else:k=A(D.second_to_time(C[W])).strip();N='看到 '+k
  571. if not e in[0,1]and Q:N+=' ('+A(Q)+')'
  572. b.append({R:K,O:i,S:D.format_img(d),Y:N})
  573. H[G]=b;H[a]=pg;H[f]=9999;H[g]=90;H[c]=999999
  574. return H
  575. def get_fav_detail(C,pg,mlid,order):
  576. I='cnt_info';D={};J='https://api.bilibili.com/x/v3/fav/resource/list?media_id=%s&order=%s&pn=%s&ps=10&platform=web&type=0'%(mlid,order,pg);F=C._get_sth(J).json()
  577. if F[M]==0:
  578. H=[];K=F[E].get('medias',[])
  579. for B in K:
  580. if B.get(k)in[2]and B.get(P)!='已失效视频':L=A(B[t]).strip();N=C.cleanCharacters(B[P]);Q=B[h].strip();T=A(C.second_to_time(B[n])).strip()+BL+C.zh(B[I][Bx])+'\u3000💬'+C.zh(B[I][BR]);H.append({R:m+L+'_mlid'+A(mlid),O:N,S:C.format_img(Q),Y:T})
  581. D[G]=H;D[a]=pg;D[f]=9999;D[g]=99;D[c]=999999
  582. return D
  583. def get_up_videoNum(B,mid):
  584. C={};I=f"http://api.bilibili.com/x/space/navnum?mid={mid}";D=B._get_sth(I,Q).json()
  585. if D[M]==0:
  586. C[BP]=A(D[E][p]).strip();G=divmod(F(C[BP]),B.userConfig[Z]);H=G[0]
  587. if G[1]!=0:H+=1
  588. C[Cb]=H
  589. B.up_info[mid].update(C);B.get_up_info_event.set()
  590. get_up_info_event=x.Event();up_info={}
  591. def get_up_info(B,mid,data={}):
  592. J='Official';D=data;C=mid;B.up_info[C]=A=B.up_info.get(C,{});B.pool.submit(B.get_up_videoNum,C)
  593. if not D:
  594. K=f"https://api.bilibili.com/x/web-interface/card?mid={C}";G=B._get_sth(K).json()
  595. if G[M]==0:D=G[E]
  596. else:return A
  597. F=D['card'];A[AS]='未关注'
  598. if D[AS]:A[AS]='已关注'
  599. A[H]=I=B.cleanCharacters(F[H]);A[Bz]=Ak+C+'_pubdate_getupvideos","name": "'+I.replace(AA,AH)+Az+I+A_;A[A5]=F[A5];A[Aj]=B.zh(F[Aj]);A[B_]=B.zh(D[B_]);A[Al]=F[J][Al]+AU+F[J][P];return A
  600. def get_vod_relation(F,query):
  601. G=f"https://api.bilibili.com/x/web-interface/archive/relation?{query}";A=F._get_sth(G).json();B=[]
  602. if A[M]==0:
  603. A=A[E]
  604. if A[Ce]:B.append('已关注')
  605. else:B.append('未关注')
  606. C=[]
  607. if A[Cf]:C.append('⭐')
  608. if A[Am]:C.append('👍')
  609. D=A.get(BS)
  610. if D:C.append('💰'*D)
  611. if U(C)==3:B.append('👍💰⭐')
  612. else:B.extend(C)
  613. if A['dislike']:B.append('👎')
  614. if A['season_fav']:B.append('已订阅合集')
  615. return B
  616. def get_follow(I,pg,sort):
  617. J=pg;D=sort;K={}
  618. if D==BT:L='https://api.bilibili.com/x/relation/followings?vmid={0}&pn={1}&ps=10&order=desc&order_type=attention'.format(I.userid,J)
  619. elif D==C0:L='https://api.bilibili.com/x/relation/followings?vmid={0}&pn={1}&ps=10&order=desc&order_type='.format(I.userid,J)
  620. elif D==B0:L='https://api.live.bilibili.com/xlive/web-ucenter/v1/xfetter/GetWebList?page={0}&page_size=10'.format(J)
  621. elif D==BU:L='https://api.bilibili.com/x/v2/history?pn={0}&ps=15'.format(J)
  622. elif D==B1:L='https://api.bilibili.com/x/relation/tag?mid={0}&tagid=-10&pn={1}&ps=10'.format(I.userid,J)
  623. elif D==C1:L='https://api.bilibili.com/x/relation/whispers?pn={0}&ps=10'.format(J)
  624. else:L='https://api.bilibili.com/x/relation/followers?vmid={0}&pn={1}&ps=10&order=desc&order_type=attention'.format(I.userid,J)
  625. Q=I._get_sth(L).json()
  626. if Q[M]!=0:return K
  627. if D==B1 or D==BU:T=Q[E]
  628. elif D==B0:T=Q[E]['rooms']
  629. else:T=Q[E][G]
  630. if F(J)==1:I.recently_up_list=[]
  631. X=[]
  632. for C in T:
  633. U=B
  634. if D==BU:
  635. N=Ai+A(C[Ah][s])
  636. if N in I.recently_up_list:continue
  637. I.recently_up_list.append(N);V=A(C[Ah][H]).strip();W=A(C[Ah][A5]).strip()
  638. elif D==B0:N=A(C[Cg]);V=I.cleanCharacters(C[P]);W=C['cover_from_user'].strip();U=C[A6].strip()
  639. else:N=Ai+A(C[s]);V=A(C[A6]).strip();W=A(C[A5]).strip()
  640. if C2 in C and C[C2]==1:U=B1
  641. X.append({R:N,O:V,S:I.format_img(W),Y:U})
  642. K[G]=X;K[a]=J;K[f]=9999;K[g]=99;K[c]=999999;return K
  643. def homeVideoContent(A):B=A.get_found(rid=L,tid=C3,pg=1)[G][:F(A.userConfig[Bl])];C={G:B};return C
  644. def categoryContent(I,tid,pg,filter,extend):
  645. u='_clicklink';O=pg;H=extend;D=tid;I.pool.submit(I.stop_heartbeat)
  646. if D==AM:
  647. if A1 in H:D=H[A1]
  648. if D.isdigit():
  649. D=F(D)
  650. if D>10000:D-=10000;return I.get_timeline(tid=D,pg=O)
  651. b=D;D=C3;return I.get_found(tid=D,rid=b,pg=O)
  652. b=L;return I.get_found(tid=D,rid=b,pg=O)
  653. elif D==Ac:
  654. D=V;P=A3;d='-1'
  655. if A1 in H:D=H[A1]
  656. if q in H:P=H[q]
  657. if C4 in H:
  658. if P==A3:P=A0
  659. d=H[C4]
  660. return I.get_bangumi(D,O,P,d)
  661. elif D==AN:
  662. R=L;P=Ay
  663. if s in H:R=H[s]
  664. if q in H:P=H[q]
  665. if R==L and not I.userid or R==As:return I.get_Login_qrcode(O)
  666. return I.get_dynamic(pg=O,mid=R,order=P)
  667. elif D==Ad:
  668. D=A3;h=L
  669. if A1 in H:D=H[A1]
  670. if N in D:i=D.split(N);D=i[0];h=i[1]
  671. return I.get_live(pg=O,parent_area_id=D,area_id=h)
  672. elif D==As:return I.get_Login_qrcode(O)
  673. elif D==BE:
  674. j=BT
  675. if C5 in H:j=H[C5]
  676. return I.get_follow(O,j)
  677. elif D==Ae:
  678. S=A(I.userConfig[Bm])
  679. if Af in H:S=H[Af]
  680. m=I.config[l].get(Ae)
  681. if S in[V,A0]:return I.get_bangumi(tid=S,pg=O,order='追番剧',season_status=B)
  682. elif S==L and m:
  683. for Q in m:
  684. if Q[W]==Af:
  685. if U(Q[K])>1:S=Q[K][2][C]
  686. break
  687. P='mtime'
  688. if q in H:P=H[q]
  689. return I.get_fav_detail(pg=O,mlid=S,order=P)
  690. elif D==BF:
  691. type=C3
  692. if k in H:type=H[k]
  693. if type==BJ:return I.get_follow(pg=O,sort=BU)
  694. return I.get_history(type=type,pg=O)
  695. elif D.endswith('_getbangumiseasons'):
  696. if F(O)==1:return{G:I.detailContent_args[D.split(N)[0]][C6]}
  697. elif D.endswith('_getupvideos'):R,P,v=D.split(N);return I.get_up_videos(pg=O,mid=R,order=P)
  698. elif D.endswith('_related'):
  699. w,v=D.split(N);x=f"https://api.bilibili.com/x/web-interface/archive/related?aid={w}";o=I._get_sth(x,e).json();T={}
  700. if o.get(M)==0:
  701. r=[]
  702. for y in J(I.get_found_vod,o[E]):r.extend(y)
  703. T[G]=r;T[a]=1;T[f]=1;T[g]=99;T[c]=40
  704. return T
  705. elif D.endswith(u):
  706. X=D.replace(u,B);Y=L
  707. if n in H:Y=H[n]
  708. return I.get_search_content(key=X,pg=O,duration_diff=Y,order=B,type=p,ps=I.userConfig[Z])
  709. else:
  710. Y=L
  711. if n in H:Y=H[n]
  712. type=p
  713. if k in H:type=H[k]
  714. P=Ch
  715. if q in H:P=H[q]
  716. X=A(I.search_key);t=I.config[l].get(Aq)
  717. if not X and t:
  718. for Q in t:
  719. if Q[W]==At:
  720. if U(Q[K])>0:X=Q[K][0][C]
  721. break
  722. if At in H:X=H[At]
  723. return I.get_search_content(key=X,pg=O,duration_diff=Y,order=P,type=type,ps=I.userConfig[Z])
  724. def get_search_content(D,key,pg,duration_diff,order,type,ps):
  725. I=pg;L=BG
  726. if not A(I).isdigit():L=I;I=1
  727. X=D.encrypt_wbi(keyword=key,page=I,duration=duration_diff,order=order,search_type=type,page_size=ps)[0];Z=f"https://api.bilibili.com/x/web-interface/wbi/search/type?{X}";V=D._get_sth(Z,Q).json();F={}
  728. if V.get(M)==0 and u in V[E]:
  729. W=[];J=V[E].get(u)
  730. if J and type==AG:J=J.get('live_room')
  731. if not J:return F
  732. for C in J:
  733. if type!=C[k]:continue
  734. H=B
  735. if type==C7:N=Ai+A(C[s]).strip();U=C['upic'].strip();K='👥'+D.zh(C[Aj])+' 🎬'+D.zh(C[Cd]);H=C[A6]
  736. elif type==AG:N=A(C[CW]).strip();U=C[h].strip();K='👁'+D.zh(C['online'])+Ag+C[A6]
  737. elif'media'in type:N=A9+A(C[A8]).strip();U=C[h].strip();K=A(C[Aw]).strip().replace('更新至','🆕')
  738. else:
  739. N=m+A(C[T]).strip();U=C[Au].strip();K=A(D.second_to_time(D.str2sec(C[n]))).strip()+BL+D.zh(C[Bx])
  740. if L==BG:K+=' 💬'+D.zh(C[BR])
  741. if not H:H=D.cleanCharacters(C[P])
  742. if L:H=L+H
  743. W.append({R:N,O:H,S:D.format_img(U),Y:K})
  744. F[G]=W;F[a]=I;F[f]=9999;F[g]=99;F[c]=999999
  745. return F
  746. def cleanSpace(C,s):return A(s).replace(An,B).replace('\t',B).replace('\r',B).replace(A7,B)
  747. def cleanCharacters(C,s):return A(s).replace('<em class="keyword">',B).replace('</em>',B).replace('&quot;',AA).replace('&amp;','&')
  748. def get_normal_episodes(L,episode):
  749. D=episode;M=D.get(AI);C=L.detailContent_args
  750. if M:C=C[M]
  751. N=D.get(T,B)
  752. if not N:N=C[T]
  753. S=D.get(v,B);H=D.get(P,B)
  754. if not H:H=D.get(By,B)
  755. J=D.get(n,B)
  756. if not J:
  757. X=D.get(a,B)
  758. if X:J=X[n]
  759. E=G=Y=U=B;O=D.get('ep_id',B)
  760. if AV in D and C8 in D[AV]:O=L.find_bangumi_id(D[AV])
  761. if O:
  762. if J and A(J).endswith(BV):J=F(J/1000)
  763. if H.isdigit():H='第'+H+C[C9]
  764. E=D.get('badge',B)
  765. if not L.session_vip.cookies and E=='会员'and L.userConfig[CN]or E=='付费'and L.userConfig[CO]:C[B2]=U=V
  766. if L.session_vip.cookies:E=E.replace('会员',B)
  767. if E==BW:E=E.replace(BW,B);Y=V
  768. if E:E='【'+E+'】'
  769. G=D.get('long_title',B)
  770. if not E and G:G=A7+G
  771. Q=H+E+G;Q=Q.replace(I,A2).replace(w,AJ)
  772. if B3 in C:
  773. if Q in C[B3]:Q+=f"_av{N}"
  774. else:C[B3].append(Q)
  775. K=f"{Q}${N}_{S}_{O}_{J}_"
  776. if M:K+='@'+M
  777. if f"{N}_{S}"in C:W=C[B4];W[0]=K+BX;K=I.join(W);C[B4]=W
  778. Z=C.get(o,B)
  779. if Z==AT+A(O):C[BY]=K
  780. b=C.get(B5,B)
  781. if b:
  782. if Y:return K,B
  783. if U:
  784. if G:G='【解析】'+G
  785. H+=G;R=f"{H}${N}_{S}_{O}_{J}_{U}"
  786. if M:R+='@'+M
  787. if Z==AT+A(O):C[BY]=R+I+C[BY]
  788. else:R=K
  789. return K,R
  790. else:return K
  791. def get_ugc_season(D,section,season_title,sec_len,array):
  792. F=season_title;E=section
  793. if sec_len>1:A=F+A7+E[P]
  794. else:A=F
  795. A=A.replace(I,A2).replace(w,AJ);G=E.get(BO);C=I.join(J(D.get_normal_episodes,J(lambda e:D.add_this_array(e,array),G)))
  796. if BX in C:C=C.replace(BX,B);return A,C,0
  797. return A,C
  798. def get_vodReply(K,oid,pg=B):
  799. W='member';V='rpid';X=K.encrypt_wbi(type=1,ps=30,oid=A(oid))[0];Y=f"https://api.bilibili.com/x/v2/reply/wbi/main?{X}";L=K._get_sth(Y).json();O=B
  800. if L[M]==0:
  801. I=L[E].get('replies');Q=L[E].get('top_replies')
  802. if Q and I:I=Q+I
  803. if I:
  804. Z=L[E]['upper'][s];R=[]
  805. for F in I:
  806. a=F[V];J=F[W]['sex']
  807. if J and J=='女':J='👧'
  808. else:J='👦'
  809. S=F[s];H=F[W][A6]
  810. if S==Z:H='🆙'+H
  811. b='👍'+K.zh(F[Am]);H=Ak+f'{S}_pubdate_getupvideos","name": "'+H.replace(AA,AH)+Az+b+J+H+A_+':';G=F[Av][Ci].strip()
  812. if'/note-app/'in G:continue
  813. if U(G)>400 or G.count(D)>24:G=K.cleanSpace(G)
  814. c=F[Av].get('jump_url',{})
  815. for(C,N)in c.items():
  816. d=C
  817. if not N.get('app_url_schema')and not N.get('pc_url'):
  818. if C.startswith('https://www.bilibili.com/')or C.startswith('https://b23.tv/'):
  819. C=A(C).split('?')[0].split(AR)
  820. while C[-1]==B:C.pop(-1)
  821. C=C[-1]
  822. if C.startswith(m)or C.startswith('BV')or C.startswith(AT)or C.startswith(A9):a=A(F[V]);T=N[P].replace(AA,AH);e=Ak+C+'_clicklink","name": "'+T+Az+'▶'+T+A_;G=G.replace(d,e)
  823. f=H+G;R.append(f)
  824. O=An.join(R)
  825. return O
  826. def add_this_array(A,e,array):e[AI]=array;return e
  827. detailContent_args={}
  828. def detailContent(H,array):
  829. A8='tag_name';A3='up_info';A1='relation';A0='vodReply';L=array;H.pool.submit(H.stop_heartbeat);L=L[0]
  830. if L.startswith(Cj):
  831. n=L.split(N)
  832. if n[1]=='tab&filter':return H.setting_tab_filter_detailContent()
  833. elif n[1]=='liveExtra':return H.setting_liveExtra_detailContent()
  834. elif n[1]=='login':return H.setting_login_detailContent(n[2])
  835. if L.startswith(G):return H.series_detailContent(L)
  836. if L.isdigit():return H.live_detailContent(L)
  837. if L.startswith(Ai):return H.up_detailContent(L)
  838. H.detailContent_args[L]=K={AI:L,**H.detailContent_args.get(L,{})};AO=K.get(B6)
  839. if AO:return H.interaction_detailContent(K)
  840. f=id=A4=p=B;V=K.get(T);AD=K.get(o)
  841. if V:
  842. L=f"av{V}"
  843. if AD:L=AD
  844. f=1
  845. K['_notfirst']=f
  846. if L.startswith(A9)or L.startswith(AT):return H.ysContent(K)
  847. for d in L.split(N):
  848. if d.startswith(m):id=d.replace(m,B);p=H.encrypt_wbi(aid=id)[0]
  849. elif d.startswith('BV'):id=d;p=H.encrypt_wbi(bvid=d)[0]
  850. elif d.startswith(Af):A4=d.replace(Af,B)
  851. if not A0 in K:K[A0]=H.pool.submit(H.get_vodReply,id)
  852. if not A1 in K:K[A1]=H.pool.submit(H.get_vod_relation,p)
  853. AP=f"https://api.bilibili.com/x/web-interface/wbi/view/detail?{p}";q=H._get_sth(AP,Q).json()
  854. if q[M]!=0:return{}
  855. W=q[E]['View'];AE=W.get(AV,B)
  856. if C8 in AE:K[o]=id=H.find_bangumi_id(AE);return H.ysContent(K)
  857. L=K[AI];Z=A(W[Ah][s]);K[T]=V=A(W.get(T));r=W.get(v)
  858. if not A3 in K:K[A3]=H.pool.submit(H.get_up_info,mid=Z,data=q[E].get('Card'))
  859. AF=H.cleanCharacters(W[P]);AQ=W[Au];j=W[Al].strip();AR=W['tname'];AS=X.strftime('%Y%m%d',X.localtime(W[Ay]));k=W[BM];t=W['rights'].get('is_stein_gate',0);g=[];g.append('▶'+H.zh(k[BN]));g.append('💬'+H.zh(k[BR]));g.append('👍'+H.zh(k[Am]));g.append('💰'+H.zh(k[BS]));g.append('⭐'+H.zh(k[Cf]));e={R:m+A(V),O:AF,S:AQ,BH:AR,CA:AS};e[Y]=AU.join(g)
  860. if f"{V}_{r}"in K:K.pop(f"{V}_{r}")
  861. A5=W[B4]
  862. if A5:K[B4]=z(J(H.get_normal_episodes,J(lambda e:H.add_this_array(e,L),A5)))
  863. a=[];c=[];u=[];A6=[];h=W.get(B3)
  864. if h:
  865. K[B3]=[];K[f"{V}_{r}"]=B;AG=h['sections']
  866. for AX in AG:b=H.pool.submit(H.get_ugc_season,AX,h[P],U(AG),L);A6.append(b)
  867. for b in Bj(A6):
  868. if b.result()[-1]==0:
  869. a.insert(0,b.result()[0]);c.insert(0,b.result()[1])
  870. if not I in b.result()[1]:f=1
  871. else:a.append(b.result()[0]);c.append(b.result()[1])
  872. A6.remove(b)
  873. u.append(T)
  874. if not f:u+=[A0,A1,A3,f"{V}_{r}"]
  875. else:
  876. a=['B站']
  877. if t:a[0]='互动视频'
  878. if not h or not f:
  879. if A5:a=[a[0]];AY=I.join(K[B4]).replace(BX,B);c=[AY]
  880. if H.userid:
  881. AZ=f"➕关注${V}_{Z}__1__notplay_follow";Aa=f"➖取关${V}_{Z}__2__notplay_follow";Ab=f"👍点赞${V}_{Z}__1__notplay_like";Ac=f"👍🏻取消点赞${V}_{Z}__2__notplay_like";Ad=f"👍💰投币${V}_{Z}__1__notplay_coin";Ae=f"👍💰💰${V}_{Z}__2__notplay_coin";Ag=f"👍💰⭐三连${V}_{Z}____notplay_triple";A7=[AZ,Ag,Ab,Ad,Ae,Aa,Ac]
  882. if A4:Ao=f"☆取消收藏${V}_{Z}__{A4}_del_notplay_fav";A7.append(Ao)
  883. for x in H.userConfig.get(CQ,[]):Ap=x[D].replace(I,A2).replace(w,AJ);Aq=x[C];x=f"⭐{Ap}${V}_{Z}__{Aq}_add_notplay_fav";A7.append(x)
  884. Ar=I.join(A7);a.insert(1,'做点什么');c.insert(1,Ar)
  885. if t:c[0]='片头$'+c[0].split(w)[1]
  886. e[AB]=i.join(a);e[AC]=i.join(c)
  887. if not h or f:
  888. y=[Ak+A(V)+'_related","name":"'+AF.replace(AA,AH)+'"}/]相关推荐[/a]']
  889. if U(j)<60 and j.count(D)<4:j+=An*F(3-U(j)/29)
  890. y.append(j);As=';'.join(sorted(J(lambda x:Ak+x[A8].replace(AA,AH)+'_clicklink","name":"'+x[A8].replace(AA,AH)+Az+A2+x[A8]+A2+A_,q[E].get('Tags',[])),key=U));y.append(As);l=K.get(A3);AK=K.get(A1)
  891. if l and AK:l=l.result();e[BZ]=Ba+l[Bz]+Ck+l[Aj]+AU+AU.join(AK.result())
  892. AL=K.get(A0)
  893. if AL:y.append(AL.result())
  894. e[AW]=An.join(y)
  895. if t:K[CB]=a.copy();K[Bb]=c.copy();K[CC]=e.copy();u+=[T,CB,Bb,CC]
  896. if not h and not t:H.detailContent_args.pop(L)
  897. else:
  898. AM={}
  899. for(AN,At)in K.items():
  900. if AN in u:AM[AN]=At
  901. H.detailContent_args[L]=AM.copy()
  902. Av={G:[e]};return Av
  903. def interaction_detailContent(V,array):
  904. C=array;M=C.get(AI);N=C.get(T);W=C.get(v,0);O=C.get(CD,0);X=C.get(B6);Y=f"https://api.bilibili.com/x/stein/edgeinfo_v2?aid={N}&graph_version={X}&edge_id={O}";F=V._get_sth(Y,Q).json().get(E);R={}
  905. if F:
  906. S=C.get(CB).copy();D=C.get(Bb).copy();H=C.get(CC)
  907. if O:J=A(F[P]).replace(I,A2).replace(w,AJ);D[0]+=f"#{J}${N}_{W}___@{M}"
  908. else:D[0]=D[0].split(I)[0]
  909. C[Bb]=D.copy();Z=F['edges'].get('questions',[]);K=[]
  910. for U in Z:
  911. a=U.get(P,B)
  912. for L in U.get('choices',[]):b=L[t];c=L[v];d=L.get('option',B);J=A7.join([a,d]).replace(I,A2).replace(w,AJ);K.append(f"{J}${b}_{c}_interaction@{M}")
  913. if K:S.insert(1,'选项');D.insert(1,I.join(K))
  914. else:C.pop(CD);C.pop(v)
  915. H[AB]=i.join(S);H[AC]=i.join(D);R[G]=[H]
  916. return R
  917. def series_detailContent(C,array):
  918. U='archives';K=array;L,type,V=K.replace('list_',B).split(N);D=1;M=99;A={R:K,AB:'B站'};S=[]
  919. while Ab:
  920. W='https://api.bilibili.com/x/series/archives?mid=%s&series_id=%s&pn=%s&ps=%s'%(L,V,D,M);X=C._get_sth(W,Q).json();F=X.get(E)
  921. if not A.get(O):A[O]=F[U][0][P]
  922. Y=I.join(J(C.get_normal_episodes,F.get(U)));S.append(Y);Z=F[a][c]
  923. if M*D>=Z:break
  924. D+=1
  925. A[AC]=I.join(S);T=C.up_info[L];A[BZ]=Ba+T[H]+AU+T[AS];b={G:[A]};return b
  926. def up_detailContent(L,array):
  927. F=array.replace(Ai,B);L.get_up_info_event.clear();L.pool.submit(L.get_up_info,F);Q=f"关注$_{F}__1__notplay_follow";R=f"取消关注$_{F}__2__notplay_follow";T=f"特别关注$_{F}__-10_special_notplay_follow";U=f"取消特别关注$_{F}__0_special_notplay_follow";P=[Q,T,R,U];P='做点什么$ $$$'+I.join(P);L.get_up_info_event.wait();E=L.up_info[F];M={O:E[H]+Cc,S:E[A5],BZ:Ba+E[H]+AU+E[AS]+'\u3000UID:'+A(F),Y:'👥 '+E[Aj]+'\u3000🎬 '+E[BP]+'\u3000👍 '+E[B_],AW:E[Al]}
  928. if L.userid:M[AB]='做点什么$$$关注TA';M[AC]=P
  929. V=L.config[l].get(AN);M[Cl]=A7.join(J(lambda x:Ak+A(F)+N+x[C]+'_getupvideos","name": "'+E[H].replace(AA,AH)+' '+x[D]+Az+x[D]+A_,V[-1][K]));W={G:[M]};return W
  930. def setting_login_detailContent(J,key):
  931. M=key;E='f';D='d';C='c';W=J.cookie_dic_tmp.get(M,B);K=B
  932. if not W:K=J.get_cookies(M)
  933. if K:K=f"【{K}】通过手机客户端扫码确认登录后点击相应按钮设置账号"
  934. else:K='【已扫码并确认登录】请点击相应按钮设置当前获取的账号为:'
  935. Q={O:'登录与设置',AW:'通过手机客户端扫码并确认登录后,点击相应按钮设置cookie,设置后不需要管嗅探结果,直接返回二维码页面刷新,查看是否显示已登录,已登录即可重新打开APP以加载全部标签'};T=['登录$$$退出登录'];P=[];X=K+'$ ';Y='设置为主账号,动态收藏关注等内容源于此$'+A(M)+'_master_login_setting';Z='设置为备用的VIP账号,仅用于播放会员番剧$'+A(M)+'_vip_login_setting';P.append(I.join([X,Y,Z]));a='点击相应按钮退出账号>>>$ ';b='退出主账号$master_logout_setting';c='退出备用的VIP账号$vip_logout_setting';P.append(I.join([a,b,c]));d=[{E:'主页站点推荐栏',C:Bl,D:{AL:'3图',AQ:'4图','6':'6图','8':'8图','9':'9图'}},{E:'视频画质',C:Bn,D:J.vod_qn_id},{E:'视频编码',C:Bo,D:J.vod_codec_id},{E:'音频码率',C:Ap,D:J.vod_audio_id},{E:'收藏默认显示',C:Bm,D:{L:'默认收藏夹',V:'追番',A0:'追剧'}},{E:'上传播放进度',C:BA,D:{L:'关','15':'开'}},{E:'直播筛选细化',C:Bp,D:{L:'关',V:'开'}}]
  936. for H in d:
  937. T.append(H[E]);R=H[D][A(F(J.userConfig[H[C]]))]
  938. if Ap==H[C]:R=A(R).replace(BV,'k')
  939. U=['当前:'+R+'$ ']
  940. for(id,S)in H[D].items():
  941. if Ap==H[C]:S=A(S).replace(BV,'k')
  942. U.append(S+w+A(id)+N+H[C]+'_setting')
  943. P.append(I.join(U))
  944. Q[AB]=i.join(T);Q[AC]=i.join(P);e={G:[Q]};return e
  945. def setting_tab_filter_detailContent(K):
  946. L={O:'标签与筛选',AW:'依次点击各标签,同一标签第一次点击为添加,第二次删除,可以返回到二维码页后重进本页查看预览,最后点击保存,未选择的将追加到末尾,如果未保存就重启app,将丢失未保存的配置'};M=[];P=[];V=[{D:BB,C:'标签'},{D:BC,C:'推荐[分区]'},{D:BD,C:'推荐[排行榜]'},{D:r,C:Ad}]
  947. for Q in V:
  948. F=Q[D];M.append(Q[C]);E=K.userConfig.get(A(F)+AD,[]);R=B
  949. if E:R='【未保存】'
  950. else:E=K.userConfig.get(F,[])
  951. if not E:E=K.defaultConfig.get(F)
  952. if E and Aa(E[0])==d:E=z(J(lambda x:x[D],E))
  953. S=['当前: '+','.join(E)+'$ ',f"{R}点击这里保存$_{F}_save_setting",f"点击这里恢复默认并保存$_{F}_clear_setting"];T=K.defaultConfig[F].copy()
  954. if F==r:W=K.userConfig.get(A4,[]);T.extend(W.copy())
  955. for H in T:
  956. U=A(H)
  957. if Aa(H)==d:U=H[D]+Ao+H[C].replace(N,Ao);H=H[D]
  958. S.append(f"{H}${U}_{F}_setting")
  959. P.append(I.join(S))
  960. L[AB]=i.join(M);L[AC]=i.join(P);X={G:[L]};return X
  961. def setting_liveExtra_detailContent(H):
  962. Q='_liveFilter_setting';F={O:CS,AW:'点击想要添加的标签,同一标签第一次点击为添加,第二次删除,完成后在[标签与筛选]页继续操作,以添加到直播筛选分区列中'};J=['已添加'];R=H.userConfig.get(A4,[]);E=['点击相应标签(只)可以删除$ #清空$clear_liveFilter_setting']
  963. for B in R:S=B[C];B=B[D];E.append(B+w+'del_'+B+N+S+Q)
  964. E=[I.join(E)];T=H.userConfig.get(AO,{})
  965. for(V,W)in T.items():
  966. L=W[K][K]
  967. if U(L)==1:continue
  968. J.append(V);M=[]
  969. for P in L:B=A(P[D]).replace(N,'-').replace(I,A2).replace(w,AJ);id=A(P[C]).replace(N,Ao).replace(I,A2).replace(w,AJ);M.append(B+'$add_'+B+N+id+Q)
  970. E.append(I.join(M))
  971. F[AB]=i.join(J);F[AC]=i.join(E);X={G:[F]};return X
  972. def get_all_season(C,season):
  973. B=season;D=A(B[A8]);E=B[CE];F=C.detailContent_args[B[AI]]
  974. if D==F[B5]:F[B7]=E
  975. G=B[h];H=B[Ax][Aw];I={R:A9+D,O:E,S:C.format_img(G),Y:H};return I
  976. def get_bangumi_section(B,section,array):
  977. A=section;C=A[P].replace(I,A2).replace(w,AJ);D=A[k]
  978. if D in[1,2]and U(A['episode_ids'])==0:E=A[BO];F=z(J(lambda x:B.get_normal_episodes(x)[0],J(lambda e:B.add_this_array(e,array),E)));return C,F
  979. def ysContent(E,this_array):
  980. r='rating';C=this_array;F=C[AI];X=C.get(T);d=C.get(o)
  981. if d:F=d;C.pop(o)
  982. if AT in F:X='ep_id='+F.replace(AT,B);C[o]=F
  983. else:X='season_id='+F.replace(A9,B)
  984. F=C[AI];s='https://api.bilibili.com/pgc/view/web/season?{0}'.format(X);D=E._get_sth(s,Q).json().get(u,{});C[B5]=Z=A(D[A8]);e=D[P];C[B7]=D[CE];C[C9]='集'
  985. if D[k]in[1,4]:C[C9]='话'
  986. N=D[Ax][Al]
  987. if r in D:N=A(D[r]['score'])+'分 '+N
  988. M=D.get(C6)
  989. if U(M)==1:C[B7]=M[0][CE];M=0
  990. elif U(M)>1:C[C6]=z(J(E.get_all_season,J(lambda e:E.add_this_array(e,F),M)));N+=' [a=cr:{"id": "'+F+'_getbangumiseasons","name": "'+e.replace(AA,AH)+'"}/]更多系列[/a]'
  991. f=D.get(BO);g=[]
  992. for H in D.get('section',[]):
  993. if H:a=E.pool.submit(E.get_bangumi_section,H,F);g.append(a)
  994. t=D[h];v=D['share_sub_title'];w=D['publish']['pub_time'][0:4];x=D['evaluate'];j=D[BM];y='▶'+E.zh(j['views'])+'\u3000❤'+E.zh(j['favorites']);V={R:A9+Z,O:e,S:t,BH:v,CA:w,Cl:y,AW:x};V[Y]=N;W=[];K=[];L=[]
  995. if f:
  996. b=[];c=[]
  997. for(l,m)in J(E.get_normal_episodes,J(lambda e:E.add_this_array(e,F),f)):
  998. if m:b.append(l);c.append(m)
  999. else:W.append(l)
  1000. if C.get(B2)and c:K.append(A(C[B7])+'【解析】');L.append(I.join(c))
  1001. if b:K.append(A(C[B7]));L.append(I.join(b))
  1002. n=[];p=[]
  1003. for a in Bj(g):
  1004. H=a.result()
  1005. if H:
  1006. if H[0]==BW:W+=H[1]
  1007. else:n.append(H[0]);p.append(I.join(H[1]))
  1008. if W:K.append(BW);L.append(I.join(W))
  1009. K+=n;L+=p;q=C.get(BY)
  1010. if q:K.insert(0,'B站');L.insert(0,q)
  1011. if E.userid:A0='做点什么';A1=f"❤追番剧$__{Z}_add__notplay_zhui#💔取消追番剧$__{Z}_del__notplay_zhui";K.insert(1,A0);L.insert(1,A1)
  1012. V[AB]=i.join(K);V[AC]=i.join(L);A2={G:[V]};return A2
  1013. def get_live_api2_playurl(W,room_id):
  1014. K=room_id;O=[];P=[];G='https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo?room_id={0}&qn=0&platform=web&protocol=0,1&format=0,1,2&codec=0,1&dolby=5&panorama=1'.format(K);Q=W._get_sth(G,AF).json()
  1015. if Q[M]==0:
  1016. H=Q[E].get(Cm,B)
  1017. if H:
  1018. X=H[CF][Cn];C={Bc:{'avc':L,'hevc':V},AX:{'flv':L,'ts':V,'fmp4':A0}};C[AY]=d(J(lambda x:(x[AY],x[Al]),H[CF]['g_qn_desc']));R=[]
  1019. for Y in X:R.extend(Y[AX])
  1020. D={}
  1021. for S in R:
  1022. format=A(S.get('format_name'))
  1023. for T in S[Bc]:
  1024. U=A(T.get('codec_name'));Z=T.get('accept_qn')
  1025. for F in Z:
  1026. G=format+N+U+f"$live_{K}_"+A(F)+N+C[AX][format]+N+C[Bc][U]
  1027. if not D.get(C[AY][F]):D[C[AY][F]]=[]
  1028. D[C[AY][F]].append(G)
  1029. for(a,b)in D.items():O.append(a);P.append(I.join(b))
  1030. c=O,P;return c
  1031. def live_detailContent(C,room_id):
  1032. J=room_id;L=C.pool.submit(C.get_live_api2_playurl,J);W='https://api.live.bilibili.com/room/v1/Room/get_info?room_id='+A(J);N=C._get_sth(W,Q).json();T={}
  1033. if N.get(M)==0:
  1034. B=N[E];K=A(B['uid']);H=C.pool.submit(C.get_up_info,K);X=C.cleanCharacters(B[P]);Y=B.get(CX);Z=B.get(CY);a=B.get('parent_area_name')+'-'+B.get('area_name');D={R:J,O:X,S:Y,BH:a,AW:Z}
  1035. if F(B.get(CT)):D[CA]=B.get('live_time').replace('-','.')
  1036. U=L.result()[0];V=L.result()[1]
  1037. if C.userid:b='关注TA';c='是否关注$ ';d=f"➕关注$_{K}__1__notplay_follow";e=f"➖取关$_{K}__2__notplay_follow";f=[c,d,e];g=I.join(f);U.insert(1,b);V.insert(1,g)
  1038. D[AB]=i.join(U);D[AC]=i.join(V);H=H.result();D[BZ]=Ba+H[Bz]+Ck+C.zh(B.get(Ce))+AU+H[AS];T[G]=[D]
  1039. return T
  1040. search_key=B
  1041. def searchContent(A,key,quick,pg=V):
  1042. E=key
  1043. if not A.session_fake.cookies:A.pool.submit(A.getFakeCookie,Ab)
  1044. for C in A.task_pool:C.cancel()
  1045. if F(pg)>1:return A.get_search_content(key=E,pg=pg,duration_diff=0,order=B,type=p,ps=A.userConfig[Z])
  1046. A.task_pool=[];A.search_key=E;I={p:B,Co:'番剧: ',Cp:'影视: ',C7:'用户: ',AG:'直播: '}
  1047. for(type,J)in I.items():C=A.pool.submit(A.get_search_content,key=E,pg=J,duration_diff=0,order=B,type=type,ps=A.userConfig[Z]);A.task_pool.append(C)
  1048. D={};H=[]
  1049. for C in Bj(A.task_pool):K=C.result().get(G,[]);H.extend(K);A.task_pool.remove(C)
  1050. if U(H):D[G]=H;D[a]=pg;D[f]=9999;D[g]=99;D[c]=999999
  1051. return D
  1052. stop_heartbeat_event=x.Event()
  1053. def stop_heartbeat(A):
  1054. try:
  1055. for B in A.task_pool:B.cancel()
  1056. finally:A.stop_heartbeat_event.set()
  1057. def start_heartbeat(B,aid,cid,ssid,epid,duration,played_time):
  1058. E=played_time;G=F(B.userConfig[BA])
  1059. if not B.userid or not G:return
  1060. H=F((duration-E)/G)+1;I='https://api.bilibili.com/x/click-interface/web/heartbeat';C={T:A(aid),v:A(cid),Bd:A(B.csrf)}
  1061. if ssid:C['sid']=A(ssid);C[o]=A(epid);C[k]=AQ
  1062. D=0;B.stop_heartbeat_event.clear()
  1063. while Ab:
  1064. if D==G or B.stop_heartbeat_event.is_set():E+=D;D=0
  1065. if not D:
  1066. H-=1
  1067. if not H:E=-1;B.stop_heartbeat_event.set()
  1068. C['played_time']=A(E);C=B.encrypt_wbi(**C)[1];B.pool.submit(B._post_sth,url=I,data=C)
  1069. if B.stop_heartbeat_event.is_set():break
  1070. X.sleep(1);D+=1
  1071. wbi_key={}
  1072. def get_wbiKey(A,hour):D='wbi_img';C=A.fetch(CP,headers=A.header);F=C.json()[E][D]['img_url'];G=C.json()[E][D]['sub_url'];H=[46,47,18,2,53,8,23,32,15,50,10,31,58,3,45,35,27,43,5,49,33,9,42,19,29,28,14,39,12,38,41,13,37,48,7,16,24,55,40,61,26,17,0,1,60,51,30,4,22,25,54,21,56,59,6,63,57,62,11,36,20,34,44,52];I=F.split(AR)[-1].split('.')[0]+G.split(AR)[-1].split('.')[0];J=reduce(lambda s,i:s+I[i],H,B)[:32];A.wbi_key={W:J,'hour':hour}
  1073. def encrypt_wbi(D,**C):
  1074. E=AK(X.time());F=X.gmtime(E).tm_hour
  1075. if not D.wbi_key or F!=D.wbi_key['hour']:D.get_wbiKey(F)
  1076. C['wts']=E;G='ABCDEFGHIJK';C['dm_img_list']='[]';C['dm_img_str']=B.join(B8.sample(G,2));C['dm_cover_img_str']=B.join(B8.sample(G,2));C['dm_img_inter']='{"ds":[],"wh":[0,0,0],"of":[0,0,0]}';C=d(sorted(C.items()));C={C:B.join(filter(lambda chr:chr not in"!'()*",A(D)))for(C,D)in C.items()};H=Bk(C);I=hashlib.md5((H+D.wbi_key[W]).encode(encoding=Br)).hexdigest();C['w_rid']=I;return[H+'&w_rid='+I,C]
  1077. def _get_sth(A,url,_type=e,**C):
  1078. E=_type;B=url
  1079. if E==AF and A.session_vip.cookies:D=A.session_vip.get(B,headers=A.header,**C)
  1080. elif E==Q:
  1081. if not A.session_fake.cookies:A.getFakeCookie_event.wait()
  1082. D=A.session_fake.get(B,headers=A.header,**C)
  1083. else:D=A.session_master.get(B,headers=A.header,**C)
  1084. return D
  1085. def _post_sth(A,url,data):return A.session_master.post(url,headers=A.header,data=data)
  1086. def post_live_history(B,room_id):C={Cg:A(room_id),'platform':'pc',Bd:A(B.csrf)};D='https://api.live.bilibili.com/xlive/web-room/v1/index/roomEntryAction';B._post_sth(url=D,data=C)
  1087. def do_notplay(E,ids):
  1088. L='triple';K='fav';H,I,M,G,J,N,F=ids;C={Bd:A(E.csrf)};O=D=B
  1089. if F=='follow':
  1090. if J==C2:C.update({'fids':A(I),'tagids':A(G)});D='https://api.bilibili.com/x/relation/tags/addUsers'
  1091. else:C.update({'fid':A(I),'act':A(G)});D='https://api.bilibili.com/x/relation/modify'
  1092. elif F=='zhui':C.update({A8:A(M)});D='https://api.bilibili.com/pgc/web/follow/'+A(G)
  1093. elif F==Am:C.update({T:A(H),Am:A(G)});D='https://api.bilibili.com/x/web-interface/archive/like'
  1094. elif F==BS:C.update({T:A(H),'multiply':A(G),'select_like':V});D='https://api.bilibili.com/x/web-interface/coin/add'
  1095. elif F==K:C.update({'rid':A(H),k:A0});C[J+'_media_ids']=A(G);D='https://api.bilibili.com/x/v3/fav/resource/deal'
  1096. elif F==L:C.update({T:A(H)});D='https://api.bilibili.com/x/web-interface/archive/like/triple'
  1097. E._post_sth(url=D,data=C)
  1098. if F in[Am,BS,K,L]:C={T:A(H),Bd:A(E.csrf),'csrf_token':A(E.csrf)};D='https://api.bilibili.com/x/web-interface/share/add';E.pool.submit(E._post_sth,url=D,data=C)
  1099. E._refreshDetail()
  1100. def get_cid(D,aid,cid):
  1101. C=cid;G=f"https://api.bilibili.com/x/web-interface/view?aid={aid}&cid={C}";A=D._get_sth(G).json().get(E,{})
  1102. if not C:C=A[v]
  1103. H=A[n];F=B
  1104. if AV in A and C8 in A[AV]:F=D.find_bangumi_id(A[AV])
  1105. return C,H,F
  1106. cookie_dic_tmp={}
  1107. def get_cookies(A,key):
  1108. D='https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key='+key;B=A._get_sth(D,Q).json()
  1109. if B[M]==0:
  1110. C=B[E][Ci]
  1111. if not C:A.cookie_dic_tmp[key]=d(A.session_fake.cookies);A.pool.submit(A.getFakeCookie)
  1112. return C
  1113. return'网络错误'
  1114. def set_cookie(A,key,_type):
  1115. D=_type;C=key;F=A.cookie_dic_tmp.get(C,B)
  1116. if not F:
  1117. G=A.get_cookies(C)
  1118. if G:return
  1119. E=A.userConfig.get(j,{});E[D]={AE:A.cookie_dic_tmp.get(C,{})};A.userConfig.update({j:E});A.getCookie(D);A.dump_config()
  1120. def unset_cookie(A,_type):
  1121. C=_type
  1122. if C==AF:A.session_vip.cookies.clear()
  1123. else:A.session_master.cookies=A.session_fake.cookies;A.userid=A.csrf=B
  1124. if C in A.userConfig.get(j,{}):A.userConfig[j].pop(C);A.dump_config()
  1125. def set_normal_default(B,id,type):B.userConfig[type]=A(id);B.dump_config()
  1126. def set_normal_cateManual(B,name,_List,action):
  1127. H=action;F=name;E=_List;G=B.userConfig.get(A(E)+AD)
  1128. if not G:G=B.userConfig[A(E)+AD]=[]
  1129. if H=='save':
  1130. for I in B.defaultConfig[E]:
  1131. if not I in G.copy():B.userConfig[A(E)+AD].append(I)
  1132. B.userConfig[E]=B.userConfig[A(E)+AD].copy();B.userConfig.pop(E+AD);B.dump_config()
  1133. elif H=='clear':B.userConfig[E]=B.defaultConfig[E].copy();B.userConfig.pop(A(E)+AD);B.dump_config()
  1134. else:
  1135. if E==r:
  1136. F=F.split(Ao)
  1137. if U(F)==3:F[1]+=N+A(F[2])
  1138. F={D:F[0],C:A(F[1])}
  1139. if F in G:B.userConfig[A(E)+AD].remove(F)
  1140. else:B.userConfig[A(E)+AD].append(F)
  1141. def add_cateManualLiveExtra(A,action,name,id):
  1142. F='cateManualLive_tmp';G=A.userConfig.get(A4,[])
  1143. if not G:G=A.userConfig[A4]=[]
  1144. if action=='clear':
  1145. for E in G:
  1146. E[C]=E[C].replace(Ao,N)
  1147. if E in A.userConfig.get(r,[]):A.userConfig[r].remove(E)
  1148. if E in A.userConfig.get(F,[]):A.userConfig[F].remove(E)
  1149. A.userConfig.pop(A4)
  1150. elif id in z(J(lambda x:x[C],A.userConfig.get(A4,[]))):
  1151. B={D:name,C:id};A.userConfig[A4].remove(B);B[C]=id.replace(Ao,N)
  1152. if B in A.userConfig.get(r,[]):A.userConfig[r].remove(B)
  1153. if B in A.userConfig.get(F,[]):A.userConfig[F].remove(B)
  1154. else:B={D:name,C:id};A.userConfig[A4].append(B)
  1155. A.dump_config()
  1156. vod_qn_id={'127':'8K','126':'杜比视界','125':'HDR','120':'4K','116':'1080P60帧','112':'1080P+','80':'1080P','64':'720P'};vod_codec_id={'7':'avc','12':'hevc','13':'av1'};vod_audio_id={'30251':'Hi-Res无损','30250':'杜比全景声','30280':Cq,'30232':'132000','30216':'64000'}
  1157. def get_dash_media(E,media,aid,cid,qn):
  1158. I='SegmentBase';C=media;F=A(C.get(t));J=C.get(CG,B);K=C.get('codecs');L=C.get('bandwidth');M=C.get('startWithSap');H=C.get(Cr);O=C[I].get('indexRange');P=C[I].get('Initialization');D=H.split(AR)[0];G=B
  1159. if D==p:Q=C.get('frameRate');R=C.get('sar');S=C.get('width');T=C.get('height');G=f"height='{T}' width='{S}' frameRate='{Q}' sar='{R}'"
  1160. elif D==AZ:U=E.vod_audio_id.get(F,Cq);G=f"numChannels='2' sampleRate='{U}'"
  1161. V=f"{E.localProxyUrl}{D}&aid={aid}&cid={cid}&qn={qn}".replace('&','&amp;');F+=N+A(J);W=f'''
  1162. <Representation id="{F}" bandwidth="{L}" codecs="{K}" mimeType="{H}" {G} startWithSAP="{M}">
  1163. <BaseURL>{V}</BaseURL>
  1164. <SegmentBase indexRange="{O}">
  1165. <Initialization range="{P}"/>
  1166. </SegmentBase>
  1167. </Representation>''';E.pC_urlDic[f"{aid}_{cid}"][D]=C;return W
  1168. def get_dash_media_list(E,media_lis,aid,cid,qn):
  1169. F=media_lis
  1170. if not F:return B
  1171. G=F[0][Cr].split(AR)[0]
  1172. if G==p:I=A(qn);H=A(E.userConfig[Bo])
  1173. else:I=A(E.userConfig[Ap]);H=L
  1174. C={}
  1175. for D in F:
  1176. if G==AZ and not C:C=D
  1177. if A(D[t])==I:
  1178. if not C or A(D[CG])==H:
  1179. C=D
  1180. if A(D[CG])==H:break
  1181. J=f'\n <AdaptationSet>\n <ContentComponent contentType="{G}"/>{E.get_dash_media(C,aid,cid,qn)}\n </AdaptationSet>';return J
  1182. def get_dash(B,ja,aid,cid,qn):
  1183. A=ja;D=A.get(n);G=A.get('minBufferTime');H=B.pool.submit(B.get_dash_media_list,A.get(p),aid,cid,qn);C=A.get(AZ,[]);E=A.get('dolby',{}).get(AZ)
  1184. if E:C=E+C
  1185. F=A.get('flac')
  1186. if Aa(F)==d:C.insert(0,F.get(AZ))
  1187. I=B.pool.submit(B.get_dash_media_list,C,aid,cid,qn);J=f'<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" type="static" mediaPresentationDuration="PT{D}S" minBufferTime="PT{G}S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">\n <Period duration="PT{D}S" start="PT0S">{H.result()}{I.result()}\n </Period>\n</MPD>';return J
  1188. def miao(B,m):
  1189. m=A(m).partition('.')[2]
  1190. if U(m)==0:m=BV
  1191. if U(m)==1:m=m+'00'
  1192. if U(m)==2:m=m+L
  1193. return m
  1194. def down_sub(C,url):
  1195. I=C._get_sth(url,Q).json()['body'];E=B;F=1
  1196. for D in I:G=AK(D['from'],3);H=AK(D['to'],3);J=D[Av];K=X.strftime(Bw,X.gmtime(G))+','+C.miao(G);L=X.strftime(Bw,X.gmtime(H))+','+C.miao(H);E+=A(F)+An+K+A7+'-->'+A7+L+An+J+'\n\n';F+=1
  1197. return E
  1198. localProxyUrl='http://127.0.0.1:9978/proxy?do=py&siteType=3&siteKey=py_bilibili&type='
  1199. def get_subs(J,aid,cid):
  1200. L='application/x-subrip';I=[];M=J.encrypt_wbi(aid=aid,cid=cid)[0];N=f"https://api.bilibili.com/x/player/wbi/v2?{M}";D=J._get_sth(N,e).json().get(E)
  1201. if D:
  1202. for K in D[Cs].get('subtitles',[]):
  1203. O=A(K.get('lan_doc',B));C=K.get('subtitle_url')
  1204. if C.startswith('//'):C=CR+C
  1205. C=CK(C);I.append({b:f"{J.localProxyUrl}subtitle&url={C}",H:O,AX:L})
  1206. if I:I.insert(0,{b:B,H:A7,AX:L})
  1207. G=0
  1208. if F(D.get('last_play_cid',0))==F(cid):
  1209. G=F(D.get('last_play_time'))
  1210. if G>0:G=F(G/1000)
  1211. P=D.get(Ct,{}).get(B6,B);return I,G,P
  1212. pC_urlDic={}
  1213. def _get_playerContent(G,result,aid,cid,epid):
  1214. e='durls';c='video_info';W='quality';P=epid;N=cid;L=aid;C=result;G.pC_urlDic[f"{L}_{N}"]=I={**G.pC_urlDic.get(f"{L}_{N}",{}),T:L,v:N,o:P};R=G.userConfig[Bn]
  1215. if P:H='https://api.bilibili.com/pgc/player/web/v2/playurl?aid={}&cid={}&qn={}&fnval=4048&fnver=0&fourk=1&from_client=BROWSER'.format(L,N,R)
  1216. else:
  1217. X={'avid':L,v:N,AY:R,'fnval':4048,'fnver':0,'fourk':1,'from_client':'BROWSER'}
  1218. if not G.session_vip.cookies:X['try_look']=1
  1219. f=G.encrypt_wbi(**X)[0];H=f"https://api.bilibili.com/x/player/wbi/playurl?{f}"
  1220. Q=G._get_sth(H,AF).json();S=B
  1221. if Q[M]==0:
  1222. if E in Q:D=Q[E]
  1223. elif u in Q:
  1224. D=Q[u]
  1225. if c in D:Y=D['view_info']['report'];S=Y[A8];P=Y['ep_id'];D=D[c]
  1226. else:return C
  1227. else:return C
  1228. I[B5]=S;I[o]=P;Z=d(J(lambda x:(x[W],x['new_description']),D['support_formats']));C[b]=[];U=D.get('dash');V=f"&aid={L}&cid={N}&qn="
  1229. if U:
  1230. I[CH]=U;C[AX]=Cu
  1231. for g in U[p]:
  1232. id=g[t];O=Z[id]
  1233. if not O in C[b]:
  1234. H=f"{G.localProxyUrl}dash{V}{id}"
  1235. if id==F(R):C[b]=[O,H]+C[b]
  1236. else:C[b].extend([O,H])
  1237. elif e in D:
  1238. for a in D[e]:
  1239. K=a[W];O=Z[K];H=f"{G.localProxyUrl}durl{V}{K}"
  1240. if K==F(R):C[b]=[O,H]+C[b]
  1241. else:C[b].extend([O,H])
  1242. I[A(K)]=a[Be][0]
  1243. else:K=D[W];I[A(K)]=D[Be][0];C[b]=f"{G.localProxyUrl}durl{V}{K}"
  1244. I[u]={**I.get(u,{}),**C};return C,S,P
  1245. def _refreshDetail(A,t=0):X.sleep(F(t));A.fetch('http://127.0.0.1:9978/action?do=refresh&type=detail')
  1246. def playerContent(C,flag,id,vipFlags):
  1247. C.pool.submit(C.stop_heartbeat);D={};P=B
  1248. if'@'in id:id,P=id.split('@')
  1249. I=C.detailContent_args.get(P,C.detailContent_args);H=id.split(N)
  1250. if U(H)<2:return D
  1251. if AG==H[0]:return C.live_playerContent(id)
  1252. G=H[0];E=H[1]
  1253. if Cj in H:
  1254. if'liveFilter'in H:id=H[2];C.add_cateManualLiveExtra(G,E,id)
  1255. elif E in[BB,r,BC,BD]:S=H[2];C.set_normal_cateManual(G,E,S)
  1256. elif'login'in H:C.set_cookie(G,E)
  1257. elif'logout'in H:C.unset_cookie(G)
  1258. else:C.set_normal_default(G,E)
  1259. return D
  1260. elif'notplay'in H:C.pool.submit(C.do_notplay,H);return D
  1261. elif Ct in H:I[CD]=G;I[v]=E;C.pool.submit(C._refreshDetail);return D
  1262. G,E,J,M,W=id.split(N)
  1263. if not E or not M:E,M,J=C.get_cid(G,E)
  1264. D[BR]='https://api.bilibili.com/x/v1/dm/list.so?oid='+A(E)
  1265. if W:X='https://www.bilibili.com/bangumi/play/ep'+A(J);D[b]=X;D['flag']='bilibili';D[B2]=V;D['jx']=V;D[CI]={AP:C.header[AP]};return D
  1266. Y=C.pool.submit(C.get_subs,G,E);K=C.pC_urlDic.get(f"{G}_{E}")
  1267. if K:D,Q,J=K[u],K[B5],K[o]
  1268. else:D[B2]=L;D[CJ]=B;D[CI]=C.header;D,Q,J=C._get_playerContent(D,G,E,J)
  1269. D['subs'],Z,O=Y.result();a=I.get(B6,B);R=I.get(T)
  1270. if R and G!=R or f"{G}_{E}"in I:I[T]=G;C.pool.submit(C._refreshDetail,2)
  1271. elif O and a!=O:I[B6]=O;C.pool.submit(C._refreshDetail)
  1272. else:c=C.pool.submit(C.start_heartbeat,G,E,Q,J,F(M),Z);C.task_pool.append(c)
  1273. return D
  1274. def live_playerContent(D,id):
  1275. K='url_info';T,I,O,format,G=id.split(N)
  1276. if D.userid and F(D.userConfig[BA])>0:D.pool.submit(D.post_live_history,I)
  1277. P='https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo?room_id={0}&protocol=0,1&format={1}&codec={2}&qn={3}&ptype=8&platform=web&dolby=5&panorama=1'.format(I,format,G,O);J=D._get_sth(P,AF).json();C={}
  1278. if J[M]==0:
  1279. try:H=J[E][Cm].get(CF);G=H[Cn][0][AX][0][Bc][0]
  1280. except:return C
  1281. Q=A(G['base_url']);R=A(G[K][0]['host']);S=A(G[K][0]['extra']);H=R+Q+S;C[b]=H;C[CJ]=B
  1282. if'.flv'in H:C[CJ]='video/x-flv'
  1283. else:return C
  1284. C[B2]=L;C[CI]={Cv:'https://live.bilibili.com',AP:D.header[AP]};return C
  1285. def _testUrl(A,url,id,mediaType):
  1286. B=head(url,headers=A.header,timeout=5).status_code
  1287. if B!=200:A.pC_urlDic[id][mediaType].pop(url)
  1288. def get_fastesUrl(C,ja,id,mediaType):
  1289. E=mediaType;A=ja;D=A
  1290. if Aa(A)==d:C.pC_urlDic[id][E]=D=[A.get('baseUrl',A.get(b,B))];D.extend(A.get('backup_url',[]));C.pC_urlDic[id][Bf]=F(d(J(lambda x:x.split('=')[:2],D[0].split('?')[1].split('&'))).get(Bf,0))
  1291. for G in D:C.pool.submit(C._testUrl,G,id,E)
  1292. def localProxy(D,param):
  1293. N='range';M='application/octet-stream';E=param;A=E.get(k)
  1294. if A==Cs:O=D.down_sub(E[b]);return[200,M,O]
  1295. F=E.get(T);G=E.get(v);H=E.get(AY);C=D.pC_urlDic[f"{F}_{G}"]
  1296. if A=='dash':P=D.get_dash(C[CH],F,G,H);return[200,Cu,P]
  1297. if A in[Be,p,AZ]:
  1298. if A==Be:A=H
  1299. K=AK(X.time());I=C.get(Bf)
  1300. if Aa(C[A])==d or(I-K)%10==0:D.get_fastesUrl(C[A],f"{F}_{G}",A);I=C.get(Bf)
  1301. J=B8.choice(C[A])
  1302. if not J or A!=AZ and I-K<1800:
  1303. D._get_playerContent({},F,G,C[o]);C=D.pC_urlDic[f"{F}_{G}"]
  1304. if A==p:D.get_dash(C[CH],F,G,H)
  1305. D.get_fastesUrl(C[A],f"{F}_{G}",A);J=B8.choice(C[A])
  1306. L=D.header.copy()
  1307. if N in E:L['Range']=E[N]
  1308. Q=D.fetch(J,headers=L,stream=Ab);return[206,M,Q.content]
  1309. return[404,'text/plain',B]
  1310. config={'player':{},l:{BE:[{W:C5,H:'分类',K:[{D:B0,C:B0},{D:BT,C:BT},{D:C0,C:C0},{D:B1,C:B1},{D:C1,C:C1},{D:'我的粉丝',C:'我的粉丝'}]}],AN:[{W:q,H:'别人投稿排序',K:[{D:'最新发布',C:Ay},{D:'最多播放',C:'click'},{D:'最多收藏',C:'stow'},{D:'最早发布',C:CZ},{D:'合集和列表',C:Ca}]}],Ac:[{W:A1,H:'分类',K:[{D:'番剧',C:V},{D:'国创',C:AQ},{D:'电影',C:A0},{D:'电视剧',C:'5'},{D:'纪录片',C:AL},{D:'综艺',C:'7'}]},{W:q,H:'排序',K:[{D:A3,C:A3},{D:'播放数量',C:A0},{D:'更新时间',C:L},{D:'最高评分',C:AQ},{D:'弹幕数量',C:V},{D:'追看人数',C:AL},{D:'开播时间',C:'5'},{D:'上映时间',C:'6'}]},{W:C4,H:'付费',K:[{D:'全部',C:'-1'},{D:'免费',C:V},{D:'付费',C:'2%2C6'},{D:'大会员',C:'4%2C6'}]}],Ae:[{W:q,H:'排序',K:[{D:'收藏时间',C:'mtime'},{D:'播放量',C:BN},{D:'投稿时间',C:'pubtime'}]}],BF:[{W:k,H:'分类',K:[{D:'视频',C:BK},{D:Ad,C:AG},{D:BJ,C:BJ},{D:BQ,C:BQ}]}],Aq:[{W:k,H:'类型',K:[{D:'视频',C:p},{D:'番剧',C:Co},{D:Ac,C:Cp},{D:Ad,C:AG},{D:'用户',C:C7}]},{W:q,H:'视频排序',K:[{D:'综合排序',C:Ch},{D:'最多点击',C:'click'},{D:'最新发布',C:Ay},{D:'最多收藏',C:'stow'},{D:'最多弹幕',C:'dm'}]},{W:n,H:'视频时长',K:[{D:'全部',C:L},{D:'60分钟以上',C:AQ},{D:'30~60分钟',C:AL},{D:'5~30分钟',C:A0},{D:'5分钟以下',C:V}]}]}};header={'Origin':'https://www.bilibili.com',Cv:'https://space.bilibili.com',AP:'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0'}