web-dev-qa-db-ja.com

Python 3.0urllib.parseエラー "タイプstrはバッファAPIをサポートしていません"

  File "/usr/local/lib/python3.0/cgi.py", line 477, in __init__
    self.read_urlencoded()
  File "/usr/local/lib/python3.0/cgi.py", line 577, in read_urlencoded
    self.strict_parsing):
  File "/usr/local/lib/python3.0/urllib/parse.py", line 377, in parse_qsl
    pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
TypeError: Type str doesn't support the buffer API

誰かがこれを回避する方法について私に指示できますか? cgi.Fieldstorageにデータをフィードすることで取得していますが、他の方法ではできないようです。

23
Evan Fosmark

urllibは次のことを行おうとしています。

b'a,b'.split(',')

これは機能しません。バイト文字列とユニコード文字列は、Py3kで以前よりもスムーズに混合されないため、エンコードの問題が後でではなく早く失敗するようになっています。

したがって、エラーは「バイト文字列をurllib.parseに渡すことができない」ことをかなり不透明に示しています。おそらくあなたはPOSTリクエストを行っています。フォームでエンコードされた文字列がコンテンツ本文としてcgiに送られます。コンテンツ本文はまだバイト文字列/ストリームであるため、新しいurllibと衝突します。 。

そうですね、これはcgi.pyのバグですが、2to3変換のもう1つの犠牲者であり、新しい文字列モデルでは適切に修正されていません。着信バイトストリームをurllibに渡す前に、文字に変換する必要があります。

Python 3.0のライブラリ(特にWeb関連のライブラリ)はまだかなり派手だと言いましたか?:-)

28
bobince

pythonチュートリアル( http://www.python.org/doc/3.0/tutorial/stdlib.html )から、urlopenメソッドを使用する例があります。同じエラーが発生します。

for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
    if 'EST' in line or 'EDT' in line:  # look for Eastern Time
        print(line)

バイトthingoを正しいエンコーディングの文字列に変換するには、str関数を使用する必要があります。次のように:

for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
    lineStr = str( line, encoding='utf8' )
    if 'EST' in lineStr or 'EDT' in lineStr:  # look for Eastern Time
        print(lineStr)
13
Martlark