🔤

日本語のWebページをスクレイプする際に文字コードで嵌まる

2022/02/21に公開約1,400字

1. きっかけ

複数年にわたる記事が蓄積された Web を request 使ってスクレイピングしているときに、ページのエンコーディングが記事年代によって異なっていた。しかも、おそらくは文字コード指定の方法も年代によって異なる可能性の高い事例が発生した。

下記の様な処理を複数年代の url リストから for ループ回して取ってくる際に、re でサーチしての処理で、あるはずの文字がないと怒られて、なんでだろう? ってなってた。

url = 'https://hogehoge.com'
session = requests.Session()
response = session.get(url)
text = response.text
## ここからテキストに対して何かの処理みたいな ##

2. 解決方法

年代別にエンコード指定する条件分岐は実装か…面倒だな。いや、ほぼ不可能かも…と途方に暮れていたところ、response.encoding = response.apparent_encodingで解決することが判明。

requestsモジュールのソースコードを見てみると、apparent_encodingはプロパティとなっており、呼び出す度に文字コード推定モジュールchardetを用いて、HTMLのバイト列から文字コードを推定しています。
cite from Pythonのrequestsモジュールでの文字コード対策

結論としては、人間が設定しないといけないレスポンスヘッダやHTML内のメタタグは最初から信用せず、バイト列を元に推定すると良いというお話でした。
cite from Pythonのrequestsモジュールでの文字コード対策

具体的には下記のようにrequest.Responseオブジェクトのオブジェクトの処理前にresponse.encoding = response.apparent_encodingを挟み込む。

url = 'https://hogehoge.com'
session = requests.Session()
response = session.get(url)
+ response.encoding = response.apparent_encoding
text = response.text
## ここからテキストに対して何かの処理みたいな ##

2.1. 参考にしたサイトリンク

Pythonのrequestsモジュールでの文字コード対策

https://kanji.hatenablog.jp/entry/python-requests-beautifulsoup-encoding

Discussion

ログインするとコメントできます