正文
作者:ieiayaobb
来源:https://segmentfault.com/a/1190000010348905
前言
作为一个炉石传说玩家,经常有事没事开着直播网站看看大神们的精彩表演。不过因为各个平台互相挖人的关系,导致关注的一些主播分散到了各个直播平台,来回切换有点麻烦,所以萌生了做一个视频聚合站的想法。
我主要去采集斗鱼、熊猫等的炉石区的主播信息。虽然各个站点的人气信息有水分,但还是做了个简单的排名。
上图:
手机上的效果图:
话不多说,上网站: http://lushiba.leanapp.cn/
项目部输在了 leancloud 上,比较省心,但有一定的免费额度(如果显示超出限制,需要晚一些来访问,毕竟免费的,每天 6 个小时限制)
源码地址: https://github.com/ieiayaobb/... 欢迎 Star
基础介绍
聚合站的思路就是采集目标站点的相关信息,通过数据处理将想要的信息做提取,整理入库,然后通过 web 展示。因为直播平台数据实时在变,所以考虑将存储的数据放在缓存中(redis),因为部署在了 lean cloud 上,所以示例就直接存储在了 lean cloud 的存储上。
为了方便讲解,我们以斗鱼为目标采集的网站,介绍解析和存储部分的内容,其他网站的处理大同小异。
功能说明
整体项目就分为数据采集解析、数据存储、web 展现三大功能。后续我们会对这三个部分的功能做逐一展开说明。
技术选型
轻量级的项目,直接就是用了 Python 来做,Python 在爬虫、web 方面都有着不错的库支持,而且 lean cloud 也支持 Python 部署,所以毫不犹豫的就采用了 Python 来做
requests 的特点就是轻量,且简单易用。虽然这是个爬虫项目,但实在规模太小,所以没必要上 scrapy 了
requests 的介绍地址:http://docs.python-requests.o...
请求模拟
url = 'http://www.douyu.com/directory/game/How'
session = requests.Session()
response = session.get(url, verify=False)
数据解析
解析部分主要有两种:正则,BeautifulSoup
这里为了通用,直接使用了正则来解析。
正则处理要求比较高,但是几乎能应对所有的情况,属于大杀器。
BeautifulSoup4 的详细介绍: https://www.crummy.com/softwa...
Django 是 Python 比较重量级的框架,Django 自带了 orm 的框架,可惜这个项目中用不到。但是我们会使用 Django 的模板引擎,Django 的模板引擎也是很方便的一个特性。Django 还提供了 django-rest-framework,方便开发 RESTful 的接口,这个项目后续做了个配搭的 React Native 的 mobile 应用,所以引入了 django-rest-framework。
详细介绍在此:https://www.djangoproject.com/
既然用了 lean cloud,存储就直接用了 lean 提供的存储功能。
详细的介绍在这里: https://leancloud.cn/docs/lea...
参考了 lean cloud 官方的项目骨架: https://github.com/leancloud/...
pureCss 还是为了简单,支持响应式,并且提供了基础的 UI 组件
详细介绍在这里: https://purecss.io/
环境准备
Python 的开发环境网上比较多,主要是 virtualenv 的准备,可以看廖老师的博客了解具体信息:
https://www.liaoxuefeng.com/w...
requirments.txt 内容如下:
Django==1.9.7
requests==2.10.0
wheel==0.24.0
gunicorn
leancloud-sdk>=1.0.9
分析与采集
视频站内容解析
页面内容(单个主播的信息)
class="play-list-link" data-rid='48699' data-tid='2' data-sid='167' data-rpos="0" data-sub_rt
="0" href="/yechui" title="衣锦夜行:狂野 登顶登顶"
target="_blank">
class="imgbox">
class="imgbox-corner-mark">
class="black">
![](http://img2.jintiankansha.me/get6?src=http://upload-images.jianshu.io/upload_images/2485846-20d3cbfd6e33df69.gif?imageMogr2/auto-orient/strip)
class="mes">
class="mes-tit">
class="ellipsis">衣锦夜行:狂野 登顶登顶
class="tag ellipsis">炉石传说
class
=
"dy-name ellipsis fl"
>
衣锦夜行
class
=
"dy-num fr"
>
8.1 万
我们需要采集的有几部分内容:
-
直播间 url (节点里的 href,/yechui)
-
直播间的标题(节点里的 title,衣锦夜行:狂野 登顶登顶)
-
直播间的截图(节点里的 img 标签的 src,https://rpic.douyucdn.cn/a170...)
-
直播间的人气(8.1 万)(这里有个注意的地方,斗鱼的人气可能是 X 万,需要把这个万转化成数值方便排序)
-
主播名称(衣锦夜行)
页面处理与采集
所有完整的直播站处理代码在 fetch.py 中
命中主播信息节点
re.finditer('([sS]*?)', response.content.decode('utf8')):
简单的说明一下代码:
response.content.decode('utf8')
解析代码
采集 href 信息(主播房间链接)
href = re.search('href=".*?"', group).group().lstrip('href="').rstrip('"')
采集标题信息
title = re.search('title=".*?"', group).group().lstrip('title="').rstrip('"')
采集截图信息
img = re.search('data-original=".*?"', group).group().lstrip('data-original="').rstrip('"')
采集主播名称
name = re.search('.*?', group).group().lstrip('').rstrip('')
采集人气数量信息
num = re.search(
', group).group().lstrip('').rstrip('')
处理'万'字
int(round(float(num.replace('万', '').replace('r', '').replace('n', '')) * 10000))
存储与刷新
采集到的信息需要存储到 lean cloud 的存储中,会调用 lean cloud 所提供的 API
字段设计
Chairman
-
id
直播间的唯一 id
-
name
直播间主播名称
-
title
直播间的标题
-
href
直播间的页面地址
-
num
直播间的人气
-
img
直播间的截图
接口设计
/fetch
Fetch 的接口包含了清空、采集、解析、存储所有的更新逻辑,设计这个接口的目的主要是方便后面使用云函数进行定时调用,以更新数据,调用逻辑如下(lean cloud 不支持全部遍历,所以用了 while 循环来遍历所有,先清空,再采集):
leancloud.init(LEAN_CLOUD_ID, LEAN_CLOUD_SECRET)
query = leancloud.Query('Chairman')
allDataCompleted = False
batch = 0
limit = 1000
while not allDataCompleted:
query.limit(limit)
query.skip(batch * limit)
query.add_ascending('createdAt')
resultList = query.find()
if len(resultList) < limit:
allDataCompleted = True
leancloud.Object.destroy_all(resultList)
batch
= 1
fetcher = Fetcher()
fetcher.fetch_douyu()
/chairmans(redis 版本才支持)
Django-rest-framework 提供,可以通过分页的方式展现当前库中的信息
/chairman/{id}(redis 版本才支持)
Django-rest-framework 提供,可以根据指定 id 获取某一个主播的信息
刷新机制
lean cloud 提供了一种云函数的概念,并且可以像配置 cron 一样,定期的去触发某一个请求,为了能够定期的更新排行榜,我们会通过配置这个云函数,实现定期的数据刷新
云函数是一个 cloud.py 文件,内容如下
engine = Engine(get_wsgi_application())
@engine.define
def fetch(**params):
leancloud.init(LEAN_CLOUD_ID, LEAN_CLOUD_SECRET)
# fetch 逻辑
在 lean cloud 中配置定时执行
页面展示
页面部分比较简单,以一个列表的形式,展现了主播的排行榜信息,点击某一个主播,直接跳转到对应直播网站的目标直播间。因为考虑到在手机上的显示,所以做了自适应
列表页
列表页的渲染使用了 Django 的模板引擎
由于 lean cloud 的存储和 Django 的 orm 不一样,所以这里需要将 attributes 放到列表中,页面上才能用模板语法进行访问
view 部分代码:
def get_index(request):
leancloud.init(LEAN_CLOUD_ID, LEAN_CLOUD_SECRET)
query =