いっしきまさひこBLOG

AI・機械学習関連、Web制作関連、プログラミング関連、旅行記録などなど。一色政彦。

Windows 11でのエンダッシュとエムダッシュの入力方法と、各ハイフン&ダッシュ文字の違いと使い分け

社内文書やメールなどを書いている時、あるいは日々のチャットAIへの入力で、「-」というキーを打つことは多いですよね。

  1. 「state-of-the-art」と書くときの「-」
  2. 「10–20ページ」と書くときの「–」
  3. 「彼は言った―」と書くときの「―」

これらすべて、キーボード右上の「-」キー(ハイフンマイナス)で済ませていないでしょうか? 通常はそれでOKですが、3つ目は日本語の全角ダッシュなので「だっしゅ」とIMEで入力して変換すると入力できます。取りあえずそのルールだけ覚えていれば、通常は問題が起きないはずです。

しかし実は、これらの「横棒」にはそれぞれ異なる意味と役割があり、タイポグラフィ(文字組版)の世界では厳密に使い分けられています。特に英語圏ではエンダッシュ(–)とエムダッシュ(—)を入力して使い分ける場合があり、macOSではこれらを以下のショートカットキーで入力できます。

  • エンダッシュ (–): Option + - (ハイフンキー)
  • エムダッシュ (—): Option + Shift + - (ハイフンキー)

このような状況なので「Windowsでは入力できない」という不満が各所で挙がっていました。そこで、Windows 11では、これらの記号を以下のショートカットキーで簡単に入力できるようになりました。

  • エンダッシュ (–): Windows + - (ハイフンキー)
  • エムダッシュ (—): Windows + Shift + - (ハイフンキー)

入力方法も似ているのでこれなら覚えやすいですね。しかし入力できたとしても、どんなときにこれらを使うか分からないと思います。私も普段使っていないので調べながらでないと分かりません。

ということでこの記事では、似て非なる「ハイフン系」の記号たちを整理し、Windows 11での入力方法と、シーン別のベストプラクティス(使い分けの指針)を解説します。

1. 似ている「横棒」たち 比較表

まずは、「横棒」で表現される代表的な記号(文字)たちを整理してみましょう。

  記号 名前 (Unicode) 主な役割 Windows 11での入力(一例)
- ハイフンマイナス (U+002D) 【兼用】単語連結、マイナス代用。(キーボードから直接入力する基本の文字) - キー(右上にある「ほ」のキー)
エンダッシュ (U+2013) 【英語】範囲、期間、関係性 (例: 10–20) [Windows] + [-] (※1)
エムダッシュ (U+2014) 【英語】補足、中断、強調 (例: —like this—) [Windows] + [Shift] + [-] (※1)
日本語のダッシュ (U+2015) 【日本語】補足、副題、区切り 「だっしゅ」と入力して変換
マイナス記号 (U+2212) 【数学】本物の引き算記号 (例: $10 − 5$) 「まいなす」と入力して変換
上付きマイナス (U+207B) 【数学】指数の負号 (例: 10⁻³) 「うえつき」などで変換
長音符号 (U+30FC) 【日本語】音を伸ばす (例: ラーメン) 日本語入力状態で「-」キー(「ほ」のキー)
波ダッシュ (U+301C) 【日本語】範囲、柔らかい表現 (例: 10時~) 日本語入力状態で「~」キー(Shift + 「へ」のキー)

(※1) メインキーボードの - キー(テンキー不可)

2. 各記号の役割と Windows 11 での入力方法

① ハイフン(ハイフンマイナス, U+002D)

私たちがキーボードで [-] キーを押したときに入力される、最も身近な記号です。

