年も明けたので、Evernoteを卒業します。
Webクリップにもメモにも使えて、できるだけ無料か買い切りで使えて、すぐにサービス終了してしまわなさそうなものを条件として探すと、移行先はほぼNotion一択になるかなぁと思いました。
Notionには公式でEvernoteからのインポート機能があるが、Webクリップや画像のインポートには対応していない。
それ自体はまあ諦めがつくものの、致命的なのは、インポート中にそういうインポートできないノートがあると、コンソールにエラーを吐き捨てて静かに処理を中止してしまうこと。
エラーとなったノートの特定も容易ではない。
この時点でちょっとNotion自体に不安も生じるところではあるが、、まあちょっと諦めずに使ってみることにします。
やること
Evernoteのノートブック単位で、ノートをNotionに一括インポートする。
レイアウトの維持までは期待しないが、メモもWebクリップもインポートできて、画像もあわせて取り込まれること。
幸いにも、非公式なインポートツールを作っている人がいたので利用させていただく。
https://github.com/vzhd1701/enex2notion
※試す場合は自己責任でお願いします
実行環境
Python の実行環境が必要。
Python 3.6 以上と書いているが、手元の環境だと 3.6 で実行したら dataclasses のインポートでエラーになったので、3.7 以上でやるほうがいいかも。
※追記:ツール作者の方からコメントいただき、ツールバージョン v0.2.4 で Python 3.6 対応されているとのこと。
事前準備
- インポート対象のノートブックを enex 形式でエクスポートしておく
- 現在のEvernoteアプリではこのエクスポートができない?らしいので、その場合は Evernote Legacy を使うか、同じ人が作っているevernote-backupを利用できるらしい
- Notionの token_v2 を取得しておく
- このへんを参照
手順
基本的にはツールのREADMEに書いてあるとおりです。
- enex2notion をインストール
- pip を使うなら以下のとおり
$ pip install enex2notion $ enex2notion --version // 0.2.3
- token を指定せずに dry run してみる
$ enex2notion --verbose foo.enex
- エラーにならなければ、token を指定して実行
- warning っぽいものはいっぱい出たが無視した
$ enex2notion --verbose --token [TOKEN] foo.enex
- Notion側で Evernote ENEX Import というノートの下に取り込まれていることを確認する
注意点
- 文章が改行単位でブロックとしてひとつずつ取り込まれるため、長文のメモや、ごちゃごちゃした情報の含まれるWebページのクリップなどは相当な時間がかかる(1ノートで10分以上とか…)
- 公式のインポート機能で事足りるなら、そちらのほうが圧倒的に速い
- 使った感じ、ツールの作りはわりと粗めな印象
- 途中でエラーになると時間がもったいないので、最初に token なしで dry run しておくことをオススメ
- 手元のノートだと以下のようなエラーになるものがあった
- Evernote上でファイルを保存し直してから再実行したらエラーにならなくなった
- ※追記:ツール v0.2.4 で修正されたかも?
ERROR: Unhandled exception while parsing note '[ノート名]'! Traceback (most recent call last): File "path\to\python\current\lib\runpy.py", line 196, in _run_module_as_main return _run_code(code, main_globals, None, File "path\to\python\current\lib\runpy.py", line 86, in _run_code exec(code, run_globals) File "path\to\python\current\Scripts\enex2notion.exe\__main__.py", line 7, in <module> File "path\to\python\current\lib\site-packages\enex2notion\cli.py", line 128, in main cli(sys.argv[1:]) File "path\to\python\current\lib\site-packages\enex2notion\cli.py", line 123, in cli enex_uploader.upload(enex_input) File "path\to\python\current\lib\site-packages\enex2notion\cli.py", line 64, in upload note_blocks = self._parse_note(note) File "path\to\python\current\lib\site-packages\enex2notion\cli.py", line 74, in _parse_note return parse_note( File "path\to\python\current\lib\site-packages\enex2notion\note_parser.py", line 27, in parse_note note_blocks = parse_note_blocks(note_dom) File "path\to\python\current\lib\site-packages\enex2notion\note_parser_blocks.py", line 38, in parse_note_blocks block = _parse_block(child) File "path\to\python\current\lib\site-packages\enex2notion\note_parser_blocks.py", line 77, in _parse_block return tag_parser(element) File "path\to\python\current\lib\site-packages\enex2notion\note_parser_e_table.py", line 9, in parse_table rows = _convert_table_into_rows(element) File "path\to\python\current\lib\site-packages\enex2notion\note_parser_e_table.py", line 26, in _convert_table_into_rows longest_row = max(len(r) for r in rows) ValueError: max() arg is an empty sequence
--done-file
オプションでハッシュ値のファイル出力先を指定し、インポートが中断されたところからリジューム実行できるようなことが書いてあるが、試した限りではいまいち判定がうまく動いてくれず、普通に二重に取り込まれてしまった- なので中断されると再実行が大変なので、安定した回線で、十分な時間のあるときに実行するのがオススメ
備考
このツールはたぶんNotionの非公式APIと呼ばれるものを使っていると思いますが、現在Notionでは公式APIも公開されています。
なのでこの非公式APIがいつまで利用できるかは不明。
公式APIを使って自前でインポートスクリプト書くという手もありかもです。