ML競馬育成計画

技術ブログ×競馬予測

【Python3】スクレイピング中に[\xa0]に遭遇した時の対処法

Seleniumとlxmlを使ってクローリング&スクレイピングを行っている時に、\xa0という文字列が取得したい文字列に付与された状態で取得されてしまったことがあったので、対処法について調べてみました。

print(race_name)
#=> "新潟記念\xa0"

元のWebページはどうなっているのか確認

そもそもスクレイピング対象のWebページはどんな状態になっていたのかを開発者ツールから確認してみると、以下のようなページソースとなっていました。(「新潟記念」という文字列を取得する為に、「h1タグの中身を取得する」というcssセレクタを使っています。)

<h1>新潟記念&nbsp;</h1>

&nbspとはそもそもなに?

ノーブレークスペース(no-break space)を意味していて、スペースの箇所での自動的な改行を防ぐ特殊なスペースのことです。通常の半角スペースを使用した場合、ブラウザの表示サイズによって自動的に改行が行われる場合がありますが、&nbspを使用すると、どれだけ画面サイズが小さくなっても改行は行われません。 あれ?じゃあそしたら[&nbsp]という文字が付与されるんじゃないの?と思いましたが、そこの原因にあたりをつける為には、文字実体参照と数値文字参照ってなに?というのを把握する必要があります。

文字実体参照

HTMLにおいて、直接記述出来ない文字や記号を表記する際に、特定の文字列によってその文字を参照する文字実体参照という方法があります。HTMLに&nbsp;という文字列を書くことで、ブラウザが「改行しない空白」を表示する、という仕組みです。

数値文字参照

10進数もしくは16進数によって直接記述出来ない文字や記号を指定する方法です。文字実体参照は「特定の文字列」で特殊文字を参照するのに対して、数値文字参照は、「数値と文字」で参照を行います。(文字実体参照の方が直感的であるが、文字実体参照として定義されていない特殊文字を参照する為には、数値文字参照を使用する必要がある)

結論

ノンブレークスペースの文字実体参照は[&nbsp;]で、数値文字参照が[\xa0]です。cssselectでh1タグ内の文字列を取得した際に、ノンブレークスペースが本当に取得したい文字列(新潟記念)の後に記述されていた為、ノンブレークスペースの数値文字参照が文字として一緒に取得されてしまった、というのが原因のようですね。

対処法

非常に簡単で、余計な文字列はいらないので、replaceで消してあげればOKです

print(race_name.replace(u"\xa0",u""))
#=> "新潟記念"