PythonでWord文書内のハイパーリンクを抽出する  

Word文書には、多くの場合、外部リソースを参照するためのハイパーリンクが含まれています。しかし、手作業でリンクを探すのは非効率で、見落としのリスクもあります。Pythonを使って自動でリンクを抽出すれば、リンクのインデックス作成や文書管理が容易になります。この記事では、**Pythonを使用してWord文書内のハイパーリンクを一括抽出する方法**を紹介し、アンカーテキスト（表示テキスト）、URL、およびヒントを取得する手順を解説します。 

この記事で使用する方法には、無料の[Free Spire.Doc for Python](https://jp.e-iceblue.com/introduce/introduce-free-doc-for-python.html)ライブラリが必要です。インストールはPyPIから可能です：  
```sh
pip install spire.doc.free
```

## PythonでWord文書内のすべてのハイパーリンクを抽出する  
`Document` クラスを使用してWord文書を読み込み、処理を行います。Word文書内のハイパーリンクは**フィールド（Field）** として段落テキストに挿入されるため、文書内の各セクションの子オブジェクトを判別し、すべての段落を取得した後、段落内の子オブジェクトを判別することで、すべてのフィールドを見つけ出し、さらにフィールドの種類を識別することでハイパーリンクフィールドを抽出できます。  
ハイパーリンクフィールドを特定した後、`Field.FieldText` プロパティを使用してハイパーリンクの**アンカーテキスト**を取得し、`Field.Code` プロパティを使用して以下の形式のフィールドコードを取得できます：  
- 通常のハイパーリンクのフィールドコード：  
  ```sh
  HYPERLINK "https://www.example.com/"
  ```
- ヒント付きのハイパーリンクのフィールドコード：  
  ```sh
  HYPERLINK "https://www.example.com/ai" \o "ヒントの内容"
  ```

フィールドコードを分割することで、URLやヒントの内容を取得し、完全なハイパーリンク情報を抽出できます。  

以下は、Pythonを使用してWord文書内のハイパーリンクを抽出する手順です。  
必要なモジュール：`Document`、`Paragraph`、`Field`、`FieldType`。  

1. **Word文書を読み込む**：`Document` オブジェクトを作成し、`Document.LoadFromFile()` メソッドで対象のファイルを開きます。  
2. **文書構造を走査する**：  
   - すべてのセクション (`Sections`) を走査します。  
   - 各セクションの本文 (`Section.Body.ChildObjects`) を走査します。  
   - `Paragraph` タイプの子オブジェクトを抽出し、それらの `Paragraph.ChildObjects` をさらに解析します。  
3. **ハイパーリンクを抽出する**：  
   - `Field` タイプの段落内オブジェクトを識別し、`FieldType` が `FieldType.FieldHyperlink` であるかを判定します。  
   - `FieldText` から**アンカーテキスト**を取得し、`Field.Code` から**URL**と**ヒント**を解析します。  
4. **抽出したハイパーリンク情報を保存する**。  

## **コード例**
```python
from spire.doc import Document, Paragraph, Field, FieldType

# Documentオブジェクトを作成
doc = Document()

# Wordファイルを読み込む
doc.LoadFromFile("サンプル.docx")

# ハイパーリンク情報を格納するリストを作成
hyperlinks = []

# 文書内のセクションを走査
for i in range(doc.Sections.Count):
    # 現在のセクションを取得
    section = doc.Sections.get_Item(i)
    # セクション内の本文オブジェクトを走査
    for j in range(section.Body.ChildObjects.Count):
        # 現在の子オブジェクトを取得
        secObj = section.Body.ChildObjects.get_Item(j)
        # 子オブジェクトが段落かどうかを確認
        if isinstance(secObj, Paragraph):
            # 段落内のオブジェクトを走査
            for k in range(secObj.ChildObjects.Count):
                # 現在の子オブジェクトを取得
                paraObj = secObj.ChildObjects.get_Item(k)
                # 子オブジェクトがフィールドかつハイパーリンクフィールドであるかを確認
                if isinstance(paraObj, Field) and paraObj.Type == FieldType.FieldHyperlink:
                    # ハイパーリンクのアンカーテキストを取得
                    anchorText = paraObj.FieldText
                    # ハイパーリンクのURLを取得
                    url = paraObj.Code.split('"')[1]
                    # ヒント（スクリーンチップ）が存在するかを確認
                    if "\\o" in paraObj.Code:
                        # ヒントを取得
                        hyperlinkTip = paraObj.Code.split('\"')[3].strip()
                        # アンカーテキスト、URL、ヒントをリストに追加
                        hyperlinks.append(f"アンカーテキスト：{anchorText}\nURL：{url}\nヒント：{hyperlinkTip}\n\n")
                    else:
                        # アンカーテキストとURLのみをリストに追加
                        hyperlinks.append(f"アンカーテキスト：{anchorText}\nURL：{url}\n\n")

# ハイパーリンク情報をファイルに書き込む
with open("output/抽出したハイパーリンク.txt", "w", encoding="utf-8") as file:
    for hyperlink in hyperlinks:
        file.write(hyperlink)

# 文書を閉じる
doc.Close()
```

## **抽出結果**
![PythonでWord文書内のすべてのハイパーリンクを抽出](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/8190eb8f-c6c2-485c-9a86-b09603777bd5.png)

この記事では、Pythonを使用してWord文書内のハイパーリンクを抽出する方法を紹介しました。ハイパーリンクのアンカーテキスト、URL、ヒントを取得することで、文書管理の効率を向上させ、正確性を確保することができます。