2018年9月18日火曜日

Pythonで青空文庫の作品テキストからルビなどを取り除く

青空文庫のデータを一括ダウンロードするで青空文庫の作品テキストデータを一括ダウンロードしたが、このままだとテキストマイニングなどに利用するには問題がある。青空文庫の作品テキストにはルビなどの本文以外の記号や文字が含まれているので、それらを除去する必要がある。そこで、Python3で夏目漱石の「坊っちゃん」の作品テキストからルビなどの本文以外の文字や記号を除去してみる。


環境


Bash on Ubuntu on Windows

※GitHubのaozorabunkoからデータはダウンロード済みとする。


作品テキストデータのzipファイルからテキストを取り出す


まずは青空文庫のデータを一括ダウンロードするのコマンドで夏目漱石の「坊っちゃん」のzipファイルのパスを確認しておく。


以下のコードでzipファイル内のテキストファイル名をzipfileモジュールで取得し、テキストファイルの中身を取り出す。
import sys
import zipfile

def zip2ruby(fname):
    """
    zipファイルから作品テキストを取り出す
    """
    with zipfile.ZipFile(fname, 'r') as zf:
        item = zf.infolist()[0]
        with zf.open(item.filename) as f:
            # テキストの文字コードのShift-JISでデコードしておく
            return f.read().decode('shift-jis')

def main():
    # zipファイルパスを引数として渡す
    argvs = sys.argv
    if len(argvs) != 2:
        print('Usage: python3 {} "zip file path"'.format(argvs[0]))
        exit()

    ruby = zip2ruby(argvs[1])
    print(ruby)

if __name__ == '__main__':
    main()


以下のように実行すると「坊っちゃん」のテキストが出力される。



ルビなどの除去


続いて、ルビなど作品本文以外の文字や記号を取り除く。取り除くのは、テキスト先頭部にある【テキスト中に現れる記号について】の箇所と、末尾の「底本:」ではじまる箇所。それから、以下のようなルビなどの記号の箇所。これらを正規表現で取り除く。

(「坊っちゃん」作品テキストから抜粋)

Python3のコードは以下の通り。

※以下コード赤字部(全角「|」)の前に半角空白が入っていて「|」が取り除けていなかったのを修正。
    txt = re.sub(r'《.*?》|[#.*?]|', '', txt)
(2018/11/23追記)

import sys
import zipfile
import re

def zip2ruby(fname):
    """
    zipファイルから作品テキストを取り出す
    """
    with zipfile.ZipFile(fname, 'r') as zf:
        item = zf.infolist()[0]
        with zf.open(item.filename) as f:
            # テキストの文字コードのShift-JISでデコードしておく
            return f.read().decode('shift-jis')

def ruby2txt(ruby):
    """
    ルビなどの作品本文以外の文字や記号を取り除く
    """
    # テキスト上部の【テキスト中に現れる記号について】箇所の除去
    txt = re.split(r'-{50,}', ruby)[2]

    # テキスト下部の「底本:~」の除去
    txt = re.split(r'底本:', txt)[0]

    # ルビ、ルビの付く文字列の始まりを特定する記号、入力者注を除去
    txt = re.sub(r'《.*?》|[#.*?]||', '', txt)

    # テキスト前後の空白を除去
    return txt.strip()

def main():
    # zipファイルパスを引数として渡す
    argvs = sys.argv
    if len(argvs) != 2:
        print('Usage: python3 {} "zip file path"'.format(argvs[0]))
        exit()

    ruby = zip2ruby(argvs[1])
    txt = ruby2txt(ruby)
    print(txt)

if __name__ == '__main__':
    main()

冒頭の一文を、ルビなどを除去する前後で比較すると以下のようになる。

ルビなど除去前
 親譲《おやゆず》りの無鉄砲《むてっぽう》で小供の時から損ばかりしている。

ルビなど除去後
 親譲りの無鉄砲で小供の時から損ばかりしている。


これで青空文庫のデータが利用しやすくなったかな?

0 件のコメント:

コメントを投稿