搜索
查看: 4813|回复: 6

python实现B站收藏夹同步

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

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


## 食用方法

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

![image.png](data/attachment/forum/202002/01/110220ktw9htbe7h9g9toa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600 "image.png")

## 效果

![image.png](data/attachment/forum/202002/01/110502alyjeoysdds1l7xj.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600 "image.png")

![image.png](data/attachment/forum/202002/01/111846phic19c11n851xnh.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600 "image.png")

## 代码

```python

# 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
   

```
[/md]
image.png
image.png
image.png
回复

使用道具 举报

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

感谢分享~!
回复

使用道具 举报

发表于 2020-3-5 18:30:47 | 显示全部楼层
好像不错,虽然没有这个习惯。
回复

使用道具 举报

发表于 2020-3-12 08:29:43 | 显示全部楼层
感谢大佬!!!!!!!!!很有用!!!
回复

使用道具 举报

发表于 2020-3-23 15:48:03 | 显示全部楼层
膜拜,这个太神奇了,太方便了。
回复

使用道具 举报

 楼主| 发表于 2020-3-23 18:36:06 | 显示全部楼层
拂晓 发表于 2020-3-23 15:48
膜拜,这个太神奇了,太方便了。

失效,今天b站改了接口,暂时爬不到了
回复

使用道具 举报

发表于 2020-3-24 18:52:46 | 显示全部楼层
这个显卡不太冷 发表于 2020-3-23 18:36
失效,今天b站改了接口,暂时爬不到了

AV改成BV了,稿件标识也从纯数字改成了数字和大小写字母组成的字符串。
回复

使用道具 举报

联系我们(Contact)|手机版|萝卜头IT论坛 ( 苏ICP备15050961号-1 )

GMT+8, 2024-11-21 19:50 , Processed in 0.086844 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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