結論
BeatutifulSoupの第一引数に、requests.getのレスポンスをresponse.text、response.encodingでエンコーディングして文字列型で指定すると文字化けになることがある。文字化けを回避するには、response.contextとしbytes型を指定する。
理由は、レスポンスHTMLに問題がある。原因は、Content-Typeのエンコーディング(charset)がおかしかったり、指定されてなかったりするからだ。
BeautifulSoupはstr型かbyte型で指定できる。
requests側でエンコーディング(文字列型で指定)
- response.encoding : Content-Typeのエンコーディング
- response.text : response.encodingでデコードされたstr型のレスポンスボディ
BeautifulSoup側でエンコーディング(bytes型で指定)
- response.content: bytes型のレスポンスボディ
NGな書き方
import requests
from bs4 import BeautifulSoup
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
OKな書き方
import requests
from bs4 import BeautifulSoup
response = requests.get(url)
soup = BeautifulSoup(response.content, 'lxml')