2013-06-29 2 views
6

편집 : 문제를 알아 냈습니다. #user_sex의 #이 (는) 파이썬 요청에 의해 % 23 (으)로 변환되지 않습니다. 파이썬 요청을 % 23으로 변환하도록 강제하는 방법이 있습니까? 아니면 그 부분을 직접 코딩해야할까요?파이썬에서 urlencode가 작동하지 않는다고 요청합니까?

저는 facebook fql 멀티 쿼리를 만들려고합니다. 내가

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)를 실행하면 내가 코드이

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은 그러나

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

입니다 (json은 원하는 데이터를 가지고있다).

나는 첫 fql_url과 fql_url로 코딩 된 손을 비교했으며 둘 다 json을 얻는 데 사용되는 동일한 url을 가져와야합니다. urlencode 요청이 작동하지 않습니까? 아니면 제가 여기서 잘못된 것을하고 있습니까?

답변

12

문제는, #은 참으로 URL에 유효한 문자입니다. 조각 부분을 나타냅니다. 조각은 항상 사용자 에이전트에 의해 해결되므로 절대로 서버로 보내지 않습니다. 이 작업을 시도 할 수 있습니다 :

당신이 볼 수 있듯이, 당신의 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"}') 

은 조각으로 분석된다.

편집 :

가장 편리한 방법은 아마 요청이 모든 인코딩을 할 수 있도록하는 것입니다.

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 (으)로 인코딩하는 것 같습니다. 그러나 그 코드가 여기에 없기 때문에 당신이 실수 한 곳을 말할 수 없었습니다. 유효하지 않은 문자가있는 경우 인용 부호를 사용하십시오 ('+'를 인용해야하는 경우 quote_plus를 사용하십시오). 언제든지 명령 줄에서 시도 할 수 있습니다. >>> d = { 'e': 'e^& * F ##'} >>> urllib.urlencode (d) 'e = e % 5E % 26 % 2AF % 23 % 23 ' # -> % 23 –

+1

감사합니다. 지금 당장 사용하겠습니다. 하지만 왜 요청이 올바르게 인코딩되지 않는지 알고 있습니까? 이것은 제가 언급 한 도서관입니다. http : // docs.python-requests.org/ko/latest/ – bab

관련 문제