用Python列出哔哩哔哩up主剧集目录

專 欄

丁果,Python中文社区作者。对django、pyqt、opencv、tornado感兴趣。

GitHub:https://github.com/lidingke

特别喜欢看木鱼水心的解说,特别是木鱼微剧场系列。有点麻烦的是剧集都是离散的,为此写个爬虫把url爬下来,并根据标题按剧集分类,列出了一个目录。这样以后看起来就方便了,不用一页一页找了。

github仓库如下:

https://github.com/lidingke/muyushuixin

这篇文章主要讲三部分内容:

1、爬取内容并解析生成目录的流程。 2、用到的一些小tips。 3、哪部分处理的不好以及计划内的改进。

目标

列出目录并按剧集分类,按照观看人数排序。选择B站的原因是B站较少有视频失效的情况,而且B站的架构更流畅更适合爬虫爬取。

爬虫部分

爬虫的目标地址是blibili上的木鱼水心的空间,该空间的结构是分页式的,总共17页。

正常套路就是用字符串的format方法拼接出17个url,并用request获取,然后lxml+xpath解析出相应标签里的内容就行了,需要解析出的html元素就是标题和观看人数。

通过解析标题里的“《》”来解析出标题,通过“()”里的part来解析出序号。图中画红框就是需要解析出的内容。

明确了思路就开始写了,结果发现获取不到相应的信息,爬取到的网页会直接跳登陆页面。遇到这种情况我以为是要搞模拟登陆,结果配置好cookie后发现还是获取不到。

折腾了好久,发现原因是B站的空间内容是动态生成的。搞清楚这一点后,果断打开chrome的开发者的Network栏抓包,设置到XHR,最终找到了json地址,我们需要的内容在getSubmitVideos这一栏下,如下图所示。

后面的事就简单了,按照这个地址拼接成分页的url,request这些url得到到json数据,连lxml+xpath都不用。

虽然没用上xpath,这里还是提一下,用chrome可以自动生成xpath的匹配规则,在相应的html标签上右键->Copy->Copy Xpath就可以了。

总结一下就是静态网页用xpath或者BS,动态网页就是抓包找获取json的url。

解析部分

需要的value是获取到的json中的data-vlist-(title,play,aid),其中title就是标签,play是人气,aid是视频id,最后的aid是用来拼接单个视频url的。

小tips1,采用继承自collection的自定义类:

保存解析后的值用了一个自定义的类——Schedule,该类继承自MutableMapping,这是一个自定义字典。

将解析的代码块放入setitem方法,最后输出的的格式化代码放入str方法中。

这么做可以在节省大量代码的情况下保证程序的规范,一般我们需要让对象的表现更自然一些的话可以这么做。

小tips2,用元组做字典的键:

元组是一种可hash的数据结构,为了实现更细粒度的key,采用元组是一种较好的办法。

具体到这个自定义类中,应该改用剧集名+分剧序列号作为key,比如('人民的名义',1)这样的,并且这样的key也可以方便用起来时拆包。

不过有点不好的是,如果要搜索的时候就不好用in dict.keys()这样的方法了,得遍历keys。所以在getitem方法中选择返回符合剧集名的所有item的列表。

小tips3,排序时使用key和reverse属性:

程序中用到两次排序,其中一次是这样的,

show_list.sort(key=lambda x: x[1], reverse=True)

这里用一个lambda函数将元组的序列为1,也就是第二个值作为排序索引,同时用reverse逆了个序。

如果不用lambda,可以用operater模块中的itemgetter方法,不用reverse也可以用切片中的[::-1]逆序。

需要的改进

解析分剧集序列号这部分代码用的是字符串的find方法和正则模块,搭配大量的if-else,简直糟糕透了。这么做的原因也是分剧在标题中格式不统一,有按照P和Part来分的,有按照上中下来分的,还有Part加罗马数字分的。打算后面以状态机的方式写个正则来一劳永逸的解决这个问题。

用自定义的数据结果在解析和排序时也是挺绕的,打算后面按照数据库设计范式来改,不知道利用数据库范式的设计会不会有所改善。

原文发布于微信公众号 - Python中文社区(python-china)

原文发表时间:2017-09-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java成长之路

Java内存模型

多任务处理在现代计算机操作系统中几乎已经是一项必备的功能了。计算机cpu的运算速度与它的存储和通信子系统速度的差距太大,大量的时间都花费在磁盘I/O、网络通信或...

1691
来自专栏desperate633

浅谈servlet的生命周期servlet的生命周期详解servlet生命周期中三大重要的时刻

servlet从被加载到销毁经历了多个阶段,其中需要我们十分了解每个阶段的意义作用,才能更好地编写相关的servlet程序。

882
来自专栏章鱼的慢慢技术路

《算法图解》第五章笔记与课后练习_散列函数与散列表

1855
来自专栏腾讯Bugly的专栏

【团队分享】刀锋铁骑:常见Android Native崩溃及错误原因

王竞原,负责网游刀锋铁骑项目,高级开发工程师,使用C++已有10年,非常喜欢C++,特别是C++11。希望能与广大的C++爱好者多交流。 一、什么是Androi...

4863
来自专栏杨建荣的学习笔记

从sysbench中学习Lua

我做事喜欢结果导向,喜欢快速迭代,能10分钟搞定,绝对不愿意花15分钟。但是技术行当,还是得耐得住寂寞,因为很多事情10分钟搞不定,可能100分钟,100...

3035
来自专栏小曾

.Net高级进阶,教你如何构建企业模型数据拦截层,动态控制字段验证

如图:现在你要在控制器里面判断,账号名称、密码、邮箱不能为空,并且名称和密码不超过16位。

1181
来自专栏灯塔大数据

技术| Python的从零开始系列连载(三十)

为了解答大家学习Python时遇到各种常见问题,小灯塔特地整理了一系列从零开始的入门到熟练的系列连载,每周五准时推出,欢迎大家学积极学习转载~

912
来自专栏逍遥剑客的游戏开发

MPQ文件系统优化

1726
来自专栏web开发

JavaSript模块规范 - AMD规范与CMD规范介绍

JavaSript模块化     在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?     模块化是指在解决某一个复杂问题或者...

2396
来自专栏Golang语言社区

Golang使用pprof监控性能及GC调优

作者:峰云就她了 链接:http://xiaorui.cc/?p=3000 來源:个人博客

3733

扫码关注云+社区

领取腾讯云代金券