はじめに
Shift_jisとかいう今回は某5ちゃんねるを例にさせてもらう。
Responseを出力する
そのまま出力してみる
test.py
headers = { 'connection': 'keep-alive' }
response = requests.get(target_url, headers=headers, stream=False)
print(response.text)
UnicodeEncodeError: 'cp932' codec can't encode character '\x93' in position 33: illegal multibyte sequence
UnicodeEncodeErrorがでる。
案外知られてないが、Pythonで出力する場合
cp932というshift_jisの亜種ともいえる文字コードに変換してから出力されるわけだが
その際、cp932に変換できない文字が含まれているとエラーが出る。
test.py
print("😂")
ただ無視して出力することもできる。
test.py
print("😂".encode('cp932','ignore').decode('cp932', 'ignore'))
ただ今回のResponseを無視して出力してみると
<a href="1440930335/l50">1: VBvO}XiVer.6.0 j part65 []~]©2ch.net (487)</a>
<a href="1529199088/l50">2: X§¢±± 149C (635)</a>
<a href="1556284220/l50">3: E}/KXbh 83 (75)</a> sequence
文字化けしてしまう
そもそも今回はShift_jisを取得したはずなのに
Unicodeを変換しようとしていること自体がおかしい
つまりResponseの文字コードの設定がいかれてるので
response.encodingを正しく設定してあげる。
test.py
response.encoding = 'shift_jis'
<a href="javascript:changeSubbackStyle();" target="_self" class="js">表示スタイル切替</a>
<a href="/tech/kako/kako0000.html"><b>過去ログ倉庫はこちら</b></a> <a href="/tech/"><b>板TOPはこちら</b></a></small></div>
<div><small id="trad">
<a href="1551746188/l50">1: 人工知能ディープラーニング機械学習の数学 ★2 (224)</a>
…
できました。
Beautiful Soupに渡す
test.py
response.encoding = 'shift_jis'
soup = bs4.BeautifulSoup(response.text, 'html.parser')
print(soup.prettify().encode('cp932','ignore').decode('cp932', 'ignore'))
返ってくるのはUnicode
また
Beautiful SoupはUnicodeDammitと呼ばれるクラスを使って与えられたドキュメントのエンコーディングを調べ、元のエンコーディングがなにであろうともUnicodeに変換します。
と便利な機能があるのでresponse.content(bytes型)を渡す。
test.py
soup = bs4.BeautifulSoup(response.content, 'html.parser')
print(soup.prettify().encode('cp932','ignore').decode('cp932', 'ignore'))
…
<a href="1411797173/l50">
371: 【C/C++】統合開発環境CLion【JetBrains】 (49)
</a>
…
BeautifulSoupにはbytes型を渡そう。
また今回はWindowsに標準出力するために
.encode('cp932','ignore').decode('cp932', 'ignore')
というめんどくさいことをしているが、返ってくるのはUnicodeなので
普通に操作するだけならそのままで扱える。