前言

一直以来我都有构建属于自己的动漫库的想法,并且我也为之付诸了行动,我通过PLEX和本地的群晖DS220NAS服务器,搭建了一套集存储和在线观看于一体的媒体库。

媒体库建完后,作为一个有着些许强迫症的用户,我还希望可以记录每部番剧的版本,例如是web,还是BDMV,亦或是BDrip,字幕来自于哪个字幕组,以及是哪个压制组,分辨率是多少等等,作为后续是否洗板的依据。

为此,我又通过notion创建了一个数据库,为每一部我收集的番剧创建一个列表记录信息,但是每加一部我都得去bangumi上把番剧对应的基础信息一个个贴到表格里面,这让我觉得有些繁琐,于是萌生了自动化这一步骤的想法。

关于

bangumi API

Bangumi是一个专注于动漫、漫画、游戏、轻小说等文化产品的社区网站。它提供了开放的API接口,让开发者可以方便地获取番剧、人物等相关信息。我们可以通过访问https://api.bgm.tv/subject/{动画ID}来获取指定番剧的信息。例如,我们要获取《进击的巨人》第一季的信息,可以访问https://api.bgm.tv/subject/55770。返回的信息包括番剧的中文名、日文名、简介、封面图等。

{
    "id": 55770,
    "url": "http:\/\/bgm.tv\/subject\/55770",
    "type": 2,
    "name": "\u9032\u6483\u306e\u5de8\u4eba",
    "name_cn": "\u8fdb\u51fb\u7684\u5de8\u4eba",
    "summary": "\u60a0\u957f\u7684\u5386\u53f2\u4e4b\u4e2d,\u4eba\u7c7b\u66fe\u4e00\u5ea6\u56e0\u88ab\u5de8\u4eba\u6355\u98df\u800c\u5d29\u6e83\u3002\u5e78\u5b58\u4e0b\u6765\u7684\u4eba\u4eec\u5efa\u9020\u4e86\u4e00\u9762\u5de8\u5927\u7684\u5899\u58c1,\u9632\u6b62\u4e86\u5de8\u4eba\u7684\u5165\u4fb5\u3002\u4e0d\u8fc7,\u4f5c\u4e3a\u201c\u548c\u5e73\u201d\u7684\u4ee3\u4ef7,\u4eba\u7c7b\u5931\u53bb\u4e86\u5230\u5899\u58c1\u7684\u5916\u9762\u53bb\u8fd9\u4e00\u201c\u81ea\u7531\u201d\u3002\u4e3b\u4eba\u516c\u827e\u4f26\u00b7\u8036\u683c\u5c14\u5bf9\u8fd8\u6ca1\u89c1\u8fc7\u7684\u5916\u9762\u7684\u4e16\u754c\u62b1\u6709\u5174\u8da3\u3002\u5728\u4ed6\u6b63\u505a\u7740\u5230\u5899\u58c1\u7684\u5916\u9762\u53bb\u8fd9\u4e2a\u68a6\u7684\u65f6\u5019,\u6bc1\u574f\u5899\u58c1\u7684\u5927\u5de8\u4eba\u51fa\u73b0\u4e86\uff01",
    "eps": 25,
    "eps_count": 25,
    "air_date": "2013-04-06",
    "air_weekday": 6,
    "rating": {
        "total": 19860,
        "count": {
            "10": 2309,
            "9": 4448,
            "8": 8211,
            "7": 3428,
            "6": 960,
            "5": 267,
            "4": 71,
            "3": 32,
            "2": 28,
            "1": 106
        },
        "score": 8.1
    },
    "rank": 184,
    "images": {
        "large": "http:\/\/lain.bgm.tv\/pic\/cover\/l\/78\/c9\/55770_HsJfh.jpg",
        "common": "http:\/\/lain.bgm.tv\/pic\/cover\/c\/78\/c9\/55770_HsJfh.jpg",
        "medium": "http:\/\/lain.bgm.tv\/pic\/cover\/m\/78\/c9\/55770_HsJfh.jpg",
        "small": "http:\/\/lain.bgm.tv\/pic\/cover\/s\/78\/c9\/55770_HsJfh.jpg",
        "grid": "http:\/\/lain.bgm.tv\/pic\/cover\/g\/78\/c9\/55770_HsJfh.jpg"
    },
    "collection": {
        "wish": 1255,
        "collect": 28200,
        "doing": 2203,
        "on_hold": 854,
        "dropped": 867
    }
}

