Python asks urlencode not working?

EDIT: I understood the problem. # In #user_sex does not convert to% 23 on python requests. Is there a way to make python requests convert # to% 23 or do I just need to pass the code for this part?

I am trying to do multi-user fql futures. When I use fql_url below

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 ) 

and run request.get (fql_url) returned by json -

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

However, when I pass the fql_url code like this

 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 ) 

everything works (json has the required data).

I compared both the first fql_url and the manual fql_url code, and both should result in the same url being used to get json. Is the urlencode request broken or am I doing something wrong here?

+6
source share
2 answers

The problem is that # really a valid character in the url. It denotes the fragmentary part. Since the fragment is always resolved by the user agent, it is never sent to the server. You can try the following:

 >>> 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"}') 

As you can see, the last part of your URL has been parsed.

Edit:

The most convenient way would probably be to allow requests to do the whole encoding.

 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}) 
+12
source

Use urllib.quote() before calling urlopen .

  • If you use urllib.urlencode correctly, it seems to encode # in %23 .
  • If you’ve ever been stuck with invalid characters, quote them (and if you need to specify “+”, use quote_plus).
  • You can always try on the command line:

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

Please note that #%23

+3
source

Source: https://habr.com/ru/post/948358/


All Articles