0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Notion API 使ってみた ~Twitterトレンド保存~

Posted at

最初に

Notion API(公式のもの)を使って何か作りたいということで、Twitterのトレンドを取得して、トレンドのキーワードに関連するツイートを保存するプログラムを作りました。特に意味はありませんw
実際に動かしています→Notionのリンクはこちら
※作成者など、一部の情報が非表示の場合があります。
image.png
image.png

記事について

簡易な説明または一部のみの説明を行います。コピペのみでは動かない場合があります。全体のコードは、こちらに置いていますが、初心者が書いたので見にくいです。
また、説明用に変更していることがあります。

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をオススメするよ!

image.png

1-3.基本情報を入力する。

image.png
image.png

1-4.「送信」ボタンを押す

image.png

1-5.トークンを利用します。「表示」を押すと「コピー」できます。

image.png

2.利用したいNotionのページを作成・インテグレーションと連携する

「招待」をしたページ以外、プログラムで編集や読み取る権限はないから安心!

2-1.新しいページを作成しましょう!タイトルはなんでもいいよ!

image.png

2-2.右上にある「共有」をクリックして「ユーザーやインテグレーションを追加...」をクリック

image.png

2-3.作成したインテグレーションがあるので「招待」する

image.png

2-4.以下の画像のように追加されていたら準備OK!

image.png

3.tweepyを使ってみよう

この記事ではNtion APIがメインですのでTwitter apiの取得の仕方は省略します。

3-1.API連携を行う

API_key.py
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.トレンドの一覧取得する

trends.py
#日本の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

tweet_search.py
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はこちらのページとなります。

notion_search.py
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はこちらのページとなります。

notion_search.py
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を書き込む

notion_create.py
  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.親ページにテキストを書き込む

notion_create.py
  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.区切り線を書き込む

notion_create.py
  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.親ページに画像を埋め込む

notion_create.py
  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.親ページに動画を埋め込む

notion_create.py
  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はこちらのページとなります。

関連ツイートの内容を保存するためのデータベースページを作成するコード

notion_create.py
  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はこちらのページとなります。

notion_create.py
  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

最後に

全体のコードを見たい方は以下のリンクからどうぞ

実際に保存しているページは以下のリンクからどうぞ

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?