BeautifulSoupを使って不要なタグとルビを取り除く

以前の記事で、青空文庫から取得したテキストの文字化けを治しました。
次は、不要なタグを除去します。

正規表現でやってしまえば早いのですが、せっかくなので、BeautifulSoupの使い方の確認も兼ねてこちらを使ってみました。

前提として、
htmlという変数に、銀河鉄道の夜のページのソースが入っているものとします。


# ライブラリのインポートと、soupオブジェクトへの変換
from bs4 import BeautifulSoup
soup = BeautifulSoup(html)

soup.find([タグ名]) や、 soup.find(class_=[class名])で、中のタグを指定することができます。
さらに、get_text()関数を使うと、タグを取り除いた文字列が表示されます。
これで div や h1,h2,…や、a,brタグなど不要タグはほぼほぼ除去できます。
ついでに、不要な前後の空白をstrip()で取り除いて、
300文字を表示してみましょう。


print(soup.find(class_="main_text").get_text().strip()[:300])

# 結果
一、午后(ごご)の授業

「ではみなさんは、そういうふうに川だと云(い)われたり、乳の流れたあとだと云われたりしていたこのぼんやりと白いものがほんとうは何かご承知ですか。」先生は、黒板に吊(つる)した大きな黒い星座の図の、上から下へ白くけぶった銀河帯のようなところを指(さ)しながら、みんなに問(とい)をかけました。
 カムパネルラが手をあげました。それから四五人手をあげました。ジョバンニも手をあげようとして、急いでそのままやめました。たしかにあれがみんな星だと、いつか雑誌で読んだのでしたが、このごろはジョバンニはまるで毎日教室でもねむく、本を読むひまも読む本もないので、なんだかどんなことも

さて、残りは 午后(ごご) などのルビです。

これも不要なので取り除きます。
該当部分のソースコードを見ると、下記のように、ruby, rb, rt, rpの4つのタグがあります。
このうち、 rubyとrbは、タグの中身は残したいので、get_text()で取り除けば十分ですが、rbとrtはタグとその中身を消す必要がります。


一、<ruby><rb>午后</rb><rp>(</rp><rt>ごご</rt><rp>)</rp></ruby>の授業

それには、decompose関数を使用します。


for tag in soup.findAll(["rt", "rp"]):
    # タグとその内容の削除
    tag.decompose()

参考ですが、タグだけを消して、中身を残す時はunwarpを使います。
(昔はreplaceWithChildrenという名前だったメソッドです。pep8対応のためにリネームされたとか。)
hxタグとかbrタグとか、これを使って消してたこともあるのですが、get_text()を使うようになっていらなくなりました。

これで取り除けたはずなので、もう一度本文を表示します。


print(soup.find(class_="main_text").get_text().strip()[:300])

# 結果

一、午后の授業

「ではみなさんは、そういうふうに川だと云われたり、乳の流れたあとだと云われたりしていたこのぼんやりと白いものがほんとうは何かご承知ですか。」先生は、黒板に吊した大きな黒い星座の図の、上から下へ白くけぶった銀河帯のようなところを指しながら、みんなに問をかけました。
 カムパネルラが手をあげました。それから四五人手をあげました。ジョバンニも手をあげようとして、急いでそのままやめました。たしかにあれがみんな星だと、いつか雑誌で読んだのでしたが、このごろはジョバンニはまるで毎日教室でもねむく、本を読むひまも読む本もないので、なんだかどんなこともよくわからないという気持ちがするので

綺麗にルビが消えました。