Qiita に投稿していた記事を Hugo に移行してみた

これまで技術的なことは Qiita に書いていたのですが、アウトプットする場所がバラバラだと色々面倒だと思ったので、 Qiita の記事をこのブログ (Hugo) に持ってきました。
今回はその方法についてです。

やりたいこと

  • Qiita の記事から Hugo 用の markdown を作る
  • Qiita 記事内の画像も移行する
  • なるべく手は加えたくない (全く加えないのは無理でした)

やったこと (概要)

  1. Qiita API で記事の情報を取得
  2. 取得した記事内の画像を保存
  3. 取得した記事を Hugo 用に加工

やったこと (詳細)

1. Qiita API で記事の情報を取得

まず、Qiita から記事の内容を取得します。
幸いにも Qiita には、投稿や編集、記事一覧取得などの API が公開されているので、それを使います。

その前に、 Qiita のマイページからアクセストークンを発行しておきます。

CreateQiitaAccessToken

スコープについては、 read_qiita だけで OK です。

使う API は GET /api/v2/authenticated_user/items です。
公式ページにもありますが、パラメータは下記の通りです。

  • page
    • ページ番号 (1から100まで)
    • Example: 1
    • Type: string
    • Pattern: /^[0-9]+$/
  • per_page
    • 1ページあたりに含まれる要素数 (1から100まで)
    • Example: 20
    • Type: string
    • Pattern: /^[0-9]+$/

指定しない場合は、どちらも Example の値が使用されます。
今回、移行の対象となる Qiita の記事数は 41 だったので、 per_page100 を指定してコールします。

これまた公式の例のままですが、下記のようなレスポンスが返ってきます。

[
  {
    "rendered_body": "<h1>Example</h1>",
    "body": "# Example",
    "coediting": false,
    "comments_count": 100,
    "created_at": "2000-01-01T00:00:00+00:00",
    "group": {
      "created_at": "2000-01-01T00:00:00+00:00",
      "id": 1,
      "name": "Dev",
      "private": false,
      "updated_at": "2000-01-01T00:00:00+00:00",
      "url_name": "dev"
    },
    "id": "4bd431809afb1bb99e4f",
    "likes_count": 100,
    "private": false,
    "reactions_count": 100,
    "tags": [
      {
        "name": "Ruby",
        "versions": [
          "0.0.1"
        ]
      }
    ],
    "title": "Example title",
    "updated_at": "2000-01-01T00:00:00+00:00",
    "url": "https://qiita.com/yaotti/items/4bd431809afb1bb99e4f",
    "user": {
      "description": "Hello, world.",
      "facebook_id": "yaotti",
      "followees_count": 100,
      "followers_count": 200,
      "github_login_name": "yaotti",
      "id": "yaotti",
      "items_count": 300,
      "linkedin_id": "yaotti",
      "location": "Tokyo, Japan",
      "name": "Hiroshige Umino",
      "organization": "Increments Inc",
      "permanent_id": 1,
      "profile_image_url": "https://si0.twimg.com/profile_images/2309761038/1ijg13pfs0dg84sk2y0h_normal.jpeg",
      "twitter_screen_name": "yaotti",
      "website_url": "http://yaotti.hatenablog.com"
    },
    "page_views_count": 100
  },
  {
    //...
  }
]

これをもとに、 Hugo 用の markdown ファイルを生成します。

2. 取得した記事内の画像を保存

加工する前に、記事内の画像データを保存します。移行後には Qiita の記事は削除する予定なので。
Qiita 記事内の画像ファイルは、下記のような形になっています。

<img width="\d+" alt=".+" src=".+">

src にはフルパスが入っているので、そこから画像を保存してきます。
また、 alt にはアップロードしたときのファイル名が入っているようなので、この部分も変更するようにします。

保存する際のファイル名は、 src の値の最後の / 以降 とすると、重複なく保存できます。
新たな alt 属性として、保存時のファイル名を設定するようにします。

後に紹介するスクリプト内の話になりますが、 元の src と 新しい src、元の alt と 新しい alt の情報を保持しておいて、次の加工ステップでそれぞれ置換します。

3. 取得した記事を Hugo 用に加工

加工と言っても、ほとんどすることはありません。
なぜなら、 Qiita API で取得した状態で記事の内容は markdown になっているからです。

なので、あとは記事のタイトルとかカテゴリとかの情報を先頭に付与するだけです。
具体的には、下記のような情報を追加します。

---
title: "{title}"
date: {date}
draft: false
categories: {tags}
tags: {tags}
eyecatch: "images/eyecatch-default.png"
---

API から返却される json は記事情報のリストになっているので、各記事情報 (post) に対して

  • {title} : post.title
  • {date} : post.date
  • {tags} : post.tags のリストをゴニョゴニョする

で取得します。

で、記事本文は post.body なので、この値に対して、画像ファイルのパス、alt 属性を置換します。

あとは、記事のタイトルをファイル名として使用できるように適宜加工して、 {title}.md という形で保存すれば完成です。

Qiita から Hugo 用の markdown を生成するやつ

ということで、上で説明したことをやってくれるスクリプトを作りました。

Python3.6 での動作を想定してますが、標準ライブラリのみなので、他のバージョンでも動くと思います。試してませんが。

このごろ何かと話題の Qiita ですが、 API がしっかり用意されているので、他ブログへの移行や、他ブログからの移行も比較的やりやすい気がします。

comments powered by Disqus