Skip to content

Latest commit

 

History

21 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation


该脚本用于分析哔站视频评论。


思路

  • 评论 API:

  • 首先通过接口获得每一页的内容,保存到本地

    • 格式为 Json
    • 需要获得当前的总页数
    • 保存路径为:./comments/%04d.json
    • 如果是热门视频,评论增加得很快,怎么办?
  • 然后分析所得的 json 文件,将所需的内容筛选出来

    • 一级评论:对一级评论的回复暂不收录
    • 评论的赞数和回复数:这两个指标可以衡量该评论是否热门
      • 当然返回的每一页 json 中也有热门评论和置顶评论,可以根据 json 中的 key 来判断
    • 评论的楼层和用户名:便于后续其他操作定位
    • 评论时间
  • 将所得内容整理成新的 json 文件

  • 可视化


源 Json 格式

链接:https://api.bilibili.com/x/v2/reply?pn=1&type=1&oid=22755224&nohot=1

获得的 Json 格式如下:

{
    "code":0,
    "data":{
        "config":Object{...},
        "hots":Array[0],
        "notice":null,
        "page":Object{...},
        "replies":Array[20],
        "top":null,
        "upper":Object{...}
    },
    "message":"0",
    "ttl":1
}
  • 有用的数据都在 "data" 里。

  • "config" 暂时无用。

    "config":{
                "showadmin":1,
                "showentry":1
    }

  • "hots" 里记录了热门评论。

    "hots":Array[0]

    这里由于使用了 nohot=1,因此为空。 无论 pn 值是多少,如果 nohot=0,都会将热门评论记录下来。

  • "notice" 暂时无用。

    "notice":null

  • "page" 里保存了每一页的信息
    "page":{
        "acount":1274,    // 总的评论数,应该是包括了一级评论和次级评论。
        "count":684,      // 一级评论数。该值与最高楼数不符,猜测是因为有些楼层被删除了。
        "num":1,          // 当前页号。从 1 到最大页数。
        "size":20         // 该页一级评论数目。应该是最大 20}
  • "replies" 里保存了该页的一级评论及其回复。
    "replies":Array[20]

    每页有 20 条一级评论。Array 中的每个元素都是 Object 类型。

      典型的 Object 格式为:

      {
          "rpid":761233844,           // 该评论的ID
          "oid":22755224,             // 视频av号
          "type":1,                   
          "mid":229564109,            // 用户 mid
          "root":0,                   // 该评论的根ID,即所在的一级评论,默认为0,表示该评论为一级评论
          "parent":0,                 // 该评论所回复的评论ID
          "count":1,                  // 可能是历史的回复数?
          "rcount":1,                 // 该楼下的现存回复数
          "floor":702,                // 楼层
          "state":0,
          "fansgrade":0,
          "attr":0,
          "ctime":1525191553,         // 评论的时间戳
          "rpid_str":"761233844",
          "root_str":"0",
          "parent_str":"0",
          "like":2,                   // 点赞数
          "action":0,
          "member":{                  // 这里保存了用户信息,详情可以参考:https://github.com/uupers/BiliSpider/wiki/Bilibili-API-%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF
              "mid":"229564109",      // mid
              "uname":"小白白白白j",  // 昵称
              "sex":"保密",           // 性别
              "sign":"",              // 签名
              "avatar":"http://i1.hdslb.com/bfs/face/d189dcf522fd0da08043895ca53b5bd8485a50d2.jpg",  // 头像图片地址
              "rank":"10000",
              "DisplayRank":"0",
              "level_info":Object{...},
              "pendant":Object{...},
              "nameplate":Object{...},
              "official_verify":Object{...},
              "vip":Object{...},
              "fans_detail":null,
              "following":0
          },
          "content":{                // 这里保存了评论的信息
              "message":"追番的人这么少吗",       // 评论内容
              "plat":2,                           // 可能是平台?(电脑,手机,Pad)
              "device":"",
              "members":[
              ]
          },
          "replies":[                 // 这里保存了对一级评论的回复,需要关注的是这里的回复数量
              Object{...}             // 二级三级评论的格式和一级评论类似
          ],
          "assist":0
      }
      
  • "upper" 里保存了置顶评论的信息。
    "upper":{
                "mid":299999920,    // 该视频 UP 的 mid
                "top":Object{...}
    }

    这里 "top" 的格式和上面的一级评论是一样的。

    只不过里面的 "replies" 最多只有3个,这是因为网页版默认只展示最多3条对置顶评论的回复。只有点击“点击查看”,才会加载所有的评论。


目标 Json 格式

各参数在 Json 文件中的位置:

data -> replies -> [i=0:19] ->

楼层 时间 用户 消息 点赞数 回复数
floor fromtimestamp(ctime) member -> uname content -> message like rcount

呈现效果:

楼层 时间 用户 消息 点赞数 回复数
53 2018-04-30 10:31:17 星之碎片灬 B站不是以前那个只看番的B站了 1 7
52 2018-04-30 10:21:11 オレンジの約束 哇,原来B站不是用来看番的 1 0
51 2018-04-30 10:17:39 哆啦有个梦 总结:从哔哩哔哩动画变成了哔哩哔哩 2001 44

这里暂时只考虑了一级评论。二级评论的影响体现在回复数上。

目标 Json 格式:

[
    {
        "message":"追番的人这么少吗",
        "like":2,
        "replynum":1,
        "floor":702,
        "uname":"小白白白白j",
        "mid":"229564109",
        "time":"2018-05-02 00:19:13",
        "ctime":"1525191553"
    },
    {
        "message":"投一波硬币",
        "like":0,
        "reply":0,
        "floor":693,
        "uname":"堂主小黑",
        "mid":9388872,
        "time":"2018-05-01 23:59:13",
        "ctime":1525190353
    }
]

实现问题

  • 如何获得总的页数?

    • (源 Json 中并没有记录相关的数据)
    • ✔ 通过 json 文件中的 "data" -> "page" -> "count" + "size" 计算得到
      • 先获取第 1 页,然后解析出这几个值,再获取后续的页面
    • 解析网页中显示最大页码的对应元素,然后提取该数字
      • 优点:精度高
      • 缺点:
        • 效率较低:相比网络 IO,这点解析的时间可以忽略不计
        • 如果恰好后来的页数增加,则会漏爬:如果评论增长速度较低,可以忽略这个问题,或者可以定期重爬
        • 在 html 文件里是找不到这个内容的,因为这是前端实时计算出来的
    • 通过分析已有的 Json 是否采集到了 1 楼评论
      • 优点:可以避免漏爬和多爬
      • 缺点:
        • 效率较低,每爬一页都要解析
        • 如果 1 楼评论被用户或者 UP 主删除,则需要处理该异常情况
  • 如何保证楼数不重叠?

    • (因为页面是动态加载的,如果爬取时出现新评论,会将该页最下面的评论顶到下一页)
    • 去重:如果发现该楼已经在数据库里了,就不再加入
  • 以什么格式保存处理好的数据?

    • ✔ json
      • 优点:
        • 结构化
        • 方便检索和处理
      • 缺点
        • 不方便直接查看
        • 只适合处理少量数据
    • csv:
      • 优点:
        • 便于直接查看和处理
      • 缺点:
        • 评论中有可能出现逗号:给该项加上引号(评论中又出现引号怎么办)
        • 只适合处理少量数据
        • 难以处理嵌套类型的数据:评论里还有评论
    • 数据库
      • 优点:
        • 支持更多更复杂的操作
        • 可以容纳大量数据
      • 缺点:
        • 配置较为复杂

参考链接

About

Analyze comments of bilibili videos

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages