您的位置:首页 > 其它

如何写一只抓哔哩哔哩弹幕的爬虫

2018-03-05 10:30 471 查看
原文地址:http://blog.csdn.net/bigbigsman/article/details/78639053

如何写一只抓哔哩哔哩弹幕的爬虫

爬虫工作流程

解析首页获得视频cid
构造所有的获取弹幕链接
解析xml文件并插入数据库
遍历获取每一集的弹幕内容

1、解析首页获取每一集的cid和内容

访问静态页面,利用lxml解析视频cid和视频内容 
解析如下标记的内容: 


2、构造获取弹幕链接

构造得到弹幕的链接很简单,根据第一步得到的cid
http://comment.bilibili.com/{cid}.xml #cid 第一步获得的
1
根据cid构造url 访问获取弹幕,返回的是xml文件。 
如下: 


3、弹幕xml文件解析

获取的弹幕xml格式如下:
<d p="533.67199707031,1,25,41194,1498943949,0,7edeebe9,3511616609">刀还是没有枪快</d>
1
p这个字段里面的内容: 
0,1,25,16777215,1312863760,0,eff85771,42759017中几个逗号分割的数据 
第一个参数是弹幕出现的时间以秒数为单位。 
第二个参数是弹幕的模式1..3 滚动弹幕 4底端弹幕 5顶端弹幕 6.逆向弹幕 7精准定位 8高级弹幕 
第三个参数是字号, 12非常小,16特小,18小,25中,36大,45很大,64特别大 
第四个参数是字体的颜色以HTML颜色的十进制为准 
第五个参数是Unix格式的时间戳。基准时间为 1970-1-1 08:00:00 
第六个参数是弹幕池 0普通池 1字幕池 2特殊池【目前特殊池为高级弹幕专用】 
第七个参数是发送者的ID,用于“屏蔽此弹幕的发送者”功能 
第八个参数是弹幕在弹幕数据库中rowID 用于“历史弹幕”功能。

4、遍历获取每一集的弹幕

爬虫源码

#coding=utf-8
from lxml import etree
import requests, re, time
import datetime
import sys,sqlite3,os

#初始化数据库
if os.path.exists('bilbili.db'):
cx = sqlite3.connect('bilbili.db', check_same_thread = False)
else:
cx = sqlite3.connect('bilbili.db', check_same_thread = False)
cx.execute('''create table comment(videoname text,
chatid text,
dtTime text,
danmu_model text,
font text,
rgb text,
stamp text,
danmu_chi text,
userID text,
rowID text,
message text)''')

def request_get_comment(getdetail):
'''#获取弹幕内容'''
name,url,cid=getdetail
# url='http://www.bilibili.com'+url
url='http://comment.bilibili.com/{}.xml'.format(cid)
#preurl='http://www.bilibili.com'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)'}
response = requests.get(url=url, headers=headers)
tree=etree.HTML(response.content)
message=tree.xpath('//d/text()')
infos=tree.xpath('//d/@p')
comment=[info.split(',') for info in infos]
saveme=[]
# comments=[(cid,i) for i in zip(infos,message)]
for i in range(len(comment)-1):
# print i
try:
saveme.append((name,cid,comment[i][0],comment[i][1],comment[i][2],
comment[i][3],comment[i][4],comment[i][5],
comment[i][6],comment[i][7],message[i]
))
except Exception as e:
print(e)
continue

# print saveme
cx.executemany('''INSERT INTO comment VALUES(?,?,?,?,?,?,?,?,?,?,?)''',saveme)
cx.commit()

def indexget(url):
'''解析首页获取name,value,cid'''
r=requests.get(url)
tree=etree.HTML(r.content)
name=tree.xpath('//option/text()')
value=tree.xpath('//option/@value')
cid=tree.xpath('//option/@cid')
return [i for i in zip(name,value,cid)]

return True
if __name__ == "__main__":
'''eg: python xxx.py url
python xxx.py
url:'http://www.bilibili.com/video/av3663007'
'''
if len(sys.argv)>1:
first_url = sys.argv[1] or 'http://www.bilibili.com/video/av3663007'
else:
first_url='http://www.bilibili.com/video/av3663007'
preurl='http://www.bilibili.com'
get_comment_url= indexget(first_url)
for i in get_comment_url:
print (i)
request_get_comment(i)

cx.close()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: