DiigoからRaindrop.ioへPandasを使って移行した話

ブックマークサービスの移行について

自分は基本的にWebサイトのブックマークはWebサービスを利用するようにしているのですが、長らくその目的にDiigoを利用していました。

www.diigo.com

日本ではオンラインブックマークサービスとしては圧倒的にはてなブックマークが有名ですが、はてなに無い機能として「ブックマークしたWebページにハイライトやメモの追加を行うことができる」というものがあり、これが便利だったのではてなから乗り換えました。

課金も行って便利に使っていたDiigoですが、近年は開発が停滞しているように見受けられ(ブログも5年ほど更新されてしません)、将来性が不安になってきていました。 そんなところに次のRaindrop.ioというオンラインブックマークサービスがあることを知りました。

raindrop.io Raindrop.ioは次のような特徴を持つオンラインブックマークサービスです。

  • Diigoと同様、ブックマークしたWebサイトに対して文章にハイライトを引いたり、メモを記入することができる
  • ブックマークはコレクション(フォルダと同義)とタグという2種類の整理方法がある
    • Diigoはタグのみで、エントリ数が多くなると散らかってしまう傾向があったが、こちらはコレクションで大まかに整理した上でタグ付けして詳細を探すような使い方ができる *1
  • ブックマークの内容を分析して自動的にカテゴリ分けしてくれる機能もある
  • Webブラウザ向け拡張機能やモバイルアプリケーションももちろん提供している
    • Diigoのモバイルアプリはブラウザが前面に出てくるインターフェースだったのが使い辛かった

総じてDiigoの機能は全て保持しており、開発も盛んに行われている印象だったので乗り換えてみることにしました。

どのようにしてデータを移行するか

乗り換えるためにはデータの移行が必要です。可能ならば次の情報を持っていきたいと考えていました。

  • URL
  • ブックマークタイトル
  • エントリに対して自分が記入した説明
  • ブックマークに付けたタグ
  • ブックマークした日時
    • Webサイトの情報は陳腐化が激しいのでいつブックマークしたかの情報は重要

さすがにWebページのハイライトやノートの情報までは持っていくことは考えませんでした。

Diigo側では次のような形式でデータのエクスポートが可能でした (Diigoのエクスポートページ) 。

エクスポート形式 出力する内容
IEブックマーク URL、タイトル
Firefoxブックマーク URL、タイトル、タグ
RSS URL、タイトル、説明、タグ、Webページのハイライトやメモの情報
CSV URL、タイトル、説明、タグ、Webページのハイライトやメモの情報
Chromeブックマーク形式 URL、タイトル (今は亡きdel.icio.us互換らしい)

一番情報量が多いのはRSSCSVのようです。

一方Raindrop.io側では次のような形式でのインポートが可能です (Raindropのインポート形式についての説明) 。

というわけで多くの情報を持っていくにはCSVで移行するのが一番良さそうだと分かりました。

Pandasを使ってCSVのフォーマットを合わせる

DiigoからエクスポートしたCSVは次のようなカラム構成でした。

カラム名 内容
title ブックマークタイトル
url ブックマークのURL
tags ブックマークに付けられたタグ
description ブックマークに付けた説明文
comments Webページに添付したノート
annotations WebページのハイライトをHTMLとして出力している
createt_at ブックマーク作成日時をUTCで出力 (%Y-%m-%d %H:%M:%S フォーマット)

一方Raindrop.io側はインポートするCSVのカラム構成を次のように定めています。 カラム順は問わず、必須なのは url カラムのみです。

カラム名 内容
url ブックマークのURL
folder ブックマークが保存されているフォルダー
url ブックマークのURL
note ブックマークに付けられた説明文
tags ブックマークに付けられたタグ
created ブックマーク作成日時をUNIXタイムスタンプもしくはISO8601形式で

Diigoから出力されたCSVから次のような変換を行う必要がありますね。

  • comments 及び annotations カラムを削除
  • カラム名 descriptionnote にリネーム
  • カラム created_at の日時文字列をISO8601形式に変換する
  • カラム名 created_atcreated にリネーム

Pandasを使ってこの変換処理を行いました。Jupyter Notebookを使って実行しています。Jupyterは動かした結果をその場で見ながら試行錯誤できて便利ですね。

まずCSVをPandasを使って読み込みます。UTF-8CSVなのでそのまま読み込めます。

df = pd.read_csv("<path to input CSV>")

日時のフォーマットを変換します。まずは created_at カラムを datetime 型に変換します。

df["converted_dt"] = pd.to_datetime(df["created_at"], errors="coerce", utc=True)

Pandasは日付っぽい文字列に対してフォーマットを指定せずともある程度よろしく解釈してくれます。時刻はUTCなので utc=True を指定しています。

今度はISO8601形式の文字列に変換します。Raindropが要求するカラム created に出力します。

df["created"] = df["converted_dt"].dt.strftime("%Y-%m-%dT%H:%M:%SZ")

次にカラム名のリネームをします。

df = df.rename(columns={"description": "note"})

最後に必要なカラムだけを選択して、出力用DataFrameを作成し、CSVファイルとして出力します。

output_df = df[["url", "title", "note", "tags", "created"]]
output_df.to_csv("<path to output CSV>", index=False, quoting=csv.QUOTE_NONNUMERIC)

文字列には改行も入っているのでCSVのクォートは csv.QUOTE_NONNUMERIC を指定しました。

このファイルをRaindrop.ioに読み込ませると無事インポートに成功しました!

Diigoではこうだったのが...

Raindrop.io側にこのようにちゃんと引き継がれました。タグや登録日時の情報も引き継がれています。

*1:Diigoアウトライナー機能を提供しており、アウトライナーで整理してもらうという方針でしたが、このやり方は手軽ではなかったですね