Pythonでスクレイピング中、文字コードで詰まった時の対処法

経験則ですが、スクレイピング中なんかおかしいなぁって思ったときは、恐らくあなたではなくwebサイト側に問題があります。文字コードがきちんと設定されてない、もしくは設定されているけど間違っているのです。

鉄則

head内のcharsetは見ないこと

これ。言い方は悪いですが、絶対に信用してはいけません…。必ず痛い目を見ますよw

chardetは使わないこと

糞重いし、必ずしも正確ではないというのが理由です。これは最終手段としてとっておきましょう。

必ずheadersのcontent-type内を参照すること

正解。面倒ですが必ずここを確認しましょう。以下に手順を記述します…

事前準備

pip install requests

やってみよ~

requestsを使って中身を覗くと、こんな感じになっています。

import requests
r = requests.get('http://hayabusa.open2ch.net/news4vip/subback.html')
r.headers
結果

{'Date': 'Wed, 21 Jun 2017 09:12:51 GMT', 'Content-Type': 'text/html;charset=utf-8', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Set-Cookie': '__cfduid=db0430cc2ec9e1a0e0444fee5710732791498036371; expires=Thu, 21-Jun-18 09:12:51 GMT; path=/; domain=.open2ch.net; HttpOnly, a=16e51a6bb0eafd2a73f4c04f7ef84937; domain=.open2ch.net; path=/; expires=Thu, 21-Jun-2018 09:12:51 GMT', 'Vary': 'Accept-Encoding', 'Server': 'cloudflare-nginx', 'CF-RAY': '3725d93b719b2e21-NRT', 'Content-Encoding': 'gzip'}

ここから、文字コードが格納されている、content-typeを抜き出して見ます。

 r.headers['content-type']
結果
'text/html;charset=utf-8'

このページのエンコードはutf-8で行われているようですね。”=“以前の文字は必要ないので、文字コードだけを取り出してセットする関数を書いてみました。*1


import requests
def set_encoding(r):
"""headersから文字コードを抽出して改めてセットする。"""
if "content-type" in r.headers:
try:
charset = r.headers['content-type'].index('=') + 1
except ValueError:
r.encoding = "Shift_JIS"
else:
r.encoding = r.headers['content-type'][charset:]
else:
r.encoding = 'Shift_JIS'
r = requests.get('http://hayabusa.open2ch.net/news4vip/subback.html')
set_encoding(r)
r.encoding
結果
'utf-8'

 終わり

以上です。正直めっちゃハマったので…文字コードは厄介ですね~。

Pythonクローリング&スクレイピング -データ収集・解析のための実践開発ガイド-

Pythonクローリング&スクレイピング -データ収集・解析のための実践開発ガイド-

*1:ごめんなさい。最初forループとか使ってグルグル回しながら文字の位置探してましたが、index()使えば一発でしたね…お恥ずかしいw

コメントを残す

メールアドレスが公開されることはありません。