萝卜头IT论坛

了解更多
搜索
查看: 157|回复: 1
收起左侧

python实现B站收藏夹同步

[复制链接]
发表于 2020-2-1 11:06:46 | 显示全部楼层 |阅读模式
本帖最后由 这个显卡不太冷 于 2020-2-1 11:18 编辑

为了防止B站收藏的内容被吞,做了个这个同步工具

食用方法

  • 要求至少python3.7的环境, Windows
  • 基于you-get,需要安装最新的you-get,可以直接pip install you-get
  • video_list处填入收藏夹ID。具体来说,在web端打开B站收藏夹例 https://space.bilibili.com/2170464/favlist?fid=61630664&ftype=create 其中fid=xxx即收藏夹ID。
  • 若收藏夹ID是私有收藏夹,需要登录B站后复制一下cookie中的SESSDATA字段,填入第39行,有效期一个月
  • dashflv的高帧率视频需要完整cookies,在脚本目录下建立cookies.txt将B站cookies以Netscape cookies的格式粘贴
  • 目录下的db.ini是日志。code=0表示同步成功。否则未成功,原因可能是因为视频已经失效,或者在特殊页面,如拜年祭专有页面。

image.png

效果

image.png

image.png

代码


# coding=utf-8 
import subprocess
import sys, os
import requests, time, urllib.request, re
import configparser

def RunShellWithReturnCode(command,print_output=True,universal_newlines=True):
    video_title = ""
    os.environ["COMSPEC"] = 'powershell'
    p = subprocess.Popen(command, stdout=subprocess.PIPE, encoding='utf-8', stderr=subprocess.PIPE, shell=True, universal_newlines=universal_newlines)
    if print_output:
        print(command)
        output_array = []
        while True:
            line = p.stdout.readline()
            if not line:
                break
            print(line.strip("/n"))
            titlepos = line.find("title:")
            if titlepos != -1 :
                video_title = line[titlepos + 7:].strip()
            output_array.append(line)
        output ="".join(output_array)
    else:
        output = p.stdout.read()
    p.wait()
    errout = p.stderr.read()
    if print_output and errout:
        print(sys.stderr, errout)
    p.stdout.close()
    p.stderr.close()
    return output, p.returncode, video_title


def get_play_list(media_id, pn):
    url_api = 'https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id={}&pn={}&ps=20'.format(media_id, pn)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
        'Cookie': 'SESSDATA=598c42e6%2C1582286719%2C48857111', # 登录B站后复制一下cookie中的SESSDATA字段,有效期1个月
        'Host': 'api.bilibili.com'
    }
    html = requests.get(url_api, headers=headers).json()
    video_list = []
    try:
        for i in html['data']['medias']:
            video_list.append(i['short_link'])
        print(video_list)
    except KeyError as identifier:
        print(identifier)
    return video_list


def check_code(video_url, conf):
    if(conf.has_section(video_url)):
        if(conf.get(video_url, 'code') == '1'):
            return False
        return True
    else :
        conf.add_section(video_url)
        return False


if __name__ == "__main__":
    # RunShellWithReturnCode("you-get -i \"https://www.bilibili.com/video/av85365197\" ")
    cfg = "db.ini"
    conf = configparser.ConfigParser()
    conf.read(cfg, encoding='utf-8')

    udebug = 0

    for i in range(1, 51):
        video_list = get_play_list(135779664, i)
        if len(video_list):
            for video_url in video_list:
                if(check_code(video_url, conf) == False):
                    r_out, r_code, video_title = RunShellWithReturnCode("you-get -c cookies.txt --format=dash-flv '{}' ".format(video_url))
                    if(r_code == 1):
                        r_out, r_code, video_title = RunShellWithReturnCode("you-get -c cookies.txt '{}' ".format(video_url))
                    conf.set(video_url, 'code', str(r_code)) 
                    conf.set(video_url, 'title', video_title)
                    conf.write(open("db.ini", "w", encoding='utf-8'))
                # r_code = 0 : yes 
                # r_code = 1 : no
        else :
            print("sync complate")
            break

回复

使用道具 举报

发表于 2020-2-3 23:41:02 | 显示全部楼层
这个冬天不太冷

感谢分享~!
回复

使用道具 举报

联系站长(Contact)|萝卜头IT论坛 ( 苏ICP备15050961号-1 )

GMT+8, 2020-2-23 15:11 , Processed in 0.103792 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表