🔥

python標準ライブラリのhtml.unescapeでユニコード文字もバッチリ

2021/12/09に公開

数字で表されたUnicode文字列を元に戻したい

Webの文章をパースするのに見慣れない下記のような文字列が出てきた。

1969年に創刊さ...

調べてみるとユニコード。
https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
pythonのcodecs.decodeでいけるだろうと思い、1文字だけそのままデコードしてみる。

>>> codecs.decode('年', 'unicode-escape')
'年'

結果はダメ。

&#xそのままではダメなのかと思い、単純に&#x\\uにして;を削除してから試す。

>>> codecs.decode('\\u5e74', 'unicode-escape')
'年'

できた!

が、実際にいくつかの文章でやってみると変換時に下記のようなエラーが起きるものも出てきた。

UnicodeDecodeError: 'unicodeescape' codec can't decode bytes in position 0-4: truncated \uXXXX escape

html.unescapeが全てを解決してくれる

困って更に調べてみるとpython標準ライブラリに良いものを発見。
https://docs.python.org/ja/3/library/html.html
html.unescapeがまさにやりたいことをやってくれる。

>>> html.unescape('年')
'年'

これで変換できていなかった一部の文章も問題なく変換できました。

ちなみに

今回の集めていたのは全巻電子書籍化された「bit」の各号の「主な内容」。
https://www.paraches.com/archives/8102
一覧にしたので読みたい記事を少しだけ探しやすくなりました。

最後に

この文章を書き始めてふと気づいたのですが一部の文章でcodecs.decodeがエラーになっていたのは&#x\\uに変換する際に4桁にしていなかったのが原因だったようです。

エラーが起きる場合はオリジナルの&#x3bc\\u3bcに変換しました。

>>> codecs.decode('\\u3bc', 'unicode-escape')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'unicodeescape' codec can't decode bytes in position 0-4: truncated \uXXXX escape

これを0を加えて\\u03bcとするとちゃんと変換できます。

>>> codecs.decode('\\u03bc', 'unicode-escape')
'μ'

とは言えhtml.unescapeならそんな面倒なことを考える必要がなくて良いですね。

Discussion