2013-06-29 14 views
6

編集:私は問題を把握しました。 #user_sexの#は、Pythonリクエストによって%23に変換されていません。 #23%に変換するようにPythonリクエストを強制する方法はありますか?それとも、その部分を手作業でコードする必要がありますか?Pythonはurlencodeが機能しないことを要求しますか?

私はfacebook fql multiqueryを作ろうとしています。私は

fql_url = (
    'https://graph.facebook.com/fql?q=' 
    '{"user_sex":"SELECT sex FROM user WHERE uid=me()",' 
    '"friends":"SELECT uid, name FROM user WHERE uid IN ' 
    '(SELECT uid2 FROM friend WHERE uid1 = me()) ' 
    'AND not (sex in (SELECT sex FROM #user_sex)) ' 
    ' ORDER BY name"}' 
    '&access_token='+access_token 
) 

の下fql_urlを使用してrequests.get(fql_url)を実行すると、JSONが返さ

{u'error': { 
    u'code': 601, 
    u'message': u"(#601) Parser error: unexpected '{' at position 0.", 
    u'type': u'OAuthException'} 
} 

あるしかし、私はこの

fql_url = (
    'https://graph.facebook.com/fql?q=%7B%22' 
    'user_sex%22:%22SELECT%20sex%20FROM%20user%20WHERE%20uid=me()%22,%22' 
    'friends%22:%22SELECT%20uid,%20name%20FROM%20user%20WHERE%20uid%20IN%20' 
    '(SELECT%20uid2%20FROM%20friend%20WHERE%20uid1%20=%20me())%20' 
    'AND%20not%20(sex%20in%20(select%20sex%20from%20%23user_sex))%20%20' 
    'ORDER%20BY%20name%22%7D&' 
    'access_token='+access_token 
) 

すべてとしてコードfql_urlを渡したときに(jsonは望ましいデータを持っています)。

私は最初のfql_urlとfql_urlでコード化されたハンドの両方を比較しました。両方とも同じURLがjsonを取得するのに使用されるはずです。リクエストurlencodeが機能していないのですか、ここで何か間違っていますか?

答えて

12

問題は#が実際にURLで有効な文字であること、です。断片部分を示します。 フラグメントは常にユーザーエージェントによって解決されるため、サーバーに送信されることはありません。 あなたがこの試すことができます:あなたが見ることができるように

>>> import urllib3 
>>> urllib3.util.parse_url(fql_url) 
Url(scheme='https', auth=None, host='graph.facebook.com', port=None, path='/fql', 
    query='q={"user_sex":"SELECT sex FROM user WHERE uid=me()","friends":"SELECT uid, name FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me()) AND not (sex in (SELECT sex FROM ', 
    fragment='user_sex)) ORDER BY name"}') 

を、あなたのURLの最後の部分は、フラグメントとして解析されてしまいました。

編集:

最も便利な方法は、おそらく要求は、すべてのエンコーディングをやらせることであろう。

import requests 
s = requests.Session() 
s.params = {'access_token': 'foobarbaz'} # so you don't have to specify it every time 
query = ('{"user_sex":"SELECT sex FROM user WHERE uid=me()",' 
     '"friends":"SELECT uid, name FROM user WHERE uid IN ' 
     '(SELECT uid2 FROM friend WHERE uid1 = me()) ' 
     'AND not (sex in (SELECT sex FROM #user_sex)) ' 
     ' ORDER BY name"}') 
s.get('https://graph.facebook.com/fql', params={'q': query}) 
+0

それは意味があります。だから、基本的に最初のfql_urlを使って#23を#と置き換えるか、もっと一般的な方法でそれを行うべきでしょうか? – bab

+1

私は実用的な方法を私に答えた –

3

urlopenの前にurllib.quote()を使用してください。

  1. あなたは正しく%23#をエンコードするように見えるんurllib.urlencodeを使用している場合。
  2. 有効でない文字が残っている場合は、それらを引用してください( '+'を引用する必要がある場合はquote_plusを使用してください)。
  3. あなたは常にコマンドラインで試すことができます。#こと

$ d={'e':'e^&*F##'} $ urllib.urlencode(d) -> 'e=e%5E%26%2AF%23%23'

注 - >%23

+0

それは機能しますが、なぜそれを呼び出す必要がありますか?要求は既に変換を処理していませんか? – bab

+0

urllib.urlencodeを適切に使用している場合は、#23を#23にエンコードしているようです。そのコードはここにはなかったので、間違いがどこから来たのかは分かりませんでした。あなたが有効でない文字に執着したことがある場合は、それらを引用してください(そして、 '+'を引用する必要がある場合は、quote_plusを使用してください)。 いつでもコマンドラインで試すことができます: >>> d = {'e': 'e ^&* F ##'} >>> urllib.urlencode(d) 'e = e%5E%26 %2AF%23%23 ' # - >%23 –

+1

ここではこれを使用します。しかし、要求が正しくエンコードしていない理由を知っていますか?これは私が参照しているライブラリです。 http:// docs。python-requests.org/en/latest/ – bab

関連する問題