基于python对B站收藏夹按照视频发布时间进行排序

前言

在最一开始,我的B站收藏一直是存放在默认收藏夹中,但是随着视频收藏的越来越多,没有分类的视频放在一起,想在众多视频中找到想要的视频非常困难,因此就对收藏夹里面的视频进行了分类。但是分类之后紧接着又出现了一个新的问题:原来存放在默认收藏夹里面视频的相对顺序被打乱了——明明前几天刚收藏的视频却要翻很多很多页才能找到,因此有了这个程序。

程序的作用

因为我们看到的视频大部分都是通过推荐得到的,而推荐的视频大部分都是刚发布不久,因此大部分收藏的视频的顺序也基本是按照视频发布的顺序来的。那么通过程序对收藏夹中的视频按照发布时间重新排序,那么就和我们收藏视频的顺序几乎一致了。

机理

利用b站的API获取收藏夹中视频的视频的编号,用python中的request库获得视频对应网页的html,之后利用正则表达式得到视频发布的时间。将发布时间和视频的编号绑定,按照视频发布时间从小到大排序,再次利用b站的API将视频收藏到指定收藏夹。

出现的问题

b站视频的av号在八位以下的时候是按照视频发布顺序编排的,但是当到达九位的时候就不是按照发布顺序编排的了,因此只能通过访问视频主页来得到视频发布时间。

b站的API如果长时间比较高频率的访问会出现错误码,因此每次调用API之后都sleep了一下。

中间程序可能因为各种原因挂掉,因此在中间加入了储存中间状态的功能,否则每次挂掉都要重新爬速度非常慢。

使用方法

在创建Sort类对象时,将userAgent,cookie,fid,toFid,csrf传入类的构造函数中,之后调用类中的sortVideos()方法即可完成排序。

  1. import requests, json, time, re, datetime, random
  2. class WriteLog(object):
  3. def __getCurrentTime(self):
  4. return str(time.ctime(time.time()))
  5. def writeFile(self, fileName, l):
  6. with open(self.__getCurrentTime() + fileName, 'w') as f:
  7. for i in l:
  8. f.write(str(i) + '\n')
  9. class Sort(WriteLog):
  10. def __init__(self, fid, toFid, csrf, userAgent, cookie, MinSleepTime=5, MaxSleepTime=10):
  11. self.MinSleepTime = MinSleepTime
  12. self.MaxSleepTime = MaxSleepTime
  13. self.fid = str(fid)
  14. self.toFid = str(toFid)
  15. self.csrf = csrf
  16. self.DeadVideo = []
  17. self.headers = {'User-Agent': userAgent, 'cookie': cookie}
  18. def __Sleep(self):
  19. sleepTime = random.randint(self.MinSleepTime, self.MaxSleepTime)
  20. time.sleep(sleepTime)
  21. def __getAllVideoId(self):
  22. print('Start get all video ID')
  23. fid = self.fid
  24. res = []
  25. cnt = 0
  26. for i in range(100):
  27. if i == 0:
  28. continue
  29. url = 'https://api.bilibili.com/x/v3/fav/resource/list?media_id=' + fid + '&pn=' + str(i) + '&ps=20&keyword=&order=mtime&type=0&tid=0&platform=web&jsonp=jsonp'
  30. html = requests.get(url=url, headers=self.headers)
  31. te = json.loads(html.text)
  32. te = te['data']['medias']
  33. if te != None:
  34. for j in te:
  35. res.append(j['id'])
  36. print('num: ', cnt, '\tvideoID: ', j['id'])
  37. cnt = cnt + 1
  38. self.__Sleep()
  39. else:
  40. break
  41. print('Finish get all video ID, in total %d' % (len(res)))
  42. return res
  43. def __addVideoToFavorite(self, vid):
  44. fid = self.toFid
  45. csrf = self.csrf
  46. url = 'https://api.bilibili.com/x/v3/fav/resource/deal'
  47. data = {
  48. 'rid': vid,
  49. 'type': '2',
  50. 'add_media_ids': fid,
  51. 'del_media_ids': '',
  52. 'jsonp': 'jsonp',
  53. 'csrf': csrf,
  54. 'platform': 'web',
  55. }
  56. requests.post(url=url, data=data, headers=self.headers)
  57. print('finish add video %s to folder %s' % (vid, fid))
  58. def __getVideoPostTime(self, vid):
  59. vid = str(vid)
  60. url = 'https://www.bilibili.com/video/av' + vid
  61. text = requests.get(url).text
  62. '''
  63. data-vue-meta="true" itemprop="uploadDate" content="2021-04-07 23:29:21"><meta data-vue-meta="true" itemprop="datePublished" c
  64. '''
  65. reg = re.compile('content="([0-9]+)-([0-9]+)-([0-9]+)\s([0-9]+):([0-9]+):([0-9]+)"')
  66. text = reg.findall(text)
  67. if len(text) == 0:
  68. return -1
  69. text = text[0]
  70. if len(text) < 6:
  71. return -1
  72. t = ""
  73. for i in text:
  74. t = t + str(i)
  75. print('finish get video %s post time, it\'s post time is: %s' % (vid, t))
  76. return int(t)
  77. def __Unique(self, l):
  78. size = len(l)
  79. if size == 0:
  80. return []
  81. res = [l[0]]
  82. for i in range(size):
  83. if i == 0:
  84. continue
  85. if l[i] != l[i - 1]:
  86. res.append(l[i])
  87. return res
  88. def __addVideo(self, res):
  89. cnt = 0
  90. for i in res:
  91. self.__addVideoToFavorite(vid=i)
  92. self.__Sleep()
  93. cnt = cnt + 1
  94. def __getVideosTime(self, res):
  95. videos = []
  96. cnt = 0
  97. for i in res:
  98. t = self.__getVideoPostTime(i)
  99. if t == -1:
  100. continue
  101. item = {
  102. 'vid': str(i),
  103. 'postTime': t
  104. }
  105. videos.append(item)
  106. cnt = cnt + 1
  107. return videos
  108. def sortVideos(self):
  109. fid = self.fid
  110. toFid = self.toFid
  111. res = self.__getAllVideoId()
  112. self.writeFile('getAllVideoId' + fid + 'to' + toFid, res)
  113. videos = self.__getVideosTime(res)
  114. videos = sorted(videos, key=lambda x: x['postTime'])
  115. res = []
  116. for i in videos:
  117. res.append(i['vid'])
  118. res = self.__Unique(res)
  119. self.writeFile('getVideosTime' + fid + 'to' + toFid, res)
  120. self.__addVideo(res)
  121. self.writeFile('err' + fid + 'to' + toFid, self.DeadVideo)
  122. if __name__=='__main__':
  123. userAgent = ''
  124. cookie = ''
  125. fid = ''
  126. toFid = ''
  127. csrf = ''
  128. sortVideo = Sort(fid=fid, toFid=toFid, csrf=csrf, userAgent=userAgent, cookie=cookie)
  129. sortVideo.sortVideos()