本来の「ハイフン」と「マイナス」の役割を兼用するために用意された、コンピュータ用の文字です。

  • 役割: 単語の連結(複合語)、行末での単語の分割、マイナス記号の代用。
  • 入力: - キー(「ほ」のキー、またはテンキーの -
  • 使用例:

    state-of-the-art (複合語の連結) e-mail (単語の連結) 10 - 5 = 5 (マイナス記号の代用)

Unicodeでは U+002D、Shift_JISでは(ASCIIコードと同じ)2D(16進数)として扱われます。

② エンダッシュ (En Dash, U+2013)

「N」の文字幅に由来するダッシュです。主に英語圏で、「範囲」や「関係性」を示すために使われます。

  • 役割: 「...から...まで」という範囲、期間、関係性。
  • 入力: [Windows] + [-] キー
  • 使用例:

    pages 10–20 (10ページから20ページまで) May–August (5月から8月まで) the East–West conflict (東西対立)

③ エムダッシュ (Em Dash, U+2014)

「M」の文字幅に由来する、エンダッシュより長いダッシュです。主に英語圏で、文章の流れを強く「中断」したり「補足」したりするために使われます。

括弧 () やコロン : に近いですが、より強調したい、あるいは感情的な中断を示したい場合に使われます。

  • 役割: 文中の挿入、補足、思考の中断、会話の遮り。
  • 入力: [Windows] + [Shift] + [-] キー
  • 使用例:

    He finally answered—after a long pause—that he agreed. (彼は—長い沈黙の後—同意すると答えた。)

④ 日本語のダッシュ (Horizontal Bar, U+2015)

私たち日本人が「ダッシュ」と聞いて想像するのがこれです。全角幅を持ち、機能的には英語のエムダッシュ (—) とほぼ同じです。

  • 役割: 補足、説明、言い換え、副題。
  • 入力: 「だっしゅ」と入力して変換
  • 使用例:

    特集 ― 春の新生活 (副題として) 彼は言った―「もう帰る」と。 (会話や引用の区切りとして) この記事で紹介したショートカット―Windows 11の機能―は便利だ。 (補足・言い換えとして)

Unicodeでは U+2015、Shift_JISでは 815C(16進数)として扱われます。

⑤ (本物の)マイナス記号 (Minus Sign, U+2212)

これは数学の「引き算」専用の記号です。

キーボードのハイフンマイナス (-) との違いは、+(プラス記号)とデザイン的なバランス(高さや太さ)が揃うように設計されている点です。

  • 役割: 数学的な引き算。
  • 入力: 「まいなす」と入力して変換 (MS-IMEなど)、またはWordなどの自動変換
  • 使用例:

    10 − 5 = 5 (ハイフンマイナスより中央に配置されます)

Unicodeでは U+2212、Shift_JISでは 817C(16進数)として扱われます。

【※補足:入力と判別の難しさ】 この記号の入力は厄介です。

  • MS-IMEでは「まいなす」と変換すると候補に出ますが、フォントによっては「-」(ハイフンマイナス)との見た目での区別が非常に困難です。
  • ATOKなどの一部IMEでは、「まいなす」と変換しても候補に表示されない場合があります。この場合は文字パレットで[コード]に「2212」と指定すると入力できます。
  • 見分け方のヒント: +(プラス記号)と並べてみてください。10 + 510 − 5 のように、横棒の高さが揃っていれば、それは「本物のマイナス記号」である可能性が高いです。

⑥ 上付きマイナス (Superscript Minus, U+207B)

記号:

これは、文字の上部(上付き文字の位置)に表示される小さなマイナス記号です。

  • 役割: LaTeXやHTMLの <sup> タグが使えないプレーンテキスト(SNSやチャットなど)で、¹ ² ³ といった他の上付き文字と組み合わせて、指数の負号(マイナス乗)を示すために使われます。
  • 入力: 「まいなす」などで変換(IMEによる)、または文字コード表(文字パレット)から 207B を指定。
  • 使用例:

    10⁻³ (10のマイナス3乗)

Unicodeでは U+207B として定義されています(Shift_JISの標準的なコード範囲には含まれません)。

⑦ 長音符号 (Prolonged Sound Mark, U+30FC)

記号:

これは日本語のカタカナやひらがなで「音を伸ばす」ために使われる記号です。ご指摘の通り、日本人が語尾を伸ばす際はこちらを使います。全角の「日本語のダッシュ (―)」とよく似ていますが、役割が全く異なります。

  • 役割: 日本語の長音(伸ばす音)。
  • 入力: 日本語入力状態で「-」キー(「ほ」のキー)
  • 使用例:

    ラーメン コンピューター なるほどー

Unicodeでは U+30FC、Shift_JISでは 815B(16進数)として扱われます。

⑧ 波ダッシュ (Wave Dash, U+301C)

記号:

これは日本語特有の記号で、主に範囲を示したり、リラックスしたニュアンスを出したりするために使われます。

  • 役割: 範囲(...から...まで)、または柔らかい表現。
  • 入力: 日本語入力状態で「~」キー(Shift + 「へ」のキー)、または 「から」と入力して変換
  • 使用例:

    10時~11時 (範囲) 東京~大阪 (区間) ですよね~ (語尾のニュアンス)

Unicodeでは U+301C、Shift_JISでは 8160(16進数)として扱われます。

3. 結局どう使い分ける? シーン別ベストプラクティス

これだけ種類があると混乱してしまいますが、TPO(時と場合)で使い分けるのが現実的です。

ケース1:日常のブログ記事、Web記事、メール

結論:基本的に「ハイフンマイナス (-)」で問題ありません。

  • state-of-the-art は?
    • ハイフン (-) を使います。これは連結なので、エンダッシュ (–) やエムダッシュ (—) を使うのは誤りです。
  • 「10時~11時」や「10-20ページ」は?
    • ハイフン (-) で代用して 10-20 と書くのが一番手っ取り早く、Webでは一般的です。
    • → 日本語なら (波ダッシュ) を使う 10時~11時 の方が一般的です。
    • → 英語でこだわるなら、エンダッシュ (–) を使い 10–20 と書くとプロフェッショナルに見えます。
  • 引き算 10 - 5 は?
    • ハイフン (-) でOKです。前後にスペースを入れると、ハイフンマイナスでも読みやすくなります。

ケース2:プロの出版物、学術論文(特に英語)

結論:スタイルガイドに従い、厳密に使い分けます。

『The Chicago Manual of Style』(シカゴ・マニュアル・オブ・スタイル)やAPA(アメリカ心理学会)スタイルなど、分野ごとの厳格なルールブックに従い、エンダッシュとエムダッシュを正確に使い分けることが求められます。

ケース3:日本語の文章で「補足」を入れたい

結論:「日本語のダッシュ (―)」を使いましょう。

英語のエムダッシュ (—) を使う必要はありません。「だっしゅ」と変換して出てくる全角の を使うのが、日本語の文章として最も自然です。また、(全角ダッシュ)や(三点記号)は――……のように2つセットで使うのが、商業メディアでは一般的です。

例: 彼は言った「もう帰る」と。

おまけ:ChatGPT とエムダッシュ

最近のAI(特にChatGPT)は、文章の補足として英語の「エムダッシュ (—)」を多用するクセが指摘されています。

We found the key — a rusty old skeleton key — under the mat.

これが不自然だと感じるユーザーも多く、OpenAIのサム・アルトマン氏が「カスタム指示で『em-dashを使わないで』と指示すれば、言うことを聞くようになっている」と2025年11月14日にポストしているほどです。 AIも、この使い分けには苦労している(あるいはこだわりすぎている)のかもしれませんね。

まとめ

Windows 11の [Windows] + [-][Windows] + [Shift] + [-] といったショートカットは、これまでIMEの変換や文字コード表からしか入力できなかった記号を呼び出す、非常に便利な機能です。これらの記号を使いこなせると、プロフェッショナルな印象になります。ぜひ一度、キーボードで試してみてください。

SmartURLs ― 複数URLをスマートにコピー&オープンできる拡張機能

調べものやライティング、コーディング、編集作業など、オンラインで仕事をしていると、いつの間にかブラウザのタブが大量に開いてしまうことがあります。
それらのURLをまとめてコピーしたり、管理したりするのは意外と面倒ですよね。

そこで私は、複数のURLをすばやく・柔軟に・安全に扱える軽量Chrome拡張機能SmartURLs(スマート・ユアールエルズ)を開発しました。🚀

SmartURLs Screenshot

💡 SmartURLsでできること

SmartURLsは、日常的によくある2つの作業をぐっと簡単にします。

1. 開いているタブのURLを一括コピー

現在のウィンドウ、またはすべてのウィンドウのURLを一瞬で取得し、以下の形式で書き出せます。

  • Markdown
  • HTML
  • JSON
  • TSV(タブ区切り)
  • あるいは独自のテンプレート形式

さらに、ピン留めタブを除外したり、重複を省いたり、HTTPSのみを抽出したりといった細かいフィルタリングにも対応しています。

2. 複数のURLを一括で開く

テキスト内に含まれるURL(Markdown、HTML、プレーンテキストなど)をペーストすれば、すべてのリンクをワンクリックで開けます。
Smart Parserが自動で形式を判別してくれるので、面倒な設定は不要です。

💭 開発のきっかけ

私はWebライター兼エンジニアとして、日々多くのページを調べたり、URLを集めたりしています。
その中で、「自分の使い方にぴったり合う拡張機能がなかなか見つからない」と感じていました。

そこで、自分が本当に欲しかったツールを作ることにしたのです。

目指したのは、こんな拡張機能です。

  • ✨ 軽快でシンプルに動く
  • 🔒 通信を一切しない(完全ローカル処理)
  • 🌍 英語・日本語など多言語対応
  • 🔧 オープンソースで公開

🎨 シンプルで見やすいUI

SmartURLsは、ライト/ダーク/システムテーマに対応したレスポンシブなポップアップUIを採用しています。
設定はChrome Storageに自動保存され、初期設定も不要です。

SmartURLs Popup (Dark)

SmartURLs Popup (Light)

⚙️ 主な特徴

  • 🌐 複数URLをワンクリックでコピー&オープン
  • ✨ 出力テンプレートをカスタマイズ可能
  • 🌓 ライト/ダーク/システムテーマ対応
  • 🗣 16言語対応
  • 🔒 完全オフライン動作(データは外部に送信されません)
  • 🔓 オープンソース(Apache License 2.0)

📦 インストール方法

Chrome ウェブストアからインストール
👉 SmartURLs – Copy & Open URLs

GitHub から手動インストール
👉 isshiki/SmartURLs on GitHub

💬 おわりに

SmartURLsは「なんでもできる万能ツール」を目指していません。
その代わり、「リンクを扱う手間をなくすこと」だけに集中しています。

URLのコピーや一括オープンを、もっとスマートに、もっとストレスなく。

SmartURLs は、あなたの作業を少しだけ軽くしてくれる小さな相棒になるかもしれません。

SmartURLs: A Smarter Way to Copy and Open URLs

When you work online—researching, writing, coding, or editing—you probably have a browser full of tabs.
Copying and managing those URLs can be a pain.

That’s why I built SmartURLs, a lightweight Chrome extension that makes copying and opening multiple URLs fast, flexible, and private. 🚀

SmartURLs Screenshot

💡 What SmartURLs Does

SmartURLs simplifies two everyday tasks:

1. Copy all open tabs instantly

Export your current or all-window tabs in multiple formats:

  • Markdown
  • HTML
  • JSON
  • TSV
  • Or your own custom text template

You can even filter results—skip pinned tabs, remove duplicates, or include only HTTPS links.

2. Open multiple URLs at once

Paste any text containing URLs (Markdown, HTML, plain text, etc.) and open them all in one click.
Smart Parser automatically detects the format so you don’t have to.

💭 Why I Created It

As a web writer and developer, I often needed to collect, copy, and reopen many URLs quickly.
But I couldn’t find an existing extension that perfectly fit my workflow — either too complex, too limited, or just not quite right for everyday use.

So I decided to build the tool I truly wanted to use myself.

Here’s what I aimed for:

  • ✨ Fast and lightweight
  • 🔒 100% local (no network requests)
  • 🌍 Multilingual (English, Japanese, and more)
  • 🔧Fully open-source

🎨 Designed for Clarity

SmartURLs has a clean, responsive popup UI with Light/Dark/System themes.
Settings are saved automatically via Chrome Storage — no setup required.

SmartURLs Popup (Dark)

SmartURLs Popup (Light)

⚙️ Key Features

  • 🌐 Copy or open multiple URLs in one click
  • ✨ Custom export templates
  • 🌓 Light / Dark / System themes
  • 🗣 16 languages supported
  • 🔒 Works completely offline — your data never leaves the browser
  • 🔓 Open-source (Apache License 2.0)

📦 Installation

From the Chrome Web Store:
👉 SmartURLs – Copy & Open URLs

From GitHub (Manual Installation):
👉 isshiki/SmartURLs on GitHub

💬 Final Thoughts

SmartURLs doesn’t try to be an all-in-one manager.
It focuses on what matters: making link handling effortless.

If you ever wished copying or reopening URLs could be just one click away,
SmartURLs might become one of those small tools you can’t work without.

PromptLinker ― ChatGPT・Claude・Perplexityに“一発で飛べる”プロンプトリンク生成ツール

プロンプトを入力してリンクを生成する画面

AIに質問するとき、毎回ブラウザを開いて、テキストをコピペして……という手間を感じたことはありませんか? PromptLinker は、そんな煩わしさを一瞬で解消するシンプルなWebツールです。 入力したプロンプトを自動的にエンコードして、ChatGPT/Claude/Perplexity へ直接飛べるリンクを生成します。

機能概要

  • 入力した文章を RFC 3986 準拠 で自動エンコード
  • ChatGPT/Claude/Perplexity に対応(3サービス同時生成)
  • 改行(%0A)も正確に保持
  • クライアントサイドで完結(サーバ不要・ログも残らない)

使い方

  1. PromptLinker(Web版) にアクセス
  2. テキストエリアにプロンプトを入力
  3. 「生成する」ボタン、または Shift + Enter でリンクを作成
  4. 表示された各サービスのボタンからワンクリックで遷移

シンプルな仕組みですが、一度使うともう戻れない快適さがあります。

仕組みの概要

PromptLinkerは、入力されたテキストをURLクエリとして渡すために、 JavaScriptの標準関数 encodeURIComponent() を使って RFC 3986形式でエンコード しています。

  • 英数字と - . _ ~ はそのまま使用
  • 改行は %0A に変換
  • それ以外の文字はすべて安全にエスケープ

この形式で生成されたURLを、それぞれのAIサービスに埋め込みます。 なお、Geminiについては現時点でURLクエリによるプロンプト渡しができないため、対応を見送っています。

導入方法

ブラウザだけで動作するため、インストールは不要です。 以下のURLにアクセスすればすぐに利用できます。

https://isshiki.github.io/PromptLinker/

ローカルで使いたい場合は、GitHubリポジトリから index.html をダウンロードして、 任意の場所で開くだけで動作します。

開発メモ

  • 構成:HTML/CSS/JavaScript のみ(単一ファイル構成)
  • デプロイ:GitHub Pagesで main ブランチのルートを公開すれば利用可能
  • ソースコード:GitHubリポジトリはこちら

まとめ

AIを使う頻度が増えるほど、「プロンプトを渡すまでの数秒」が意外とストレスになります。 PromptLinkerは、その数秒を短縮する小さなツールですが、毎日の作業効率を確実に変えてくれます。

ChatGPTやClaude、Perplexityを日常的に使う人なら、ブックマークしておいて損はありません。

Gartner風「ハイプ・サイクル」曲線をPythonで描く ― hype-cycle-curve 公開

hype_cycle_with_labels.svg

新しいAI技術やトレンドを可視化する際によく登場する「ハイプ・サイクル(Hype Cycle)」。 あのガートナーのグラフを、自分で描けたら便利だと思ったことはありませんか?

そんな方のために、Pythonだけで簡単にハイプ・サイクル曲線を描けるツールを作りました。 👉 GitHub: isshiki/hype-cycle-curve

🎨 特徴

  • CSVデータ(x,y)からスムーズな曲線を自動生成
  • フェーズ分割の縦線(期待のピーク、幻滅期など)を追加可能
  • マーカーやラベルを自由にカスタマイズ(色・サイズ・位置など)
  • 日本語フォント対応(matplotlib-fontja
  • すぐ使えるSVG/PNGサンプルを同梱

💡 使い方はシンプル

uv run python scripts/render_hype_curve.py \
  --csv data/hype_cycle_curve.csv \
  --out out/hype_cycle_with_labels.svg \
  --phase-lines

1行でハイプ・サイクルのSVGが生成されます。 オプションを追加すれば、マーカーやラベルも自由自在です。

hype_cycle_vivid.svg

📦 GitHub リポジトリ

ソースコード、サンプル画像、README(英語版)はすべてこちら:

👉 https://github.com/isshiki/hype-cycle-curve

💬 こんな使い方におすすめ

  • AI技術や製品の「期待値の推移」を可視化
  • カンファレンスや資料での技術マッピング
  • ブログやレポートの挿絵に

Pythonユーザーなら uv sync だけで環境構築が完了します。 技術トレンドの可視化に、ぜひ使ってみてください。

Visualize the AI Trend ― Python Hype Cycle Curve Generator Released

hype_cycle_with_labels.svg

Ever wanted to draw a Gartner-style Hype Cycle graph by yourself — just like those you see in tech reports? Now you can, with this small Python tool.

👉 GitHub: isshiki/hype-cycle-curve

✨ Features

  • Generates smooth hype-cycle curves from simple x,y CSV data
  • Optional vertical phase dividers (e.g. Peak of Inflated Expectations)
  • Fully customizable markers and labels
  • Supports Japanese text (matplotlib-fontja)
  • Includes ready-to-use SVG and PNG samples

⚙️ Quick Example

uv run python scripts/render_hype_curve.py \
  --csv data/hype_cycle_curve.csv \
  --out out/hype_cycle_with_labels.svg \
  --phase-lines

That’s all — it creates a smooth Hype Cycle curve instantly. Add markers and labels with flexible style options.

hype_cycle_vivid.svg

📁 Repository

All source code, sample outputs, and documentation are available here:

👉 https://github.com/isshiki/hype-cycle-curve

💡 Ideal for

  • Visualizing AI or technology hype trends
  • Presentations and technical reports
  • Blog illustrations or dashboards

Clone the repo, run uv sync, and start visualizing your own Hype Cycle in minutes. Simple, elegant, and fully customizable.

CMSサイト(動的)→S3(静的)移行を自動化! Pythonスクリプト公開中

「CMSで管理されている動的なWebサイトを静的サイトに移行したい」と考えている人向けの記事です。CMSでサイトを頻繁に更新する必要がなくなった場合や、運用コストを削減したい場合などで、静的サイトへの移行は大きなメリットをもたらします。以下では、私が実践した手法と、そのために作成したPythonスクリプトを紹介します。

課題と解決策

CMSを利用した動的サイトには以下の課題があります:

  • サーバーコストが高い
  • CMSのメンテナンスが手間

これらを解決するため、私はCMSサイトを静的化し、Amazon S3+CloudFrontでホスティングする方法を選びました。この作業を効率化するため、自作のPythonスクリプトを開発しました。

このスクリプトは、以下の機能を実現します:

  • 静的化:CMSからローカル環境にHTMLファイルを取得
  • リンク修正(オプション):内部リンクの変換や、一部HTML内容の変更
  • ホスティング設定:S3にアップロード

このあと、CloudFrontでHTTPS対応のホスティングを設定する作業は説明資料に従って進めてください。

スクリプトはGitHubで公開しています:

本スクリプトおよび資料は、現状のまま(AS IS)で提供されており、いかなる保証も行いません。本スクリプトの使用により発生したいかなる損害や問題についても、作成者は一切の責任を負いかねます。ご利用は自己責任でお願いいたします。

説明資料

詳細な手順はREADME.mdに記載しています。以下にもその内容を転載しておきます。


Dynamic Web to S3 Migration

このプロジェクトは、CMS管理のWebサイトからファイルをダウンロードし、Amazon S3にアップロードするためのPythonスクリプトを提供します。

また、アップロードした後に、Amazon S3をスタティック(静的)なWebサイトホスティングサービスとして構成し、Amazon CloudFrontによりCDNで配信されるようにし、AWS Certificate Manager(ACM)により生成し自動更新されるHTTPS用のSSL証明書を設定するまでの作業手順も、このREADME.mdファイルに掲載しています。

ただし、スクリプトはWindows環境で実行しているため、それ以外の環境での動作は保証できません。細かい調整が必要な場合は、スクリプトを修正することで対応してください。

※本スクリプトの実行は自己責任で行ってください。いかなる責任も負いません。また、本スクリプトにPR(プルリクエスト)やIssue(問題報告)を送られても、一切対応しませんので、あしからずご了承ください。

構成

  • requirements.txt: 必要なPythonパッケージのリスト。
  • config.ini: 認証情報を含む設定ファイル。
  • WebHtmlDownload.py: CMS管理のWebサイトから全てのHTMLファイルをダウンロードします。
  • AwsS3Upload.py: ダウンロードされたファイルをAmazon S3にアップロードします。

ログファイル

  • <トップのローカルフォルダ名>_download_log.txt: Webサイトからのダウンロードに関するログ。
  • <トップのローカルフォルダ名>_processed_log.txt: 処理済みのURLに関するログ。
  • <トップのローカルフォルダ名>_skipped_log.txt: スキップしたURLに関するログ。
  • <トップのローカルフォルダ名>_download_retry.txt: ダウンロードに失敗したURLに関するリトライ用のログ。
  • <S3名>_upload_log.txt: Amazon S3へのアップロードに関するログ。
  • <S3名>_compare_log.txt: WebサイトとAmazon S3の内容比較に関するログ。

<トップのローカルフォルダ名>(Webサイト管理用の名前)は、S3バケット名と同じ名前にします。例:wwwexamplecom

リトライ機能

※本プロジェクト開発者が試した限りでは、失敗が発生したことがないため、リトライ機能は実装済みですが、正常に稼働するかは検証されていません。

  • ダウンロードやアップロードに失敗したファイルは、リトライ用のファイルに記録されます。
  • 次回実行時にリトライ用のファイルを読み込み、前回失敗した処理を再試行します。成功した処理は再試行しません。
  • 全てのファイルが成功した場合、リトライ用のファイルは削除されます。

前提条件

CMS管理のWebサイトをWebサーバとして活用してダイナミックなWebページを配信していることを前提としています(※ただし、未検証ですがスタティックWebサイトでも有効ななずです)。また、Azure CDNなどでCDNとSSLの自動更新を対応している場合もカバーしています。

同名のAmazon S3バケットを以下の手順で作成しておいてください。

S3バケットを作る手順

作成時に以下の内容を指定することを前提とします。

  1. AWS リージョンは「アジアパシフィック (東京) ap-northeast-1」とします。
  2. AWSコンソールでS3の[汎用バケット]を開き、[バケットを作成]をクリックします。
  3. [バケットタイプ]は「汎用」を選択します。
  4. [バケット名]は<トップのローカルフォルダ名>(Webサイト管理用の名前)と同じ名前にします。例:wwwexamplecom
  5. [ACL無効]を選択してください。
  6. [パブリックアクセスをすべてブロック]のチェックを外してください。
  7. [バケットのバージョニング]は「有効にする」にしてください。
  8. [タグ - オプション]でキーは「Name」、値は「<任意のプロジェクト名(例:masahiko.info)>」でタグを追加してください。
  9. 他はデフォルトのまま[バケットを作成]をクリックしてください。
  10. これでS3バケットの作成は完了です。

必要なPythonパッケージ

以下のコマンドを使用して、必要なパッケージをインストールしてください。

pip install -r requirements.txt

認証情報の設定

AWSのアクセスキーの取得

AWSのアクセスキーはユーザーごとに取得します。セキュリティの問題もあるので、全ての作業が終わったら無効化もしくは削除するのがお勧めです。

  1. AWS Management Consoleにログインし、IAMサービスに移動します。
  2. 左側のメニューから[ユーザー]を選択します。
  3. 該当のユーザー名をクリックします。
  4. 上部の[セキュリティ認証情報]タブを開きます。
  5. [アクセスキーを作成]をクリックします。
  6. [ユースケース]は「ローカルコード」を選択します。
  7. [説明タグ値]は空のままで[アクセスキーを作成]をクリックします。
  8. これにより、アクセスキーIDとシークレットキーが発行されるので、確実にどこかに記述してください。

config.iniの編集

ご自身の環境に合わせて修正してください。

  • domainName: CMS管理Webサイトのドメイン名を指定します。例:www.example.com
  • sitemapUrlPath: Web検索用サイトマップへのルートからのパスを指定します。例:/sitemap.xml
  • topLocalName: トップのローカルフォルダ名(Webサイト管理用の名前)を指定します。S3バケット名と同じ名前にしてください。例:wwwexamplecom
  • indexFileName: インデックスドキュメント名(デフォルトのルートオブジェクト)を設定します。例:index.html
  • S3BucketName: 比較対象のS3バケット名を設定します。
  • AccessKeyId: AWSアクセスキーIDを設定します。
  • SecretAccessKey: AWSシークレットアクセスキーを設定します。
  • Region: AWSリージョンを設定します。

使用方法

WebHtmlDownload.pyの使用方法

(1) WebHtmlDownload.pyを実行して、CMS管理のWebサイトから全てのHTMLファイルをダウンロードします。

python WebHtmlDownload.py

※古い形式のサイトマップのスキーマ「http://www.google.com/schemas/sitemap/0.84」にしか対応していません。これ以外の場合、コードを修正する必要があります。

(2) ダウンロードされたファイルは、指定されたローカルディレクトリに保存されます。

AwsS3Upload.pyの使用方法

(1) AwsS3Upload.pyを実行して、ダウンロードされたファイルをAmazon S3にアップロードします。

python AwsS3Upload.py

(2) アップロードの成功または失敗はログファイルに記録されます。

全て成功すれば作業は完了です。

さらに、Favicon(Webサイト用のアイコン)もある場合は、適切な場所(例えば/favicon.ico)にAmazon S3のサイトでアップロードしてください。

S3バケットをスタティックなWebサイトホスティングサービスにするまでの手順

注意事項

  • パブリックアクセスを有効化する際はセキュリティに注意してください。不要なデータが公開されないように。
  • 公開したくないファイルはそもそもアップロードしない方がよいでしょう。このスクリプトではもともとWebサイトでパブリックに公開されていたオブジェクト(主にHTMLページ)のみを移行する仕様になっていますので、基本的には新たに不要なデータが公開されることはないはずです。

手順 1: 静的Webサイトホスティングを有効化

  1. AWSコンソールで対象のS3バケットを選択します。
  2. 上部メニューの[プロパティ]をクリックしてください。
  3. [静的Webサイトホスティング]セクションの[編集]をクリック。
  4. 「静的Webサイトホスティング」の「有効にする」を選択します。
  5. [ホスティングタイプ]jは、「静的ウェブサイトをホストする」を選択します。
  6. [インデックスドキュメント](例: index.htmldefault.html)を入力。
    • 必要なら[エラードキュメント](例: error.html)も入力。このファイルは基本的にバケットのルート(トップレベル)に配置してください。
  7. [変更の保存]をクリックします。

サンプルのerror.htmlファイルをこのプロジェクトに含めていますので、これをS3バケットのトップレベルにアップロードしてみてください。

手順 2: ブロックパブリックアクセスをオフにする

この作業は、作成時にオフにしていれば不要です。

  1. 上部メニューの[アクセス許可]をクリック。
  2. [ブロックパブリックアクセス (バケット設定)]セクションの[編集]をクリック。
  3. すべてのチェックボックスをオフにします。
  4. 保存します。
  5. 注意: この設定変更により、バケットがパブリックにアクセス可能になるリスクがあります。次のポリシー設定を適切に行いましょう。

手順 3: バケットポリシーを設定

S3バケットをパブリックにアクセス可能にするため、バケットポリシーを記載します。

以下は、特定のS3バケット(例: example-bucket)内のすべてのオブジェクトをパブリックにするポリシーです。arn:aws:s3:::example-bucketの部分は「バケット ARN」と呼ばれますが、編集画面上でコピーできます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::example-bucket/*"
    }
  ]
}
  1. 引き続き[アクセス許可]にある[バケットポリシー]セクションの[編集]をクリック。
  2. 上記のJSONコードを貼り付けます(example-bucketを実際のバケット名に変更)。
  3. 保存します。

手順 4: オブジェクト所有者を確認

S3バケットの[アクセス許可]で[オブジェクト所有者]が「バケット所有者の強制」となっている場合、ACL(アクセスコントロールリスト)は無効になっています。つまり、このバケット内のすべてのオブジェクトは、このアカウントによって所有されます。このバケットとそのオブジェクトへのアクセスは、ポリシーのみを使用して指定されます。

このプロジェクトでは、ACLが無効であることを前提としています。ACLが有効な場合、バケットポリシーを設定しても、オブジェクト(ファイル)がパブリックでない場合があります。

手順 5: WebサイトのURLにアクセス

スタティックWebサイトのURLは、以下の形式になります。

http://{バケット名}.s3-website-{リージョン}.amazonaws.com
http://wwwexamplecom.s3-website-ap-northeast-1.amazonaws.com
  1. 対象のS3バケットの上部メニューの[プロパティ]をクリックしてください。
  2. 一番下の[静的ウェブサイトホスティング]にある「バケットウェブサイトエンドポイント」のURLを開いてみてください。個別のオブジェクトにアクセスできるかは後で確認します。
  3. 上部メニューの[オブジェクト]から任意のオブジェクトを開いてください。
  4. 上部メニューの[プロパティ]を開き、[オブジェクトの概要]の[オブジェクト URL]を開いて、実際にWebアクセスできるかを確認してください。
  5. これによりHTMLページや画像などが正常に表示されれば、S3のスタティックなWebサイトの公開は完了です。

S3バケットのサイトがCDN(カスタムドメインSSL証明書あり)で配信されるまでの手順

Amazon CloudFrontの手順の中で、AWS Certificate Manager(ACM)を使ってカスタムドメイン用のSSL証明書を取得するようになっています。証明書の発行時にDNS検証を選択することによって、期限切れの60日前に自動更新されます。

Amazon CloudFrontの設定手順

  1. CloudFrontディストリビューションの作成

    1. AWS Management Consoleにログインし、CloudFrontサービスに移動します。
    2. [CloudFront ディストリビューションを作成]をクリックします。
    3. [Origin domain]で、S3バケットのエンドポイントを選択し、それにより表示される[Web サイトのエンドポイントを使用]をクリックします。
      • 例: - <バケット名>.s3-website-<リージョン>.amazonaws.com
    4. [名前]は自動的に入力されます。
    5. [デフォルトのキャッシュビヘイビア]セクションで[ビューワープロトコルポリシー]を「Redirect HTTP to HTTPS」に設定します。
    6. [ウェブアプリケーションファイアウォール (WAF) ]セクションで「セキュリティ保護を有効にしないでください」を選択します。追加費用を発生させないためです。必要になったらONにすればよいと思います。
    7. [設定]セクションの[料金クラス]で、日本メインなら「北米、欧州、アジア、中東、アフリカを使用」を選択します。性能と価格のバランスがよいためです。世界中からアクセスされるなら「すべてのエッジロケーションを使用する (最高のパフォーマンス)」がよいでしょう。
    8. その下の[代替ドメイン名 (CNAME) - オプション]で、[項目を追加]をクリックして、カスタムドメイン名(例:re.masahiko.info)を入力します。
    9. その下の[Custom SSL certificate - optional]で、[証明書をリクエスト]リンクをクリックします。
      • [パブリック証明書をリクエスト]を選択して[次へ]をクリックします。
      • [完全修飾ドメイン名]にカスタムドメイン名(例:re.masahiko.info)を入力します。
      • [検証方法]は「DNS 検証 - 推奨」に必ずしてください。
      • 他はデフォルトの推奨設定のままにします。
      • リソースグループで管理しやすいように[タグ]も付けるのがお勧めです。キーは「Name」として、値は「masahiko.info」など独自のグループ名を指定します。
      • [リクエスト]をクリックします。
      • [ステータス]が「保留中の検証」となるので、検証用にDNSのCNAMEの追加が必要です。お使いのDNSの設定箇所で、[ドメイン]内の表で取得できる「CNAME名」からサブドメインまでの部分(例:_abcdef123456gh7i8j9klm01n2opq345.<subdomain>)を名前として、「CNAME値」(ドメイン名で場合によっては最後の.を除いて内容、例:_a0123bcdefghigklmnopqrst45fvwxyz.zfyfvmchrl.acm-validations.aws.)を値(正規名)として指定してください。
      • 30分もしないうちに発行済みになります。[ステータス]に「発行済み」と表示されるまで待ちます。ブラウザーでリロードすると表示が変わる場合があります。
    10. CloudFrontのディストリビューション作成画面に戻ります。
    11. [Custom SSL certificate - optional]の右端の更新ボタンをクリックした後で、先ほど作成したSSLを[Custom SSL certificate - optional]で選択します。
    12. [Default root object - optional]にルート(/)でアクセスされたときに自動表示するファイル名(例: index.htmldefault.html)を入力。
    13. [ログ配信]は必要があればオンにしてください。ただし追加費用がかかるため、私の場合はオフにしています。
    14. [ディストリビューションを作成]をクリックします。
  2. CloudFrontディストリビューションのデプロイ

    • ディストリビューションのステータスが「有効」になるまで待ちます。わたしの場合はすぐでしたが、数分かかることがあるようです。
    • ディストリビューションのステータスは、CloudFrontのトップページでも確認できます。
  3. CloudFrontディストリビューションの確認

    • CloudFrontディストリビューションの[ディストリビューションドメイン名]を使用して、S3に配置したオブジェクトのパスのWebページや画像にアクセスして、無事に表示されるのを確認します(表示されるようになるまでに数分かかります)。例: d123456abcdef8.cloudfront.net
    • [ディストリビューションドメイン名]はCDN設定で使うので、保存しておいてください。

カスタムドメインのDNS設定と確認

最後にカスタムドメインでアクセスされるように設定すれば完了です。

カスタムドメインのCNAMEの内容(ドメイン名)に[ディストリビューションドメイン名]を指定してください。[ディストリビューションドメイン名]はCloudFrontで確認できます。

念のため、依然のCNAME内容は一時的に何かに書き写してバックアップしておきましょう。

反映まで1時間ほどかかります。長い場合は72時間程度も時間がかかることがあります。反映されたかはSSL証明書をブラウザから確認すればよいでしょう。もしくは以下のコマンドで確認できます。

nslookup <カスタムドメイン名>

ここまで出来たらCMS管理のWebサイトとAzure CDNの役目も終了なので、削除しても構いません。が、トラブル回避のため、72時間ほど様子を見てからの方がよいかもしれません。

全ての作業が終わったら、AWSのアクセスキーは無効化するか、削除しておきましょう。

ライセンス

このプロジェクトはApache License 2.0の下で公開されています。詳しくはLICENSEファイルをご確認ください。