欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

用 Python 获取 B 站播放历史记录

程序员文章站 2022-10-06 10:10:38
用 Python 获取 B 站播放历史记录 最近 B 站出了一个年度报告,统计用户一年当中在 B 站上观看视频的总时长和总个数。过去一年我居然在 B 站上看了2600+个视频,总计251个小时,居然花了这么多时间,吓得我差点把 Bilibili App 卸载了... 然而我又很好奇,到底我在 B 站 ......

用 python 获取 b 站播放历史记录

最近 b 站出了一个年度报告,统计用户一年当中在 b 站上观看视频的总时长和总个数。过去一年我居然在 b 站上看了2600+个视频,总计251个小时,居然花了这么多时间,吓得我差点把 bilibili app 卸载了...

 

 

 

然而我又很好奇,到底我在 b 站上都看了些什么类型小姐姐的视频,用几行 python 代码实现了一下。

获取请求 api 接口与 cookie

实现起来非常容易,获取 cookie 模拟请求即可

  1. 使用 chrome 浏览器
  2. 登陆b 站,进入历史记录
  3. 在网页任意位置,鼠标右键检查

 

 

 

  1. 按照下图所示,进入network页面,筛选框输入history,对结果进行筛选,页面滚轮往下即可看到浏览过程中的历史记录请求的header

 

 

 

  1. 将 header 下, cookie 一行的字符串复制出来到一个cookie.txt文本里

 

 

 

python 代码实现

  • 伪造浏览器请求
import json
import requests

def read_cookies_file(filename):
    """read cookie txt file
    :param filename: (str) cookies file path
    :return: (dict) cookies
    """
    with open(filename, 'r') as fp:
        cookies = fp.read()
        return cookies

def get_header(filename):
    cookie = read_cookies_file(filename)
    headers = {
        'accept': '*/*',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'zh-cn,zh;q=0.9,en-us;q=0.8,en;q=0.7',
        'connection': 'keep-alive',
        'cookie': cookie,
        'host': 'api.bilibili.com',
        'referer': 'https://www.bilibili.com/account/history',
        'user-agent': 'mozilla/5.0 (macintosh; intel mac os x 10_14_2) applewebkit/537.36 '
                      '(khtml, like gecko) chrome/71.0.3578.98 safari/537.36'
    }
    return headers

def req_get(headers, url):
    resp = requests.get(url, headers=headers)
    return json.loads(resp.text)
  • 使用 cookie 模拟请求
def get_all_bili_history(cookie_file):
    headers = bilibili.get_header(cookie_file)
    history = {'all': []}
    for page_num in range(max_page):
        time.sleep(0.6)
        url = 'https://api.bilibili.com/x/v2/history?pn={pn}&ps={ps}&jsonp=jsonp'.format(pn=page_num, ps=page_per_num)
        result = bilibili.req_get(headers, url)
        print('page = {} code = {} datalen = {}'.format(page_num, result['code'], len(result['data'])))
        if len(result['data']) == 0:
            break
        history['all'].append(result)

    return history
  • 代码非常简单,完整代码加群973783996

存在的问题

  • 本来想拿到所有的播放记录,做一些统计和预测,但是经过实测,b 站只能获取到最近1000条或者最近3个月的播放记录
  • 如果想获得更多,只能做一个监测程序,不停地从接口获取数据

安全问题

尽量不要使用不安全的 wifi 网络,有可能会被别有用心之人获取网络请求的 package,易泄露个人隐私。