DeliciousからTumblrに移行
更新(2011/11/22):API 利用に変更が生じたためこの記事は参考程度に留めておいてください。
ソーシャルブックマークの Delicious がサービスを終了するという話があったので、Flickr も然り、Yahoo! に買収されたスタートアップは成長が見込めないという懸念も以前からあったので重い腰を上げて Tumblr へデータを移行することにした。
既に誰かが試みているだろうと調べるとそれらしい記事があったのだけど、Delicious の出力が XML から(タグが閉じられていたりいなかったり、属性が全て大文字だったり)汚い HTM ファイルに変わってたことに加え、Tumblr API の利用制限が考慮されていなかったので、移行ツールを以下の様に自作した。
ini_set('error_reporting', E_ALL); date_default_timezone_set('Asia/Tokyo'); define('FNAME', 'delicious-20101216.htm'); define('EMAIL', 'hkitago@gmail.com'); define('PASSW', '*********'); define('SLEEP_SEC', 10); require('simplehtmldom/simple_html_dom.php'); header('Content-type: text/plain; charset=UTF-8'); parseHTM(); function parseHTM() { $htm = file_get_html(FNAME); $posts = array(); foreach($htm->find('dt') as $dt) { $a = $dt->first_child(); $d = $dt->next_sibling(); $posts[] = array( 'url' => $a->href, 'name' => trim($a->innertext), 'tags' => $a->tags, 'date' => date("Y-m-d H:i:s", $a->add_date), 'private' => $a->private, 'description' => (is_object($d) && $d->tag == 'dd') ? trim(strip_tags($d->innertext)) : null ); } $time_start = microtime(true); foreach($posts as $value) { postToTumblr($value['url'], $value['name'], $value['description'], $value['tags'], $value['date'], $value['private']); if(microtime(true) - $time_start > 10) { sleep(SLEEP_SEC); $time_start = microtime(true); } } } function postToTumblr($url, $name, $description, $tags, $date, $private) { $tumblr_email = EMAIL; $tumblr_password = PASSW; $post_type = 'link'; $post_generator = 'Delicious'; $post_url = $url; $post_description = $name; $post_tags = $tags; $post_date = $date; $post_extended = $description; $post_private = $private; $request_data = http_build_query( array( 'email' => $tumblr_email, 'password' => $tumblr_password, 'type' => $post_type, 'description' => $post_extended, 'generator' => $post_generator, 'date' => $post_date, 'url' => $post_url, 'tags' => $post_tags, 'name' => $post_description, 'private' => $post_private ) ); $c = curl_init('http://www.tumblr.com/api/write'); curl_setopt($c, CURLOPT_POST, true); curl_setopt($c, CURLOPT_POSTFIELDS, $request_data); curl_setopt($c, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($c); $status = curl_getinfo($c, CURLINFO_HTTP_CODE); curl_close($c); if ($status == 201) { echo "Success! The new post ID is $result"."\n"; } else if ($status == 403) { echo 'Bad email or password'; } else { echo "Error: $result"."\n"; } }
Delicious から出力した HTM ファイルと上記の PHP ファイル、それに HTML 解析ツールとしてPHP Simple HTML DOM Parser を適当な場所に置いて実行するだけで2005年辺りから保存していた4,151件分のデータを無事に移行することができた。所要時間を具体的に計測していないのだけど、10秒間に100件ほど処理できていた気がする。
サンプルのコードを利用する際は先頭の7行を環境に応じた値に適宜変更することと、あまりにもデータ量が多いと php.ini の設定次第では “[notice] child pid ***** exit signal Segmentation fault (11)” を出力し行末に達せず完了しない場合があるので、postToTumblr 関数を実行する前に var_dump 関数等で確認しておくと良いかと。

ってな訳で、タンブラ始めましたのでよろしくお願いします。
P.S. リンク先のページが存在するかどうか確認するようにすれば良かったなとチョット後悔。
コメントは受け付けていません。






フリーランスのウェブとiOSアプリ開発者で一児の父親。JavaScript, ActionScript, AppleScript, PHP, SQL, ObjCの読書実行試験運用管理を生業とし、BIND, SMTP, APACHE を MacBSD, FreeBSD, Mac OS X で使い、エディタは Vi, mi, Kod と遷移して現在は Smultron、そして Coda と Xcode の IDE を重用しています。作業の自動化や効率化の導入を応援しています。