飞道的博客

卧槽!原来爬取B站弹幕这么简单

475人阅读  评论(0)

公众号后台回复“图书“,了解更多号主新书内容

 作者:叶庭云,https://blog.csdn.net/fyfugoyfa

  • 一、分析网页

  • 二、获取弹幕数据

  • 三、绘制词云图

视频链接:https://www.bilibili.com/video/BV1zE411Y7JY

一、分析网页

点击弹幕列表,查看历史弹幕,并选择任意一天的历史弹幕,此时就能找到存储该日期弹幕的ajax数据包,所有弹幕数据放在一个i标签里。

查看请求的相关信息可以发现Request URL关键就是 oid 和 date 两个参数,date很明显是日期,换日期可以实现翻页爬取弹幕,oid应该是视频标识之类的东西,换个oid可以访问其他视频弹幕页面。

在这里插入图片描述

二、获取弹幕数据

本文爬取该视频1月1日到8月6日的历史弹幕数据,需构造出时间序列:


   
  1. import pandas as pd
  2. start =  '20200101'
  3. end =  '20200806'
  4. # 生成时间序列
  5. date_list = [x  for x in pd.date_range(start, end).strftime( '%Y-%m-%d')]
  6. print(date_list)

运行结果如下:


   
  1. [ '2020-01-01''2020-01-02''2020-01-03''2020-01-04''2020-01-05''2020-01-06', ...  '2020-08-06']
  2. Process finished with exit code  0

爬虫代码如下:


   
  1. # -*- coding: UTF -8 -*-
  2. "" "
  3. @File    :spider.py
  4. @Author  :叶庭云
  5. @CSDN    :https://yetingyun.blog.csdn.net/
  6. " ""
  7. import requests
  8. import pandas as pd
  9. import re
  10. import time
  11. import random
  12. from concurrent.futures  import ThreadPoolExecutor
  13. import datetime
  14. user_agent = [
  15.      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
  16.      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
  17.      "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
  18.      "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
  19.      "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
  20.      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
  21.      "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
  22.      "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
  23.      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
  24.      "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
  25.      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
  26.      "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
  27.      "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
  28.      "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
  29.     ]
  30. start_time = datetime.datetime.now()
  31. def  Grab_barrage(date):
  32.     # 伪装请求头
  33.     headers = {
  34.          "sec-fetch-dest""empty",
  35.          "sec-fetch-mode""cors",
  36.          "sec-fetch-site""same-site",
  37.          "origin""https://www.bilibili.com",
  38.          "referer""https://www.bilibili.com/video/BV1Z5411Y7or?from=search&seid=8575656932289970537",
  39.          "cookie""_uuid=0EBFC9C8-19C3-66CC-4C2B-6A5D8003261093748infoc; buvid3=4169BA78-DEBD-44E2-9780-B790212CCE76155837infoc; sid=ae7q4ujj; DedeUserID=501048197; DedeUserID__ckMd5=1d04317f8f8f1021; SESSDATA=e05321c1%2C1607514515%2C52633*61; bili_jct=98edef7bf9e5f2af6fb39b7f5140474a; CURRENT_FNVAL=16; rpdid=|(JJmlY|YukR0J'ulmumY~u~m; LIVE_BUVID=AUTO4315952457375679; CURRENT_QUALITY=80; bp_video_offset_501048197=417696779406748720; bp_t_offset_501048197=417696779406748720; PVID=2",
  40.          "user-agent": random.choice(user_agent),
  41.     }
  42.     # 构造url访问   需要用到的参数
  43.     params = {
  44.          'type'1,
  45.          'oid''128777652',
  46.          'date': date
  47.     }
  48.     # 发送请求  获取响应
  49.     response = requests.get(url, params=params, headers=headers)
  50.     #  print(response.encoding)   重新设置编码
  51.     response.encoding =  'utf-8'
  52.     #  print(response.text)
  53.     # 正则匹配提取数据
  54.     comment = re.findall( '<d p=".*?">(.*?)</d>', response.text)
  55.     # 将每条弹幕数据写入txt
  56.     with open( 'barrages.txt''a+') as f:
  57.          for con in comment:
  58.             f.write(con +  '\n')
  59.     time.sleep(random.randint( 13))   # 休眠
  60. def main():
  61.     # 开多线程爬取   提高爬取效率
  62.     with ThreadPoolExecutor(max_workers= 4) as executor:
  63.         executor. map(Grab_barrage, date_list)
  64.     # 计算所用时间
  65.     delta = (datetime.datetime.now() - start_time).total_seconds()
  66.      print(f '用时:{delta}s')
  67. if __name__ ==  '__main__':
  68.     # 目标url
  69.     url =  "https://api.bilibili.com/x/v2/dm/history"
  70.     start =  '20200101'
  71.     end =  '20200806'
  72.     # 生成时间序列
  73.     date_list = [x  for x in pd.date_range(start, end).strftime( '%Y-%m-%d')]
  74.     count =  0
  75.     # 调用主函数
  76.     main()

程序运行,成功爬取下弹幕数据并保存到txt。


   
  1. 用时: 32.040222s
  2. Process finished with exit code  0

三、绘制词云图

1. 读取txt中弹幕数据


   
  1. with open( 'barrages.txt') as f:
  2.     data = f.readlines()
  3.      print(f '弹幕数据:{len(data)}条')

运行结果如下:


   
  1. 弹幕数据: 52708
  2. Process finished with exit code  0