bangumi-api
bangumi-api

Notion API

Notion是一个功能强大的笔记和任务管理工具,它还能够创建数据库,方便地存储和管理数据。Notion提供了开放的API接口,可以让我们通过编程的方式访问和修改数据库中的数据。

申请API密钥

  1. 登录你的Notion账号,进入My Integrations页面
  2. 点击“创建新集成”按钮,填写相关信息,如名称和描述。
  3. 在“关联的工作区”中选择需要使用的API权限。
  4. 点击“提交”按钮,完成申请。

使用API密钥

  1. My Integrations页面中找到你创建的API,点击进入。
  2. 生成的API密钥将显示在页面上,复制并保存好API密钥,后面会用到。

操作步骤

确认完想法后,由于技术有限,第一个版本我准备以实现自动输入动画信息为目标

1、创建Notion数据库

由于只需要先自动录入动画信息,因此只需要创建一个简单的数据库,包含动画的名称、中文名、bangumi的ID、放送开始时间、评分、话数和链接这些信息,并且记录对应的属性。

  • 标题:text
  • 中文名:text
  • ID:text
  • 放送开始:data
  • 评分:number
  • 话数:number
  • 链接:url

创建完成表格后,记录下该表格的database_id,后面会用到,这边我是直接通过网页打开的数据库,因此直接在链接中就能找到。

https://www.notion.so/database_id?v=1b6b407fb4da75f29b755e3b7

数据库模板
数据库模板

2、整理API返回信息

在上面我们已经确定了这次需要抓取的信息,然后根据目标,在api返回值中找到对应的信息,并且记录关键值。下面还是以《进击的巨人》为例:

{"id":55770,"url":"http:\/\/bgm.tv\/subject\/55770","type":2,"name":"\u9032\u6483\u306e\u5de8\u4eba","name_cn":"\u8fdb\u51fb\u7684\u5de8\u4eba","summary":"\u60a0\u957f\u7684\u5386\u53f2\u4e4b\u4e2d,\u4eba\u7c7b\u66fe\u4e00\u5ea6\u56e0\u88ab\u5de8\u4eba\u6355\u98df\u800c\u5d29\u6e83\u3002\u5e78\u5b58\u4e0b\u6765\u7684\u4eba\u4eec\u5efa\u9020\u4e86\u4e00\u9762\u5de8\u5927\u7684\u5899\u58c1,\u9632\u6b62\u4e86\u5de8\u4eba\u7684\u5165\u4fb5\u3002\u4e0d\u8fc7,\u4f5c\u4e3a\u201c\u548c\u5e73\u201d\u7684\u4ee3\u4ef7,\u4eba\u7c7b\u5931\u53bb\u4e86\u5230\u5899\u58c1\u7684\u5916\u9762\u53bb\u8fd9\u4e00\u201c\u81ea\u7531\u201d\u3002\u4e3b\u4eba\u516c\u827e\u4f26\u00b7\u8036\u683c\u5c14\u5bf9\u8fd8\u6ca1\u89c1\u8fc7\u7684\u5916\u9762\u7684\u4e16\u754c\u62b1\u6709\u5174\u8da3\u3002\u5728\u4ed6\u6b63\u505a\u7740\u5230\u5899\u58c1\u7684\u5916\u9762\u53bb\u8fd9\u4e2a\u68a6\u7684\u65f6\u5019,\u6bc1\u574f\u5899\u58c1\u7684\u5927\u5de8\u4eba\u51fa\u73b0\u4e86\uff01","eps":25,"eps_count":25,"air_date":"2013-04-06","air_weekday":6,"rating":{"total":16999,"count":{"10":1861,"9":3645,"8":7057,"7":3079,"6":885,"5":249,"4":70,"3":29,"2":27,"1":97},"score":8},"rank":205,"images":{"large":"http:\/\/lain.bgm.tv\/pic\/cover\/l\/78\/c9\/55770_HsJfh.jpg","common":"http:\/\/lain.bgm.tv\/pic\/cover\/c\/78\/c9\/55770_HsJfh.jpg","medium":"http:\/\/lain.bgm.tv\/pic\/cover\/m\/78\/c9\/55770_HsJfh.jpg","small":"http:\/\/lain.bgm.tv\/pic\/cover\/s\/78\/c9\/55770_HsJfh.jpg","grid":"http:\/\/lain.bgm.tv\/pic\/cover\/g\/78\/c9\/55770_HsJfh.jpg"},"collection":{"wish":1023,"collect":23382,"doing":2139,"on_hold":785,"dropped":819}}

