py_bilimy.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. # coding=utf-8
  2. # !/usr/bin/python
  3. import sys
  4. sys.path.append('..')
  5. from base.spider import Spider
  6. import json
  7. import threading
  8. class Spider(Spider):
  9. box_video_type = ''
  10. def getDependence(self):
  11. return ['py_bilibili']
  12. def getName(self):
  13. return "我的哔哩"
  14. def init(self, extend=""):
  15. self.bilibili = extend[0]
  16. print("============{0}============".format(extend))
  17. pass
  18. def isVideoFormat(self, url):
  19. pass
  20. def manualVideoCheck(self):
  21. pass
  22. def homeContent(self, filter):
  23. result = {}
  24. cateManual = {
  25. "动态": "动态",
  26. "UP": "UP",
  27. "关注": "关注",
  28. "追番": "追番",
  29. "追剧": "追剧",
  30. "收藏": "收藏",
  31. "历史记录": "历史记录",
  32. # ————————以下可自定义UP主,冒号后须填写UID————————
  33. #"虫哥说电影": "29296192",
  34. # ————————以下可自定义关键词,结果以搜索方式展示————————
  35. "周杰伦": "周杰伦",
  36. #"狗狗": "汪星人",
  37. #"猫咪": "喵星人",
  38. }
  39. classes = []
  40. for k in cateManual:
  41. classes.append({
  42. 'type_name': k,
  43. 'type_id': cateManual[k]
  44. })
  45. result['class'] = classes
  46. if (filter):
  47. filters = {}
  48. for lk in cateManual:
  49. if lk in self.bilibili.config['filter']:
  50. filters.update({
  51. cateManual[lk]: self.bilibili.config['filter'][lk]
  52. })
  53. elif not cateManual[lk].isdigit():
  54. link = cateManual[lk]
  55. filters.update({
  56. link: [{"key": "order", "name": "排序",
  57. "value": [{"n": "综合排序", "v": "totalrank"}, {"n": "最新发布", "v": "pubdate"},
  58. {"n": "最多点击", "v": "click"}, {"n": "最多收藏", "v": "stow"},
  59. {"n": "最多弹幕", "v": "dm"}, ]},
  60. {"key": "duration", "name": "时长",
  61. "value": [{"n": "全部", "v": "0"}, {"n": "60分钟以上", "v": "4"},
  62. {"n": "30~60分钟", "v": "3"}, {"n": "5~30分钟", "v": "2"},
  63. {"n": "5分钟以下", "v": "1"}]}]
  64. })
  65. result['filters'] = filters
  66. return result
  67. # 用户cookies,请在py_bilibili里填写,此处不用改
  68. cookies = ''
  69. userid = ''
  70. def getCookie(self):
  71. self.cookies = self.bilibili.getCookie()
  72. self.userid = self.bilibili.userid
  73. return self.cookies
  74. def homeVideoContent(self):
  75. result = {}
  76. videos = self.bilibili.get_dynamic(1)['list'][0:3]
  77. result['list'] = videos
  78. return result
  79. def get_follow(self, pg, order):
  80. if len(self.cookies) <= 0:
  81. self.getCookie()
  82. result = {}
  83. ps = 10
  84. url = 'https://api.bilibili.com/x/relation/followings?vmid={0}&order=desc&order_type={3}&ps={1}&pn={2}'.format(self.userid, ps, pg, order)
  85. rsp = self.fetch(url, headers=self.header, cookies=self.cookies)
  86. content = rsp.text
  87. jo = json.loads(content)
  88. follow = []
  89. for f in jo['data']['list']:
  90. mid = f['mid']
  91. title = str(f['uname']).strip()
  92. img = str(f['face']).strip()
  93. remark = ''
  94. if f['special'] == 1:
  95. remark = '特别关注'
  96. follow.append({
  97. "vod_id": str(mid) + '_mid',
  98. "vod_name": title,
  99. "vod_pic": img + '@672w_378h_1c.jpg',
  100. "vod_remarks": remark
  101. })
  102. total = jo['data']['total']
  103. pc = divmod(total, ps)
  104. if pc[1] != 0:
  105. pc = pc[0] + 1
  106. else:
  107. pc = pc[0]
  108. result['list'] = follow
  109. result['page'] = pg
  110. result['pagecount'] = pc
  111. result['limit'] = 2
  112. result['total'] = 999999
  113. return result
  114. def get_up_archive(self, pg, order):
  115. mid = self.bilibili.up_mid
  116. if mid.isdigit():
  117. return self.get_up_videos(mid, pg, order)
  118. else:
  119. return {}
  120. get_up_videos_mid = ''
  121. get_up_videos_pc = 1
  122. def get_up_videos(self, mid, pg, order):
  123. result = {}
  124. ps = 10
  125. order2 = ''
  126. if order == 'oldest':
  127. order2 = order
  128. order = 'pubdate'
  129. if order2 and int(pg) == 1:
  130. url = 'https://api.bilibili.com/x/space/arc/search?mid={0}&pn={1}&ps={2}&order={3}'.format(mid, pg, ps, order)
  131. rsp = self.fetch(url, headers=self.header, cookies=self.cookies)
  132. content = rsp.text
  133. jo = json.loads(content)
  134. if jo['code'] == 0:
  135. total = jo['data']['page']['count']
  136. pc = divmod(total, ps)
  137. if pc[1] != 0:
  138. pc = pc[0] + 1
  139. else:
  140. pc = pc[0]
  141. self.get_up_videos_mid = mid
  142. self.get_up_videos_pc = pc
  143. tmp_pg = pg
  144. if order2:
  145. tmp_pg = self.get_up_videos_pc - int(pg) + 1
  146. url = 'https://api.bilibili.com/x/space/arc/search?mid={0}&pn={1}&ps={2}&order={3}'.format(mid, tmp_pg, ps, order)
  147. rsp = self.fetch(url, headers=self.header, cookies=self.cookies)
  148. content = rsp.text
  149. jo = json.loads(content)
  150. if jo['code'] == 0:
  151. videos = []
  152. vodList = jo['data']['list']['vlist']
  153. for vod in vodList:
  154. aid = str(vod['aid']).strip()
  155. title = vod['title'].strip().replace("<em class=\"keyword\">", "").replace("</em>", "")
  156. img = vod['pic'].strip()
  157. remark = "观看:" + self.bilibili.zh(vod['play']) + "  " + str(vod['length']).strip()
  158. videos.append({
  159. "vod_id": aid,
  160. "vod_name": title,
  161. "vod_pic": img + '@672w_378h_1c.jpg',
  162. "vod_remarks": remark
  163. })
  164. if order2:
  165. videos.reverse()
  166. if int(pg) == 1:
  167. info = {}
  168. self.bilibili.get_up_info(mid, info)
  169. gotoUPHome={
  170. "vod_id": str(mid) + '_mid',
  171. "vod_name": info['name'] + " 个人主页",
  172. "vod_pic": info['face'] + '@672w_378h_1c.jpg',
  173. "vod_remarks": info['following'] + ' 投稿:' + str(info['vod_count'])
  174. }
  175. videos.insert(0, gotoUPHome)
  176. pc = self.get_up_videos_pc
  177. if self.get_up_videos_mid != mid:
  178. total = jo['data']['page']['count']
  179. pc = divmod(total, ps)
  180. if pc[1] != 0:
  181. pc = pc[0] + 1
  182. else:
  183. pc = pc[0]
  184. self.get_up_videos_mid = mid
  185. self.get_up_videos_pc = pc
  186. result['list'] = videos
  187. result['page'] = pg
  188. result['pagecount'] = pc
  189. result['limit'] = 2
  190. result['total'] = 999999
  191. return result
  192. def get_zhui(self, pg, mode):
  193. result = {}
  194. if len(self.cookies) <= 0:
  195. self.getCookie()
  196. url = 'https://api.bilibili.com/x/space/bangumi/follow/list?type={2}&pn={1}&ps=10&vmid={0}'.format(self.userid, pg, mode)
  197. rsp = self.fetch(url, headers=self.header, cookies=self.cookies)
  198. content = rsp.text
  199. jo = json.loads(content)
  200. videos = []
  201. vodList = jo['data']['list']
  202. for vod in vodList:
  203. aid = str(vod['season_id']).strip()
  204. title = vod['title']
  205. img = vod['cover'].strip()
  206. remark = ''
  207. if 'index_show' in vod['new_ep']:
  208. remark = vod['new_ep']['index_show']
  209. videos.append({
  210. "vod_id": 'ss' + aid,
  211. "vod_name": title,
  212. "vod_pic": img + '@672w_378h_1c.jpg',
  213. "vod_remarks": remark
  214. })
  215. result['list'] = videos
  216. result['page'] = pg
  217. result['pagecount'] = 9999
  218. result['limit'] = 2
  219. result['total'] = 999999
  220. return result
  221. def categoryContent(self, tid, pg, filter, extend):
  222. if tid.isdigit():
  223. order = 'pubdate'
  224. if 'order' in extend:
  225. order = extend['order']
  226. return self.get_up_videos(tid, pg, order)
  227. elif tid == "关注":
  228. order = 'attention'
  229. if 'order' in extend:
  230. order = extend['order']
  231. return self.get_follow(pg, order)
  232. elif tid == "UP":
  233. order = 'pubdate'
  234. if 'order' in extend:
  235. order = extend['order']
  236. return self.get_up_archive(pg, order)
  237. elif tid == "追番":
  238. return self.get_zhui(pg, 1)
  239. elif tid == "追剧":
  240. return self.get_zhui(pg, 2)
  241. else:
  242. result = self.bilibili.categoryContent(tid, pg, filter, extend)
  243. return result
  244. def cleanSpace(self, str):
  245. return str.replace('\n', '').replace('\t', '').replace('\r', '').replace(' ', '')
  246. con = threading.Condition()
  247. def get_up_vod(self, mid, n, nList, urlList):
  248. # 获取UP主视频列表
  249. url = 'https://api.bilibili.com/x/space/arc/search?mid={0}&ps=50&pn={1}'.format(mid, n)
  250. try:
  251. rsp = self.fetch(url, headers=self.header, cookies=self.cookies)
  252. content = rsp.text
  253. except:
  254. with self.con:
  255. nList.remove(n)
  256. self.con.notifyAll()
  257. return
  258. jRoot = json.loads(content)
  259. jo = jRoot['data']['list']['vlist']
  260. if len(jo) == 0:
  261. with self.con:
  262. nList.remove(n)
  263. self.con.notifyAll()
  264. return
  265. playUrl = ''
  266. vodItems = []
  267. for tmpJo in jo:
  268. aid = tmpJo['aid']
  269. part = tmpJo['title'].replace("#", "-")
  270. url = '{0}${1}_cid'.format(part, aid)
  271. vodItems.append(url)
  272. playUrl = '#'.join(vodItems)
  273. with self.con:
  274. while True:
  275. if n == nList[0]:
  276. urlList.append(playUrl)
  277. nList.remove(n)
  278. self.con.notifyAll()
  279. break
  280. else:
  281. self.con.wait()
  282. def detailContent(self, array):
  283. if 'mid' in array[0]:
  284. arrays = array[0].split("_")
  285. mid = arrays[0]
  286. self.bilibili.up_mid = mid
  287. info = {}
  288. i = threading.Thread(target=self.bilibili.get_up_info, args=(mid, info, ))
  289. i.start()
  290. #最多获取最近2页的投稿
  291. pn = 3
  292. urlList = []
  293. #nList = []
  294. #for n in range(pn):
  295. # n += 1
  296. # nList.append(n)
  297. # with self.con:
  298. # if threading.active_count() > 10:
  299. # self.con.wait()
  300. # t = threading.Thread(target=self.get_up_vod, args=(mid, n, nList, urlList, ))
  301. # t.start()
  302. while True:
  303. _count = threading.active_count()
  304. #计算线程数,不出结果就调大,结果少了就调小
  305. if _count <= 2:
  306. break
  307. vod = {
  308. "vod_id": mid,
  309. "vod_name": info['name'] + " 个人主页",
  310. "vod_pic": info['face'],
  311. "vod_area": "bilidanmu",
  312. "vod_remarks": "", # 不会显示
  313. "vod_tags": 'mv', # 不会显示
  314. "vod_actor": "粉丝数:" + info['fans'] + " 投稿数:" + info['vod_count'] + " 点赞数:" +info['like_num'],
  315. "vod_director": info['name'] + ' UID:' +str(mid) + " " + info['following'],
  316. "vod_content": info['desc'],
  317. 'vod_play_from': '更多视频在我的哔哩——UP标签,按上键刷新查看'
  318. }
  319. first = '点击相应按钮可以关注/取关$' + str(mid) + '_mid'
  320. follow = '关注$' + str(mid) + '_1_mid_follow'
  321. unfollow = '取消关注$' + str(mid) + '_2_mid_follow'
  322. doWhat = [first, follow, unfollow]
  323. urlList = doWhat + urlList
  324. vod['vod_play_url'] = '#'.join(urlList)
  325. result = {
  326. 'list': [
  327. vod
  328. ]
  329. }
  330. return result
  331. else:
  332. return self.bilibili.detailContent(array)
  333. def searchContent(self, key, quick):
  334. if len(self.cookies) <= 0:
  335. self.getCookie()
  336. url = 'https://api.bilibili.com/x/web-interface/search/type?search_type=bili_user&keyword={0}'.format(key)
  337. rsp = self.fetch(url, headers=self.header, cookies=self.cookies)
  338. content = rsp.text
  339. jo = json.loads(content)
  340. videos = []
  341. vodList = jo['data']['result']
  342. for vod in vodList:
  343. mid = str(vod['mid'])
  344. title = "UP主:" + vod['uname'].strip() + " ☜" + key
  345. img = 'https:' + vod['upic'].strip()
  346. remark = "粉丝数" + self.bilibili.zh(vod['fans'])
  347. videos.append({
  348. "vod_id": mid + '_mid',
  349. "vod_name": title,
  350. "vod_pic": img + '@672w_378h_1c.jpg',
  351. "vod_remarks": remark
  352. })
  353. result = {
  354. 'list': videos
  355. }
  356. return result
  357. def playerContent(self, flag, id, vipFlags):
  358. return self.bilibili.playerContent(flag, id, vipFlags)
  359. config = {
  360. "player": {},
  361. "filter": {
  362. }
  363. }
  364. header = {
  365. "Referer": "https://www.bilibili.com",
  366. "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
  367. }
  368. def localProxy(self, param):
  369. return [200, "video/MP2T", action, ""]