2. Pyecharts 绘制词云


   
  1. import jieba
  2. import collections
  3. import re
  4. from pyecharts.charts  import WordCloud
  5. from pyecharts.globals  import SymbolType
  6. from pyecharts  import options as opts
  7. from pyecharts.globals  import ThemeType, CurrentConfig
  8. CurrentConfig.ONLINE_HOST =  'D:/python/pyecharts-assets-master/assets/'
  9. with open( 'barrages.txt') as f:
  10.     data = f.read()
  11. # 文本预处理  去除一些无用的字符   只提取出中文出来
  12. new_data = re.findall( '[\u4e00-\u9fa5]+', data, re.S)  # 只要字符串中的中文
  13. new_data =  " ".join(new_data)
  14. # 文本分词--精确模式分词
  15. seg_list_exact = jieba.cut(new_data, cut_all=True)
  16. result_list = []
  17. with open( 'stop_words.txt', encoding= 'utf-8') as f:
  18.     con = f.readlines()
  19.     stop_words = set()
  20.      for i in con:
  21.         i = i.replace( "\n""")   # 去掉读取每一行数据的\n
  22.         stop_words.add(i)
  23. for word in seg_list_exact:
  24.     # 设置停用词并去除单个词
  25.      if word not in stop_words and  len(word) >  1:
  26.         result_list. append(word)
  27. print(result_list)
  28. # 筛选后统计
  29. word_counts = collections.Counter(result_list)
  30. # 获取前 100最高频的词
  31. word_counts_top100 = word_counts.most_common( 100)
  32. # 可以打印出来看看统计的词频
  33. print(word_counts_top100)
  34. word1 = WordCloud(init_opts=opts.InitOpts(width= '1350px', height= '750px', theme=ThemeType.MACARONS))
  35. word1.add( '词频', data_pair=word_counts_top100,
  36.           word_size_range=[ 15108], textstyle_opts=opts.TextStyleOpts(font_family= 'cursive'),
  37.           shape=SymbolType.DIAMOND)
  38. word1.set_global_opts(title_opts=opts.TitleOpts( '弹幕词云图'),
  39.                       toolbox_opts=opts.ToolboxOpts(is_show=True, orient= 'vertical'),
  40.                       tooltip_opts=opts.TooltipOpts(is_show=True, background_color= 'red', border_color= 'yellow'))
  41. # 渲染在html页面上
  42. word1.render( "弹幕词云图.html")

运行效果如下:

3. stylecloud 绘制词云


   
  1. # -*- coding: UTF -8 -*-
  2. "" "
  3. @File    :stylecloud_词云图.py
  4. @Author  :叶庭云
  5. @CSDN    :https://yetingyun.blog.csdn.net/
  6. " ""
  7. from stylecloud  import gen_stylecloud
  8. import jieba
  9. import re
  10. # 读取数据
  11. with open( 'barrages.txt') as f:
  12.     data = f.read()
  13. # 文本预处理  去除一些无用的字符   只提取出中文出来
  14. new_data = re.findall( '[\u4e00-\u9fa5]+', data, re.S)
  15. new_data =  " ".join(new_data)
  16. # 文本分词
  17. seg_list_exact = jieba.cut(new_data, cut_all=False)
  18. result_list = []
  19. with open( 'stop_words.txt', encoding= 'utf-8') as f:
  20.     con = f.readlines()
  21.     stop_words = set()
  22.      for i in con:
  23.         i = i.replace( "\n""")   # 去掉读取每一行数据的\n
  24.         stop_words.add(i)
  25. for word in seg_list_exact:
  26.     # 设置停用词并去除单个词
  27.      if word not in stop_words and  len(word) >  1:
  28.         result_list. append(word)
  29. print(result_list)
  30. # stylecloud绘制词云
  31. gen_stylecloud(
  32.     text= ' '.join(result_list),    # 输入文本
  33.     size= 600,                      # 词云图大小
  34.     collocations=False,            # 词语搭配
  35.     font_path=r 'C:\Windows\Fonts\msyh.ttc',   # 字体
  36.     output_name= '词云图.png',                 # stylecloud 的输出文本名
  37.     icon_name= 'fas fa-apple-alt',             # 蒙版图片
  38.     palette= 'cartocolors.qualitative.Bold_5'  # palettable调色方案
  39. )

运行效果如下:


   
  1. ◆ ◆ ◆  ◆ ◆
  2. 麟哥新书已经在京东上架了,我写了本书:《拿下Offer-数据分析师求职面试指南》,目前京东正在举行 100 -40活动,大家可以用相当于原价 5折的预购价格购买,还是非常划算的:

   
  1. 数据森麟公众号的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里交流关于数据分析&数据挖掘的相关内容,还没有加入的小伙伴可以扫描下方管理员二维码,进群前一定要关注公众号奥,关注后让管理员帮忙拉进群,期待大家的加入。
  2. 管理员二维码:
  3. 猜你喜欢
  4. ● 麟哥拼了!!!亲自出镜推荐自己新书《数据分析师求职面试指南》● 厉害了!麟哥新书登顶京东销量排行榜!● 笑死人不偿命的知乎沙雕问题排行榜
  5. ● 用Python扒出B站那些“惊为天人”的阿婆主!● 你相信逛B站也能学编程吗

转载:https://blog.csdn.net/weixin_38753213/article/details/109554851
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场