python-docxモジュールでdocxファイルからテキストを抽出しています。  
そこで1つ質問なのですが、テキスト内に振り仮名（ルビ）が存在するかどうかを調べることはできるのでしょうか。  
また、もし調べることができたとして、そのルビの内容を取得するにはどうしたらよいのでしょうか。  
何かご存知でしたら教えていただけると幸いです。  
環境はWindows10、Python3.7です。  
よろしくお願いいたします。
CC BY-SA 4.0
2019-05-05T03:09:44.773
54729
2022-07-02T11:31:45.140
2022-07-02T05:26:37.857
3060
29034
question
python python3 windows python-docx
python-docxで振り仮名が存在するか調べる方法
本家SOの関連質問[Use Python docx to create phonetic guide / 'Ruby text' in
Word?の回答](https://stackoverflow.com/a/56690499/8248751)では、「`python-
docx`はルビの読み込みに未対応」の回答が寄せられています。

現時点の[`python-docx`ドキュメント](https://python-
docx.readthedocs.io/en/latest/)を読んでも、ルビを取得する方法は見つかりませんでした。

ただし`python-docx`の機能を使って、コメントの[(OOXML)
ルビ周りのメモ](https://niszet.hatenablog.com/entry/2019/01/02/230847)に記載されているOOXMLを直接解析して振り仮名を調査・抽出することは可能です。

下記のサンプルコードでは、3つの方法を使って振り仮名を抽出しています。  
[Run](https://python-docx.readthedocs.io/en/latest/api/text.html#run-
objects)ごとに振り仮名を調査・抽出する場合は、コード内の`3.`の方法を参考にしてください。

**サンプルコード**

```

    from docx import Document
    
    with open('sample.docx', 'rb') as f:
        document = Document(f)
    
    print("# 1. ドキュメントのルビを表示する")
    for t in document.element.xpath("//w:ruby/w:rt/w:r/w:t"):
        print(t.text)
    
    print("# 2. ドキュメントのルビと本文を表示する")
    ns = document.element.nsmap
    for ruby in document.element.xpath("//w:ruby"):
        r = ruby.xpath("w:rt/w:r/w:t", namespaces=ns)[0].text  # namespaces を指定しないと "lxml.etree.XPathEvalError: Undefined namespace prefix" が降りかかる
        t = ruby.xpath("w:rubyBase/w:r/w:t", namespaces=ns)[0].text  # namespaces を指定しないと "lxml.etree.XPathEvalError: Undefined namespace prefix" が降りかかる
        print(f"{t}《{r}》")
    
    print("# 3. runs のルビと本文を表示する")
    for p in document.paragraphs:
        for run in p.runs:
            ruby = run._r.xpath("w:ruby")
            # runに振り仮名が存在するか調べる
            if ruby:
                r = run._r.xpath("w:ruby/w:rt/w:r/w:t")[0].text
                t = run._r.xpath("w:ruby/w:rubyBase/w:r/w:t")[0].text
                print(f"{t}《{r}》")
    
```

参考資料:

  * [Word文書の構成](https://gammasoft.jp/support/how-to-use-python-docx-for-word-file/#doc-struct)
  * [(OOXML) ルビ周りのメモ](https://niszet.hatenablog.com/entry/2019/01/02/230847)
  * [トホホな疑問(13) Python、lxml、デフォルト名前空間とXPath](https://jhalfmoon.com/dbc/2019/10/20/%E3%83%88%E3%83%9B%E3%83%9B%E3%81%AA%E7%96%91%E5%95%8F13-python%E3%80%81lxml%E3%80%81%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E5%90%8D%E5%89%8D%E7%A9%BA%E9%96%93%E3%81%A8xpath/)
  * [python-docxにおける下線・傍点・フリガナの処理](http://cup.sakura.ne.jp/use_markdown/ue_ruby.html#session-ex11)
    * 振り仮名を追加したい場合はこちらが参考になります
CC BY-SA 4.0
2022-07-02T11:31:45.140
89724
2022-07-02T11:31:45.140
9820
54729
answer