爬取 bilibili 纪录片数据&数据可视化
说起纪录片就不得不提拉我入坑“冰冻星球”、“地球脉动”等国外神作,但是说到中国的纪录片,除了“舌尖上的中国”之外我居然想不到别的片子,但是最近在b站上看了很多央视爸爸拍的纪录片,比如“国家宝藏”,“航拍中国”等等,剧情结构、背景配乐、拍摄水平真的令我无比震撼,事不宜迟,从b站爬取纪录片的数据做一个简单的数据分析~
1.获取数据
1.1 获取查询api
首先我们需要爬取b站纪录片的数据,打开bilibili的纪录片索引页面后,进入F12 调试界面,之后F5刷新,在Network栏下简单分析可以看到b站的纪录片查询api是:
'https://bangumi.bilibili.com/media/web_api/search/result?style_id={0}&producer_id={1}&year={2}&order=2&st=3&sort=0&page={3}&season_type=3&pagesize=20'.format(style_id ,producer_id,year,page)
其中有4个参数style_id ,producer_id,year,page
,分别代表纪录片风格、制作方、出品年份和当前页码数(我们默认热度排序为降序,每页显示20个纪录片)。
b站的查看某季纪录片详细信息的api是:
'https://bangumi.bilibili.com/view/web_api/season?season_id={0}'.format(season_id)
其中有1个参数season_id
,代表一季纪录片的id信息。
style_id = {
'all': -1, 'history': 25 , 'food': 39, 'culture': 19, 'technology': 27,
'explore': 29, 'universe': 1201, 'pet': 1202, 'society': 1203, 'animal': 989 ,
'nature': 34, 'medical': 1204, 'military': 988, 'disaster': 1205,
'crime': 1205, 'mystery': 1205, 'journey': 31, 'sport': 1205
}
producer_id = {
'all': -1, 'cctv': 4, 'BBC': 1, 'discovery': 7,
'NHK': 2, 'history': 6, 'tv': 8, 'homemade': 9,
'ITV': 5, 'SKY': 3, 'ZDF': 10 ,
'Cooperation': 11, 'domestic': 12,'foreign': 13
}
year = {
'all' :-1,
'2019':'2009',
'2018' : '2018',
'2017' :'2017',
'2016' :'2016',
'2015' : '2015',
'2014-2010' :'2014-2010',
'2009-2005' :'2009-2005',
'2004-2000' :'2004-2000',
'90s' :'90年代',
'80s' :'80年代' ,
'before': '更早'
}
1.2 得到基本数据
爬取基本信息数据存入列表,并读入DataFrame中
page_num = 0
page_all = 0
video_frame = []
while(page_num <= page_all):
r = requests.get(get_url(page = page_num+1))
page_num += 1
video_dict = eval(r.text)
try:
video_data = video_dict['result']['data']
except:
print('not find video')
break
if page_all == 0:
video_page = video_dict['result']['page']
page_all = math.ceil(video_page['total']/video_page['size'])
print('find {} videos, {} pages'.format(video_page['total'], page_all))
for video in video_data:
video_frame.append([video['title'],\
time.localtime(video['order']['pub_date']).tm_year,\
video['season_id'], video['media_id']])
data = pd.DataFrame(video_frame,columns = ['name', 'years', 'season_id','media_id'])
print('finish')
data.head()
可以看到前5行数据, 其中season_id之后会用到
name | years | season_id | media_id |
---|---|---|---|
人生一串 | 2018 | 24439 | 97952 |
国家宝藏 第二季 | 2018 | 26017 | 4308862 |
国家宝藏 第一季 | 2017 | 21715 | 11592 |
历史那些事 | 2018 | 25810 | 139572 |
巡逻现场实录2018 | 2018 | 26025 | 4309122 |
1.3 得到详细数据
之后我们爬取纪录片的全部信息,并存入新的DataFrame
详细信息包括danmakus:弹幕
,favorites:收藏
,views:观看次数
,coins:投币
,area:区域信息
,episodes_duration:分集时长
,style:纪录片类型
,episodes_aid:分集信息
。
def get_detail_info(df, delay = 0.5):
url = r'https://bangumi.bilibili.com/view/web_api/season?season_id={0}'.format(df['season_id'])
print(url)
r = requests.get(url)
try:
info = eval(r.text)['result']
df['danmakus'] = info['stat']['danmakus']
df['favorites'] = info['stat']['favorites']
df['views'] = info['stat']['views']
df['coins'] = info['stat']['coins']
df['area'] = info['areas'][0]['name']
df['episodes_duration'] = []
df['style'] = info['style']
df