Python3でとあるURLに日本語パラメータでアクセスするときの文字コードについて
HTTPの主たるメソッドであるGET/POSTについて。Pythonで書いたコードからサイボウズの設定を更新したいので、POSTを対象にして実験してます。普段UTF-8しか使わない僕は想定通りShift_JISで書かれたサイボウズに泣かされるのであります。
python2系から3系になったことで、Unicodeや文字列に対する考え方が変わっていて、今までInの時とOutの時に「外に合わせれば動く」という考えだけでよかったのがうまくいかなくなった。たとえば"スパム!".encode("utf-8")がbytes型になる、とかにより。
ログインからさきのセッション管理はhttp.cookiejarを使えば簡単なのでそれはよしとして、POSTするときのクエリの文字コードがメインテーマとなります。
検索クエリをURLエンコードする際、日本語の文字列を正しくエンコードしするためにurllib.parse.quote_plus()を使う。ここではそれをprintで表示する*1。
import urllib.request import urllib.parse opener = urllib.request.build_opener() r = opener.open("http://search.yahoo.co.jp/search?ei=shift_jis&p=" \ + urllib.parse.quote_plus("天使ちゃんマジ天使",encoding="sjis")) print(r.readall().decode("utf-8"))
日本語が出てこないなら(UALエンコード不要な文字なら)、"?"と"&"でjoinするようなカッコ悪い実装をしなくても、
params = urllib.parse.urlencode({"ei" : "Shift_JIS" , "p" : "tenshi maji"}) r = opener.open("http://search.yahoo.co.jp/search", data=params) print(r.readall().decode("utf-8"))
ってな具合にすればいける。
POSTについてもyahooでは2010/07/29時点では試すことができて、下記の通り。
r = opener.open("http://search.yahoo.co.jp/search" , data = "ei=Shift_JIS&p=" \ + urllib.parse.quote_plus("天使ちゃんマジ天使",encoding="sjis")) print(r.readall().decode("utf-8"))
urllib.parse.urlencode()で辞書使ってかつ日本語解釈ってできないのかしら。
動くようになったし、まぁいっか。