最初に
Notion API(公式のもの)を使って何か作りたいということで、Twitterのトレンドを取得して、トレンドのキーワードに関連するツイートを保存するプログラムを作りました。特に意味はありませんw
実際に動かしています→Notionのリンクはこちら
※作成者など、一部の情報が非表示の場合があります。
記事について
簡易な説明または一部のみの説明を行います。コピペのみでは動かない場合があります。全体のコードは、こちらに置いていますが、初心者が書いたので見にくいです。
また、説明用に変更していることがあります。
2022年7月10日現在の動作は確認済みです。
参考程度に参照してください。
開発言語はPythonです。
Notion APIのバージョン
[API Referebce] Versioning
現在のバージョンは2022-06-28ですがこの記事での動作は2022-02-22です。
ヘッダーのバージョン情報を変更することで利用できます。
1.Notion APIを利用するにあたって
インテグレーションの作成方法はここを開く
1-1.APIを利用するには以下のリンクを開きます。
https://www.notion.so/my-integrations
1-2.「新しいインテグレーションを作成する」をクリックする。
ちなみにモバイル画面には対応していないようで非常に見にくいのでPCをオススメするよ!
1-3.基本情報を入力する。
1-4.「送信」ボタンを押す
1-5.トークンを利用します。「表示」を押すと「コピー」できます。
2.利用したいNotionのページを作成・インテグレーションと連携する
「招待」をしたページ以外、プログラムで編集や読み取る権限はないから安心!
2-1.新しいページを作成しましょう!タイトルはなんでもいいよ!
2-2.右上にある「共有」をクリックして「ユーザーやインテグレーションを追加...」をクリック
2-3.作成したインテグレーションがあるので「招待」する
2-4.以下の画像のように追加されていたら準備OK!
3.tweepyを使ってみよう
この記事ではNtion APIがメインですのでTwitter apiの取得の仕方は省略します。
3-1.API連携を行う
import tweepy
cunsumer_key = "access keyを入力"
cunsumer_secret = "access secretを入力"
access_token = "access tokenを入力"
access_token_secret = "access token secretを入力"
# API連携用のコード
auth = tweepy.OAuth1UserHandler(cunsumer_key, cunsumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
3-2.トレンドの一覧取得する
#日本のWOEID
woeid = 23424856
#トレンド一覧取得
trends = API_key.api.get_place_trends(woeid)
trends_top = []
for trend in trends[0]["trends"]:
trends_top.append(trend["name"])
#今回は30件のみにしている
print(trends_top[:30])
結果として
["#トレンド1","#トレンド2",...,"#トレンド30"]
が取得できる。
3-3.ツイートの内容を取得する
tweepyではかなり多くのデータを取得できますが、不必要なデータがたくさんあるので自分の欲しいデータのみに変換しています。
今回利用するツイート内容は以下の通りです。
本文、ユーザーname、ユーザーID、投稿日、リツイート数、いいね数、ハッシュタグ、プロフィール画像、ヘッダー画像、ツイートに含まれる画像(1~4枚)または動画(1本)のURL
import tweepy
import time
def search(search_word=None):
while True:
try:
# 検索条件の設定(リストで渡せば複数指定できる)
search = f"{search_word} -filter:retweets"
tweet_max = 50
# ツイートを取得してtweetsという変数に代入
tweets = tweepy.Cursor(API_key.api.search_tweets, q=search, lang="ja").items(tweet_max)
break
except:
print("ツイートの取得に失敗しました。再度リクエストします")
time.sleep(5)
# 必要な情報のみを格納する箱(=リスト)を作る
tweet_data = {}
tweet_datas = []
# リストに必要な情報を入れていく
for tweet in tweets:
#本文
tweet_data["title"]=tweet.text
#ユーザーname
tweet_data["username"]=tweet.user.name
#ユーザーID
tweet_data["userid"]=tweet.user.screen_name
#投稿日
tweet_data["date"]=str(tweet.created_at)
#リツイート数
tweet_data["retweet_count"]=tweet.retweet_count
#いいね数
tweet_data["favorite_count"]=tweet.favorite_count
#ハッシュタグ
if "hashtags" in tweet.entities.keys():
hashtag_data = {}
hashtags = []
for hashtag in tweet.entities["hashtags"]:
hashtag_data["name"] = hashtag["text"]
hashtags.append(hashtag_data)
hashtag_data = {}
tweet_data["hashtags"] = hashtags
else:
tweet_data["medias"] = []
#プロフィール画像
try:
tweet_data["profile_image"] = tweet.user.profile_image_url_https
except:
tweet_data["profile_image"]="https://img.icons8.com/ios/250/000000/twitter.png"
#ヘッダー画像
try:
tweet_data["banner"]= tweet.user.profile_banner_url
except:
tweet_data["banner"]= "https://img.icons8.com/ios/250/000000/twitter.png"
#media保存
try:
if "media" in tweet.extended_entities.keys():
media = {}
medias = []
for media_url in tweet.extended_entities["media"]:
media["type"] = media_url["type"]
if media["type"] =="video":
try:
video_bitrate = 0
for video_url in media_url["video_info"]["variants"]:
if "bitrate" in video_url.keys():
if video_url["bitrate"] > video_bitrate:
media["URL"] = video_url["url"]
video_bitrate = video_url["bitrate"]
if video_bitrate == 0:
tweet_data["medias"] = []
break
except:
tweet_data["medias"] = []
break
else:
media["URL"] = media_url["media_url_https"]
medias.append(media)
media = {}
tweet_data["medias"] = medias
else:
tweet_data["medias"] = []
except:
tweet_data["medias"] = []
tweet_datas.append(tweet_data)
tweet_data = {}
# 取得したツイートの内容を出力
return tweet_datas
結果の例(データの一部を変更しています)
{
'title': 'トレンド一覧を取得して保存するプログラムを作りました\n #トレンド',
'username': 'テルシバタ',
'userid': 'ffffffffffff',
'date': '2022-07-09 17:37:11+00:00',
'retweet_count': 0,
'favorite_count': 5,
'hashtags': [{
'name': 'トレンド'
}],
'profile_image': 'https://pbs.twimg.com/profile_images/143631243768000000/PFIEFFEFEF_normal.jpg',
'banner': 'https://pbs.twimg.com/profile_banners/12979615240280000000/1634314342',
'medias': [{
'URL': 'https://pbs.twimg.com/media/ffffffffffffff.jpg',
'type': 'photo'
}, {
'URL': 'https://pbs.twimg.com/media/eeeeeeeeeeeeee.jpg',
'type': 'photo'
}, {
'URL': 'https://pbs.twimg.com/media/dddddddddddddd.jpg',
'type': 'photo'
}]
}
4.公式Ntion APIを使ってみよう
requestsとtimeとjson以外のライブラリは利用していません。
以下のコードは必須となります。
import requests #リクエストの際に利用
import time #リクエストする時間を調整するのに利用
import json #json形式に利用
def get_request_url(end_point):
return f'https://api.notion.com/v1/{end_point}'
notion_api_key = "ここにNotionのトークンを貼り付ける"
headers = {"Authorization": f"Bearer {notion_api_key}",
"Content-Type": "application/json",
"Notion-Version": "2022-02-22"}
4-1.ページのデータを取得する
4-1-1.親ページにあるデータベースページを全部取得する
API Referenceはこちらのページとなります。
def getpages(page_id=None):
list = []
datas = {}
start_cursor = None
while True:
if start_cursor is None:
response = requests.request('GET', url=get_request_url(f'blocks/{page_id}/children?page_size=100'), headers=headers)
else:
response = requests.request('GET', url=get_request_url(f'blocks/{id}/children?page_size=100&start_cursor={start_cursor}'), headers=headers)
res = response.json()
for data in res["results"]:
try:
#データベースの場合
datas["title"] = data["child_database"]["title"]
datas["id"] = data["id"]
except:
#データベースではない場合はスキップ
continue
list.append(datas)
datas = {}
time.sleep(0.3)
if not res["has_more"]:
break
else:
start_cursor = res["next_cursor"]
return list
基本的に何ページでも取得できます。1秒に3回以上リクエストするとエラーになるので、少し間隔をあけているので少し時間がかかるかもしれません。
[
{"title":"ページ1","id","c3540e1f-dd03-49e7-9430-1d074d475d2d"},
{"title":"ページ2","id","c3540e1f-dd03-49e7-9430-1d074d475d2e"}
]
4-1-2.データベースページのページを取得する
API Referenceはこちらのページとなります。
def getdatabase(page_id=None):
list = []
datas = {}
start_cursor = None
create_json = {}
while True:
if start_cursor is None:
response = requests.request('post', url=get_request_url(f'databases/{page_id}/query'), headers=headers,json=create_json,data=json.dumps({'page_size': 100}))
else:
response = requests.request('post', url=get_request_url(f'databases/{page_id}/query'), headers=headers,json=create_json,data=json.dumps({'page_size': 100, 'start_cursor': start_cursor}))
res = response.json()
for data in res["results"]:
try:
datas["title"] = data["properties"]["ページタイトル"]["title"][0]["plain_text"]
datas["id"] = data["id"]
except:
continue
list.append(datas)
datas = {}
time.sleep(0.3)
if not res["has_more"]:
break
else:
start_cursor = res["next_cursor"]
return list
今回はタイトルしか使わないので「title」のみですが、データベースページのプロパティ情報は全て取得することができます。
[
{"title":"データベースページ1","id","c3540e1f-dd03-49e7-9430-1d074d475d2d"},
{"title":"データベースページ2","id","c3540e1f-dd03-49e7-9430-1d074d475d2e"}
]
4-2.子要素を追加する
API Referenceはこちらのページとなります。
4-2-1.親ページにヘッダー2を書き込む
def heading_2(block_id=None,content_text=None):
create_json = {"children": [
{
"object": 'block',
"type": 'heading_2',
"heading_2": {
"rich_text": [
{
"type": 'text',
"text": {
"content": content_text,
},
},
],
},
}
]}
requests.request('patch', url=get_request_url(f'blocks/{block_id}/children'), headers=headers, json=create_json)
time.sleep(0.3)
print("ヘッダー2入力完了")
4-2-2.親ページにテキストを書き込む
def text(block_id=None,content_text=None):
create_json = {"children": [
{
"object": 'block',
"type": 'paragraph',
"paragraph": {
"rich_text": [
{
"type": 'text',
"text": {
"content": content_text,
},
},
],
},
}
]}
requests.request('patch', url=get_request_url(f'blocks/{block_id}/children'), headers=headers, json=create_json)
time.sleep(0.3)
print("テキスト入力完了")
4-2-3.区切り線を書き込む
def divider(block_id=None):
create_json = {"children": [
{
"object": 'block',
"type": 'divider',
"divider": {}
}
]}
requests.request('patch', url=get_request_url(f'blocks/{block_id}/children'), headers=headers, json=create_json)
time.sleep(0.3)
print("区切り線の書き込み完了")
4-2-4.親ページに画像を埋め込む
def image(block_id=None,img = None):
create_json ={"children": [
{
"type": "image",
"image": {
"type": "external",
"external": {
"url": img
}
}
}
]}
requests.request('patch', url=get_request_url(f'blocks/{block_id}/children'), headers=headers, json=create_json)
time.sleep(0.3)
print("画像の埋め込み完了")
4-2-5.親ページに動画を埋め込む
def Video(block_id=None,Video = None):
create_json ={"children": [
{
"type": "video",
"video": {
"type": "external",
"external": {
"url": Video
}
}
}
]}
requests.request('patch', url=get_request_url(f'blocks/{block_id}/children'), headers=headers, json=create_json)
time.sleep(0.3)
print("ビデオの埋め込み完了")
4-3.親ページにデータベースページを作成する
API Referenceはこちらのページとなります。
関連ツイートの内容を保存するためのデータベースページを作成するコード
def database(block_id=None,content_text=None):
create_json = {
"parent": {
"type": "page_id",
"page_id": block_id
},
"icon": {
"emoji": "📝"
},
"title": [
{
"type": "text",
"text": {
"content": content_text,
"link": None
}
}
],
"properties": {
"本文": {
"title": {}
},
"ユーザー名": {
"rich_text": {}
},
"ユーザーID": {
"rich_text": {}
},
"投稿日": {
"date": {}
},
"リツイート数": {
"number": {
"format": "number"
}
},
"いいね数": {
"number": {
"format": "number"
}
},
"ハッシュタグ": {
"type": "multi_select",
"multi_select": {
"options": []
}
}
}
}
response = requests.request('post', url=get_request_url('databases'), headers=headers, json=create_json)
time.sleep(0.3)
print(f'{response.json()["id"]}にデータベースを作成しました')
return response.json()["id"]
4-3.データベースページにページを追加する
API Referenceはこちらのページとなります。
def database_page(block_id=None,tweet_data=None):
#tweepyのデータを変換しているだけです
tweet_data["date"] = tweet_data["date"].replace('00:00',"").replace('+',"Z").replace(' ',"T")
create_json = {
"parent": { "database_id": block_id },
"icon": {
"type": "external",
"external": {
"url": tweet_data["profile_image"]
}
},
"cover": {
"type": "external",
"external": {
"url": tweet_data["banner"]
}
},
"properties": {
"本文": {
"title": [
{
"text": {
"content": tweet_data["title"]
}
}
]
},
"ユーザー名": {
"rich_text": [
{
"text": {
"content": tweet_data["username"]
}
}
]
},
"ユーザーID": {
"rich_text": [
{
"text": {
"content": tweet_data["userid"]
}
}
]
},
"投稿日": {
"date": {
"start":tweet_data["date"]
}
},
"いいね数": {
"number": tweet_data["favorite_count"]
},
"リツイート数": {
"number": tweet_data["retweet_count"]
},
"ハッシュタグ": {
"multi_select": tweet_data["hashtags"]
}
}
}
response = requests.request('post', url=get_request_url('pages'), headers=headers, json=create_json)
time.sleep(0.3)
response_id = response.json()["id"]
print(f'{block_id }のデータベースに新しいページを作成しました')
return response_id
最後に
全体のコードを見たい方は以下のリンクからどうぞ
実際に保存しているページは以下のリンクからどうぞ