鸣谢

在此特别感谢ZLQ在本人书写此程序时提供的技术支持,大佬的博客:ZlycerQan.

基于python对B站收藏夹按照视频发布时间进行排序的更多相关文章

  1. Python网络爬虫实战(五)批量下载B站收藏夹视频

    我们除了爬取文本信息,有的时候还需要爬媒体信息,比如视频图片音乐等.就拿B站来说,我的收藏夹内的视频可能随时会失效,所以把它们下载到本地是非常保险的一件事. 对于这种大量列表型的数据,可以猜测B站收藏 ...

  2. 基于Python——实现解压文件夹中的.zip文件

    [背景]当一个文件夹里存好好多.zip文件需要解压时,手动一个个解压再给文件重命名是一件很麻烦的事情,基于此,今天介绍一种使用python实现批量解压文件夹中的压缩文件并给文件重命名的方法—— [代码 ...

  3. 基于Python——实现两个文件夹中的文件拷贝

    [背景]当复制一个文件夹中的某文件到另一个文件夹中时是一件很容易的事情,可是如果存在很多文件夹中的文件需要一一拷贝,就会变的很繁琐,稍有不慎就会遗漏,今天就用Python来解决这个问题—— [代码实现 ...

  4. 基于 python imageai 对象检测 目标检测 识别 视频

    1.视频连接如下: http://www.iqiyi.com/w_19s6vownit.html

  5. python基础课程_学习笔记13:标准库:有些收藏夹——sys

    标准库:有些收藏夹 sys sys这个模块可以让你访问和python解释器联系紧密的变量和函数. sys模块中一些重要的函数和变量 函数/变量 描写叙述 argv 命令行參数,包含脚本名称 exit( ...

  6. 基于Metronic的Bootstrap开发框架经验总结(13)--页面链接收藏夹功能的实现2(利用Sortable进行拖动排序)

    在上篇随笔<基于Metronic的Bootstrap开发框架经验总结(12)--页面链接收藏夹功能的实现>上,我介绍了链接收藏夹功能的实现,以及对收藏记录的排序处理.该篇随笔主要使用功能按 ...

  7. 基于Metronic的Bootstrap开发框架经验总结(12)--页面链接收藏夹功能的实现

    在一个系统里面,往往有很多菜单项目,每个菜单项对应一个页面,一般用户只需要用到一些常用的功能,如果每次都需要去各个层次的菜单里面去找对应的功能,那确实有点繁琐.特别是在菜单繁多,而客户又对系统整体不熟 ...

  8. 【Python】iiblogs ——命令行下的网页收藏夹

    昨天和集训队的几位大大聊天,聊着聊着就聊到了博客的问题,发现几个人要么在CSDN 要么在博客园上, 要记住他们的所有的地址还真是不便,于是灵机一动,何不自己写一款小工具来存储打开他们的博客呢?于是将这 ...

  9. python基础课程_学习笔记15:标准库:有些收藏夹——fileinput

    标准库:有些收藏夹 fileinput 重要功能 性能 叙述性说明 input([files[,inplace[,backup]]) 便于遍历多个输入流中的行 filename() 返回当前文件的名称 ...

随机推荐

  1. apk、dex完整性验证

    对Dex进行完整性的检查,可通过CRC,或者Hash值.可将校验值放到String资源文件里,或者放到服务器中. 1. 在代码中完成校验值对比逻辑,此部分代码后续不能再改变,否则CRC值会发生变化: ...

  2. incubator-dolphinscheduler 如何在不写任何新代码的情况下,能快速接入到prometheus和grafana中进行监控

    一.prometheus和grafana 简介 prometheus是由谷歌研发的一款开源的监控软件,目前已经贡献给了apache 基金会托管. 监控通常分为白盒监控和黑盒监控之分. 白盒监控:通过监 ...

  3. JAVA面试核心知识点(一):计算机网络

    一·计算机网络 1.1 网络基础知识 OSI 七层协议(制定标准使用的标准概念框架): 物理层(传递比特流0101)->数据链路层(将比特流转换为逻辑传输线路)->网络层(逻辑编址,分组传 ...

  4. vue文本滚动组件

    看了好多网上的文本组件,发现好多都有这样那样的问题:特别是滚动的时候失真的感觉,今天整合了文本滚动的方式用CSS的 animation写出一套组件:VUE项目直接用.感觉有用的朋友关注下   效果图, ...

  5. Centos7安装maven详情以及配置

    一.maven安装: 1.获取maven下载地址: 查询maven最新版本地址:https://maven.apache.org/download.cgi 当前最新版本为maven 3.6.3    ...

  6. Spring Cloud 升级之路 - 2020.0.x - 1. 背景知识、需求描述与公共依赖

    1. 背景知识.需求描述与公共依赖 1.1. 背景知识 & 需求描述 Spring Cloud 官方文档说了,它是一个完整的微服务体系,用户可以通过使用 Spring Cloud 快速搭建一个 ...

  7. Shell prompt(PS1) 与 Carriage Return(CR) 的关系?-- Shell十三问<第二问>

    Shell prompt(PS1) 与 Carriage Return(CR) 的关系?-- Shell十三问<第二问> 当你成功登录进一个文字界面之后,大部份情形下,你会在荧幕上看到一个 ...

  8. [贪心]D. 【例题4】国王游戏

    D . [ 例 题 4 ] 国 王 游 戏 D. [例题4]国王游戏 D.[例题4]国王游戏 解析 贪心思想,考虑交换后的值比交换前的小. 然后数据规模用高精度 Code #include <b ...

  9. 免费开源的客服系统 Linux 服务器环境安装部署过程

    最近因为项目需要,要找一款在线客服系统集成在 APP 中使用,而且涉及到生意开单,客服系统必须稳定可靠.另外甲方要求,必须支持 Linux 服务器环境. 我们以 Ubuntu 18.04 为例把安装部 ...

  10. 【Git基本命令】

    [基本指令] git init :使目标文件夹变成一个仓库 git add <文件名,含后缀> : 告诉git我要添加文件了 git commit -m "<提交说明> ...