由于直接通过网页获取的返回值是json语言,无法显示中文字符,且格式比较乱,因此我们需要通过简单的python脚本转换一下。

记得先导入requests和json库

import requests
import json

api_url = f"https://api.bgm.tv/subject/55770"
response = requests.get(api_url)
data = response.json()
#对输出的数据进行序列化,ensure_ascii用于输出保证将所有输入的非 ASCII 字符转义,indent是一个正整数,  代表序列化后的缩进
data = json.dumps(data, ensure_ascii=False, indent=4)
print(data)

转换后:

{
    "id": 55770,
    "url": "http://bgm.tv/subject/55770",
    "type": 2,
    "name": "進撃の巨人",
    "name_cn": "进击的巨人",
    "summary": "悠长的历史之中,人类曾一度因被巨人捕食而崩溃。幸存下来的人们建造了一面巨大的墙壁,防止了巨人的入侵。不过,作为“和平”的代价,人类失去了到墙壁的外面去这一“自由”。主人公艾伦·耶格尔对还没见过的外面的世界抱有兴趣。在他正做着到墙壁的外面去这个梦的时候,毁坏墙壁的大巨人出现了!",
    "eps": 25,
    "eps_count": 25,
    "air_date": "2013-04-06",
    "air_weekday": 6,
    "rating": {
        "total": 16999,
        "count": {
            "10": 1861,
            "9": 3645,
            "8": 7057,
            "7": 3079,
            "6": 885,
            "5": 249,
            "4": 70,
            "3": 29,
            "2": 27,
            "1": 97
        },
        "score": 8
    },
    "rank": 205,
    "images": {
        "large": "http://lain.bgm.tv/pic/cover/l/78/c9/55770_HsJfh.jpg",
        "common": "http://lain.bgm.tv/pic/cover/c/78/c9/55770_HsJfh.jpg",
        "medium": "http://lain.bgm.tv/pic/cover/m/78/c9/55770_HsJfh.jpg",
        "small": "http://lain.bgm.tv/pic/cover/s/78/c9/55770_HsJfh.jpg",
        "grid": "http://lain.bgm.tv/pic/cover/g/78/c9/55770_HsJfh.jpg"
    },
    "collection": {
        "wish": 1023,
        "collect": 23382,
        "doing": 2139,
        "on_hold": 785,
        "dropped": 819
    }
}

进程已结束,退出代码0

我们需要根据数据库中的表格,找到对应的关键值。

  • 标题:name
  • 中文名:name_cn
  • ID:id
  • 放送开始:air_date
  • 评分:rating(score)
  • 话数:eps_count
  • 链接:url

3、调用API

整理完API返回值后,我们需要通过脚本,匹配对应的关键值,并且将我们需要的信息输出来。因此我们需要在上面的脚本里添加对应关键值的匹配信息

import requests

api_url = f"https://api.bgm.tv/subject/55770"
response = requests.get(api_url)
data = response.json()

#匹配对应的关键值,你可以根据你的需要获取更多的信息
title = data['name']
name_cn = data['name_cn']
episodes = data['eps_count']
air_date = data['air_date']
rating_sorce = data['rating']['score']
id = data["id"]
url = data["url"]

print(title, name_cn, episodes, air_date, rating_sorce, id, url)

根据上面的脚本,可以获取到下面这些信息
進撃の巨人 进击的巨人 25 2013-04-06 8 55770 http://bgm.tv/subject/55770

4、通过Notion API生成表格

