2013-06-29 18 views
6

EDYCJA: znalazłem problem. # W #user_sex nie konwertuje na% 23 przez żądania Pythona. Czy istnieje sposób, aby zmusić wnioski Pythona, aby przekonwertować # do% 23, czy będę musiał po prostu ręcznie zakodować tę część?Python żąda urlencode nie działa?

Próbuję zrobić facebookowe multikwasy fql. Kiedy używam fql_url poniżej

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 
) 

i uruchomić requests.get (fql_url), JSON zwrócony jest

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

Jednak kiedy wręczyć kod z fql_url jak to

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 
) 

wszystko działa (json ma pożądane dane).

Porównywałem zarówno pierwszy plik fql_url, jak i kod fql_url z kodowaniem ręcznym, a oba powinny powodować, że ten sam adres URL będzie używany do uzyskania json. Czy żądania nie działają, czy też robię coś nie tak?

Odpowiedz

12

Problem polega na tym, że # jest rzeczywiście ważny znak w adresie URL. Oznacza część fragmentu. Ponieważ fragment jest zawsze rozwiązywany przez użytkownika, nigdy nie jest wysyłany na serwer. Można spróbować to:

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

Jak widać, ostatnia część adresu URL zakończony został analizowany jako fragmentu.

Edit:

Najwygodniej byłoby prawdopodobnie niech wnioski zrobić wszystko kodowania.

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

To ma sens. Więc zasadniczo powinienem użyć pierwszego fql_url i tylko zastąpić # z% 23 lub czy istnieje bardziej konwencjonalny sposób to zrobić? – bab

+1

Dodałem pragmatyczną drogę do mnie odpowiedzi –

3

Użyj urllib.quote() przed wykonaniem połączenia .

  1. Jeśli używasz urllib.urlencode właściwie to wydaje zakodować # w %23.
  2. Jeśli kiedykolwiek utkniesz z nieważnymi znakami, podaj je (a jeśli chcesz podać "+", użyj quote_plus).
  3. Zawsze można spróbować w wierszu poleceń:

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

Zauważ, że # ->%23

+0

To działa, ale dlaczego muszę to nazwać? Czy nie obsługuje już konwersji? – bab

+0

Jeśli używasz poprawnie kodu urllib.urlencode, kodowanie # do% 23 jest kodowane; ale skoro tego kodu tu nie było, nie mogłem powiedzieć, skąd bierzesz błąd. Jeśli kiedykolwiek utkniesz z nieważnymi znakami, podaj je (a jeśli chcesz zacytować "+", użyj quote_plus). Zawsze możesz spróbować z linii poleceń: >>> d = {'e': 'e^& * F ##'} >>> urllib.urlencode (d) 'e = e% 5E% 26 % 2AF% 23% 23 ' Pamiętaj, że # ->% 23 –

+1

Ok, dzięki, wykorzystam to na teraz. Ale czy wiesz, dlaczego żądania nie są poprawnie kodowane? To jest biblioteka, o której mówię. http: // docs.python-requests.org/en/latest/ – bab