一部のサイトでのUrllibのUrlopen Breaking(例:Stackapps API):ごみの結果を返します
質問
私は使用しています urllib2
's urlopen
StackOverFlow APIからJSONの結果を取得しようとする機能。
私が使用しているコード:
>>> import urllib2
>>> conn = urllib2.urlopen("http://api.stackoverflow.com/0.8/users/")
>>> conn.readline()
私が得ている結果:
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ\...
私はurllibにかなり初めてですが、これは私が得るべき結果のようには見えません。私は他の場所でそれを試してみました、そして私は私が期待するものを手に入れます(ブラウザを使用してアドレスを訪れるのと同じです:私にJSONオブジェクトを与えます)。
使用 urlopen
他のサイト(例:http://google.com")正常に動作し、実際のHTMLを与えてくれます。私も使用しようとしました urllib
そして、それは同じ結果をもたらします。
私はかなり立ち往生しており、この問題を解決するためにどこを見るべきかさえ知らない。何か案は?
解決
それはほとんどあなたがピクルスを食べさせるもののように見えます。 Urllib2が送信しているユーザーエージェントの文字列または受け入れヘッダーの何かがJSON以外のものを送信しているのかもしれません。
1つのテルテールは見ることです conn.headers.headers
コンテンツタイプのヘッダーが言っていることを確認します。
そして、この質問、 API呼び出しから生じる奇数文字列形式, 、あなたの答えがあるかもしれません。基本的に、GZIP減圧装置を介して結果を実行する必要がある場合があります。
このコードでのダブルチェック:
>>> req = urllib2.Request("http://api.stackoverflow.com/0.8/users/",
headers={'Accept-Encoding': 'gzip, identity'})
>>> conn = urllib2.urlopen(req)
>>> val = conn.read()
>>> conn.close()
>>> val[0:25]
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ'
はい、あなたは間違いなくGZIPエンコードされたデータを取り戻しています。
同じバージョンのPythonで異なるマシンで異なる結果を得ているように見えるので、一般に、urllib2 APIはGZIPエンコードデータを要求するために何か特別なことをする必要があるように見えます。どこか。
2009年にCodeconでEFFによるプレゼンテーションを見ました。彼らは、さまざまな種類の汚いISPトリックを発見するためにエンドツーエンドの接続テストを行っていました。このテストを行っている間に発見したことの1つは、驚くべき数の消費者レベルのNATルーターがランダムHTTPヘッダーを追加するか、透明なプロキシを行うことです。ネットワーク上に、追加または変更している機器がある場合があります Accept-Encoding
接続をより速く見せるためにヘッダー。