在上述步骤中,我们已经通过Bangumi的API获取到了我们想要的动画信息,接下来,我们需要将这些信息通过Notion的API,自动填入到我们刚刚创建的数据库中。

  • 导入notion-client库

    from notion_client import Client
  • 初始化Notion客户端,并获取对应的数据库:

    notion = Client(auth='NOTION_API_KEY')
    database_id = 'NOTION_DATABASE_ID'
    database = notion.databases.retrieve(database_id)
  • 构建新的页面信息:

    如果你有自己的需求,可以通过表格内对应的属性在这边自定义页面

    new_page = {
        "标题": {
            "title": [
                {
                    "text": {
                        "content": title
                    }
                }
            ]
        },
        "中文名": {
            "rich_text": [
                {
                    "text": {
                        "content": name_cn
                    }
                }
            ]
        },
        "话数": {
            "number": episodes
        },
        "评分": {
            "number": rating_sorce
        },
        "放送开始": {
            "date": {
                "start": air_date
            }
        },
        "ID": {
            "rich_text": [
                {
                    "text": {
                        "content": id
                    }
                }
            ]
        },
        "链接": {
            "url": f"https://bangumi.tv/subject/{id}"
        }
    }
  • 将新的页面信息添加到Notion数据库中:

    notion.pages.create(parent={"database_id": database_id}, properties=new_page)

    至此,Python脚本的编写和执行就完成了。可以通过执行脚本来获取Bangumi页面信息并填入到Notion数据库中。

5、测试

将上述两部分代码合到一起,并简单修改成手动输入动画ID,看看能否自动生成表格,还是以《进击的巨人为例》。

运行脚本后,手动输入ID55770,脚本显示已经成功创建页面。

python测试进击的巨人
python测试进击的巨人

notion自动生成进击的巨人页面
notion自动生成进击的巨人页面

可以看到我们需要的信息表格内都已经自动创建好了,测试成功。

总结

由于技术有限,python只是简单自学了一点,使用的很粗糙,这篇文章主要记录了我实现自动输入动画信息这一步骤的思路,希望能抛砖引玉,有大佬能实现完整的自动化,我自己也会继续研究优化...

完整代码

# 目标:
# 1、通过bangumi的api,获取到对应动画的相应数据;
# 2、将对应数据通过notion Api加入数据库中;

import requests
from notion_client import Client

def get_bangumi_info(bangumi_id):
    api_url = f"https://api.bgm.tv/subject/{bangumi_id}"
    response = requests.get(api_url)

    if response.status_code != 200:
        return None

    data = response.json()
    title = data['name']
    name_cn = data['name_cn']
    episodes = data['eps_count']
    air_date = data['air_date']
    rating_sorce = data['rating']['score']
    # large = data['images']['large']
    # grid = data['images']['grid']
    # 你可以根据你的需要获取更多的信息

    # return {'title': title, 'name_cn': name_cn,'episodes': episodes, 'air_date': air_date, 'rating_sorce': rating_sorce, 'large' : large, 'grid' : grid}
    return {'title': title, 'name_cn': name_cn,'episodes': episodes, 'air_date': air_date, 'rating_sorce': rating_sorce}

def notion_page_cheat(info):
    # 初始化Notion客户端
    notion = Client(auth='NOTION_API_KEY')
    database_id = 'NOTION_DATABASE_ID'
    database = notion.databases.retrieve(database_id)

    # 创建一个新的页面
    new_page = {
        "标题": {
            "title": [
                {
                    "text": {
                        "content": info['title']
                    }
                }
            ]
        },
        "中文名": {
            "rich_text": [
                {
                    "text": {
                        "content": info['name_cn']
                    }
                }
            ]
        },
        "话数": {
            "number": info['episodes']
        },
        "评分": {
            "number": info['rating_sorce']
        },
        "放送开始": {
            "date": {
                "start": info['air_date']
            }
        },
        "ID": {
            "rich_text": [
                {
                    "text": {
                        "content": id
                    }
                }
            ]
        },
        "链接": {
            "url": f"https://bangumi.tv/subject/{id}"
        }
    }

    notion.pages.create(parent={"database_id": database_id}, properties=new_page)

    print(f"已成功创建页面:{info['title']}")


id = input("动画ID:")
info = get_bangumi_info(id)

print(info['title']) # 输出 {'标题': title, '中文名': name_cn,'话数': episodes, '放送开始': air_date, '评分': rating_sorce}
notion_page_cheat(info)

参考