URL ์ฟผ๋ฆฌ ๋ฌธ์์ด์๋ ๊ฐ์ด ์๋ ๋งค๊ฐ๋ณ์๊ฐ ํฌํจ๋ ์ ์์ต๋๋ค(์: http://host/path/?foo ๋๋ http://host/path/?a=1&foo). ํ์ฌ Requests๋ ์ด์ ๋ํ ์ง์์ ์ ๊ณตํ์ง ์์ต๋๋ค.
In [68]: d
Out[68]: {'a': 1, 'foo': None}
In [69]: tl
Out[69]: [('a', 1), ('foo',)]
In [70]: RequestEncodingMixin._encode_params(d)
Out[70]: 'a=1'
In [71]: RequestEncodingMixin._encode_params(tl)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-71-5d4dac855108> in <module>()
----> 1 RequestEncodingMixin._encode_params(tl)
/home/f557010/jpm/local/lib/python2.7/site-packages/requests/models.pyc in _encode_params(data)
87 elif hasattr(data, '__iter__'):
88 result = []
---> 89 for k, vs in to_key_val_list(data):
90 if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
91 vs = [vs]
ValueError: need more than 1 value to unpack
์์๋๋:
'a=1&foo'
๋๋ ์ด๊ฒ์์ ์ฝ๊ฐ์ ๊ฐ์น๋ฅผ ๋ณผ ์ ์์ต๋๋ค. API ์ด์ ๋ก ์ธํด 'ํํ ๋ชฉ๋ก' ์ ๊ทผ ๋ฐฉ์์์๋ง ์๋ํ ์ ์์ง๋ง ์ด์ ๋ํ ์ง์์ ์ถ๊ฐํ๋ฉด ๊ด์ฐฎ์ ๊ฒ์ ๋๋ค. @sigmavirus24?
๋๋ ์ฐ๋ฆฌ๊ฐ ๊ทธ๊ฒ์ (์์ง) ์ฌ์ฉํ๋ค๊ณ ์๊ฐํ์ง ์์ง๋ง urllib3๊ฐ urlencode
์ฌ์ฉ ํ๋ ๊ฒ ๊ฐ์ผ๋ฉฐ ๊ทธ๋ ๊ฒ ํฉ๋๋ค
์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์กฐ์ฌํ๋ฉด ์ ์๋ ์์
๋ฐฉ๋ฒ ์ค ํ๋๊ฐ ๋ง์์ ๋ค์ง ์๋๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. {'foo': None}
๋ "์๋"ํ์ง๋ง ์ฌ๋ฐ๋ฅธ ์์
์ ์ํํ์ง ์์ต๋๋ค. ์ด๊ฒ์ด ์๋ง๋ ์ฐ๋ฆฌ๊ฐ ์ด์ ์ ์ด๊ฒ์ ํผํ ์ด์ ์ผ ๊ฒ์
๋๋ค. ์ฆ, RFC 3986์๋ URI์ ์ฟผ๋ฆฌ ๋ถ๋ถ ์ ๋ํ ๋งค์ฐ ... ๋์จํ ์ ์๊ฐ ์์ผ๋ฏ๋ก ์ ์๊ฐ์๋ ์ด๋ฅผ ์ฒ๋ฆฌํด์ผ _ํด์ผ ํฉ๋๋ค_. ์ฆ, ์ฐ๋ฆฌ๊ฐ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ ๋๊ตฌ๊ฐ ์๋์ง ํ์ ํ ์ ์์ต๋๋ค. =/
>>> u = urlparse.urlparse('http://example.com/foo?bar')
>>> u
ParseResult(scheme='http', netloc='example.com', path='/foo', params='', query='bar', fragment='')
>>> urlparse.parse_qs(u.query)
{}
>>> urllib.urlencode({'foo': None})
'foo=None'
>>> urllib.urlencode([('foo',)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1336, in urlencode
for k, v in query:
ValueError: need more than 1 value to unpack
๊ด๋ จ: "None ๊ฐ์ urlencode๋ 'None' ๋ฌธ์์ด์ ์ฌ์ฉํฉ๋๋ค." โ https://bugs.python.org/issue18857
@piotr-dobrogost์ ์ ๋ ฅ, @agilevic ์ ์ ๋ ฅํ์ญ์์ค. ๋น ๋ฌธ์์ด์ ๊ฐ์ผ๋ก ์ฌ์ฉํด
์ถฉ๋. =)
>>> import requests
>>> r = requests.get('https://httpbin.org/get', params={'foo': ''})
>>> r.request.url
'https://httpbin.org/get?foo='
๊ฐ์ด ์๋ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ๋ ๊ฒ๊ณผ๋ ๋ค๋ฆ ๋๋ค. Yours๋ ๋งค๊ฐ๋ณ์ ์ด๋ฆ ๋ค์ = ๊ธฐํธ๋ฅผ ๋ ๋๋งํฉ๋๋ค. ์ผ๋ถ ์์ฉ ํ๋ก๊ทธ๋จ์ ์๋ํ์ง๋ง ์์ ํ ์๋ฃจ์ ์ ์ ๊ณตํ๊ธฐ ์ํด ์ด ์ ํํ ๊ฒฝ์ฐ๋ฅผ ํด๊ฒฐํด์ผ ํฉ๋๋ค. urllib๊ฐ ํ์ง ์๋๋ค๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ์์ฒญ์ HTTP์ ๋ํ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ณด๋ค ๋ง์ ์ผ์ ๋ ์ ์ํํฉ๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก HTTP์ ์กด์ฌ ์ด์ ์ ๋๋ค.
@agilevic ์ด ๊ธฐ๋ฅ์ ๋ํด ์ ์ํ API ๋์์ธ์ ๋ฌด์์ ๋๊น?
์ฌ๊ธฐ ๋ฏธ์น ์๊ฐ์ด ์์ต๋๋ค.
>>> import requests
>>> r = requests.get('https://httpbin.org/get', params={'foo': None})
>>> r.request.url
'https://httpbin.org/get?foo'
๊ทธ๊ฒ์ด ์ผ์ด๋์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ค์ ๋ก ์ผ์ด๋๊ณ ์๋ ์ผ:
'https://httpbin.org/get'
:(
@frnhr ๋ฐ๋ผ์ ์ฐ๋ฆฌ API์์ ์๋ํ์ง ์๋ ์ด์ ๋ ํค๋ฅผ None
๋ก ์ค์ ํ๋ ๊ฒ์ด "์ง๋์์ ์ด ํค๋ฅผ ์ ๊ฑฐํ์ญ์์ค"๋ผ๋ ์ ํธ์ด๊ธฐ ๋๋ฌธ์
๋๋ค. ์ผ๋ถ ๋งค๊ฐ๋ณ์๋ Session ๊ฐ์ฒด ์์ฒด์ ์ ์ง๋ ์ ์๊ณ ์ฌ์ฉ์๋ ๋๋๋ก ์์ฒญ๋ณ๋ก ํด๋น ๋งค๊ฐ๋ณ์๋ฅผ ์ต์ ํ ์ ์๊ธฐ๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ์ ํธ๊ฐ ์์ต๋๋ค.
์์งํ ์ธ์
๊ฐ์ฒด๊ฐ ์ด API ๋นํธ์ ์ด๋ค ๊ด๋ จ์ด ์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ํ์ง๋ง ์ข์, False
์๋๋ฉด SpecialImportableObject
๋์ None
?
2016๋ 9์ 17์ผ 07:47์ Cory Benfield [email protected] ์ ๋ค์๊ณผ ๊ฐ์ด ์ผ์ต๋๋ค.
@frnhr API์์ ์๋ํ์ง ์๋ ์ด์ ๋ ํค๋ฅผ None์ผ๋ก ์ค์ ํ๋ ๊ฒ์ด "์ง๋์์ ์ด ํค๋ฅผ ์ ๊ฑฐํ์ญ์์ค"๋ผ๋ ์ ํธ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ผ๋ถ ๋งค๊ฐ๋ณ์๋ Session ๊ฐ์ฒด ์์ฒด์ ์ ์ง๋ ์ ์๊ณ ์ฌ์ฉ์๋ ๋๋๋ก ์์ฒญ๋ณ๋ก ํด๋น ๋งค๊ฐ๋ณ์๋ฅผ ์ต์ ํ ์ ์๊ธฐ๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ์ ํธ๊ฐ ์์ต๋๋ค.
โ
๋น์ ์ด ์ธ๊ธ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ฑฐ๋ GitHub์์ ๋ณด๊ฑฐ๋ ์ค๋ ๋๋ฅผ ์์๊ฑฐํ์ธ์.
@frnhr Session
API๋ requests.
API๊ฐ Session
API ์์ ๊ตฌ์ถ๋๊ธฐ ๋๋ฌธ์ ๊ด๋ จ์ฑ์ด ์์ต๋๋ค. ์ด๋ ํด๋น ๊ธฐ๋ฅ์ ํ์ ์งํฉ์ธ ํธ๋ฆฌํ ๋ํผ์
๋๋ค.
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ํ์คํ ํ ์ ์์ง๋ง ์ด๋ ์ ๋ ๊ฐ์น๊ฐ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ํค-๊ฐ ๋งคํ์ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ params
ํ๋์ ๋ฌธ์์ด์ ์ ๋ฌํด์ผ ํฉ๋๋ค. params="foo"
.
๋งค๊ฐ๋ณ์๊ฐ ๊ฐ ์์ด ์ถ๊ฐ๋์ด์ผ ํ๋ค๋ ์์ฒญ์ ๋ํ๋ผ ์ ์๋ ํน์ ์ ํ์ ์ธ์๋ฅผ ๋ง๋ ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
# defined somewhere in requests
class ValuelessParam(object):
pass
....
....
params = {'foo': 'some_param', 'bar': requests.ValuelessParam()}
requests.get('http://something', params=params)
# url should be 'http://something?foo=some_param&bar'
None์ด ์๋๊ณ , ์ค์นผ๋ผ ์์๊ฐ ์๋๋๋ค... ๊ทธ๋์ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋์ด์ผ ํฉ๋๋ค. ๋ด๋ถ์ ์ผ๋ก... ํด๋น ๊ฐ ์ ํ์ ํ์ธํ๊ณ ํน๋ณํ ์ด ๋งค๊ฐ๋ณ์๋ฅผ ๊ตฌ์ฑ๋ URL์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ํ์คํ ์๋ํ์ง๋ง API๊ฐ Kenneth๋ฅผ ์ง๋์น ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
์, ์๋์. None
์ ๊ฐ์ ๋ด์ฅ ๊ธฐ๋ฅ์ ์ง์ํ๊ณ ์ถ์ต๋๋ค. ์ด๊ฒ์ด ์ต์ ์ ์์ด๋์ด์ธ์ง๋ ์ ๋ชจ๋ฅด๊ฒ ์ง๋ง ์ ์๋ํ ์ ์์ต๋๋ค. False
๋ ๊ทธ๋ ์ง ์์ต๋๋ค.
None
๋ ์๋ํ์ง ์์ต๋๋ค. ์ฝ๋๋ฒ ์ด์ค๋ ์ด๋ฏธ "์ธ์
์์ค์์ ์ค์ ๋ ๊ฐ ์ค์ ํด์ "์ ์๋ฏธ๋ฅผ ์ ๊ณตํฉ๋๋ค.
๊ทธ๊ฒ์ ๊ฝค ํฐ ๋ณํ๊ฐ ๋ ๊ฒ์ด๋ฉฐ ๋ง์ ์ฌ๋๋ค์๊ฒ ๋์์ด ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ์๋ง๋ ๋น ํํ์ด ๊ณ ๋ ค๋ ์ ์์ต๋๋ค. (์: (,)
.
์ด๊ฒ์ด ํด๊ฒฐ๋์๋์ง ํ์คํ์ง ์์ง๋ง ์ด ์ค๋ ๋๊ฐ ๊ฐ ์์ด ํค๋ฅผ ์ถ๊ฐํ๋ ์ ํํ ์์ ์ ์ํํ๋ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค. ์ ๊ฒฝ์ฐ์๋ "QueryAll"์ด์ง๋ง RestAPI ์๋ํ์์ ์ด๋ฌํ ์ข ๋ฅ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๋ฐ์๋ ์ฌ๋ฌ ๊ฐ์ง ์์ธ์ด ์์์ต๋๋ค.
{'QueryAll': ''}
๋ฅผ ์ ๋ฌํ๋ฉด ์ด๋ป๊ฒ ๋ฉ๋๊น?
๋๋ &QueryAll= ์ ์ป์ต๋๋ค.
์ด๋ฆฐ "="์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํ API์ ๋ฌ๋ ค์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ PasswordState์ API๋ ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก์ ๋์ ์๋ ํ ๊ทธ๊ฒ์ ์ฒ์์ผ๋ก ์ด๋ํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
3.0์์๋ ๋น ๋ฌธ์์ด์ =๋ก ๋ง๋ค์ง ์๋ ๊ฒ์ ๊ณ ๋ คํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋๋จํ ๊ฒ์ ๋๋ค :-D ์ง๊ธ๊น์ง ๋ด Passwordstate ํ๋ก์ ํธ๋ teh params ๋ฌธ์์ด์ ๋์ QueryAll= ํ์์ ์ฌ์ฉํ์ฌ ์์ผ๋ก ๋์๊ฐ ์ ์์ผ๋ฏ๋ก ๋ค์ ์๋๋๋ก ๋์๊ฐ๋๋ค. ์ด ์ค๋ ๋๋ฅผ ๋ณผ ๊ฒ์ ๋๋ค :-D
๊ณ ๋ง์ ์ผ๋ค์ค!
์์ง ๋ฃ๊ฑฐ๋ ๋ณธ ์ ์ด ์์ง๋ง ์ ๋ฐ์ดํธ๊ฐ ๋ฆด๋ฆฌ์ค๋์๋์ง ํ์ธํ๊ธฐ ์ํด ๋์๋ค๋์ง ์์์ต๋๋ค.
์๊ธด โโ๊ธ
๋ณด๋ธ ์ฌ๋: Alex Zagoro [email protected]
๋ณด๋: 2018๋
9์ 22์ผ ํ ์์ผ ์ค์ 10:19
๋ฐ๋ ์ฌ๋: ์์ฒญ/์์ฒญ [email protected]
์ฐธ์กฐ: Ellson, Nick [email protected] ; ๋๊ธ [email protected]
์ ๋ชฉ: Re: [requests/requests] ๊ฐ์ด ์๋ ๋งค๊ฐ๋ณ์๋ก URL ์ฟผ๋ฆฌ ๋ฌธ์์ด์ ๋ง๋ค ์ ์์(#2651)
์ด๋ด, ์ด๊ฒ์ ๋ํ ์ด๋ค ์ ๋ฐ์ดํธ?
๋๋ ํ์ฌ๋์ด ๋ฌธ์ ์ ์ง๋ฉด ํด ์์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋์ด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ฐฉ๋ฒ์ ์ฐพ์์ต๋๊น?
์ด ๊ฐ๋จํ์ง๋ง ๋งค์ฐ ์ผ๋ฐ์ ์ธ ๊ธฐ๋ฅ์ ๋ํ ์์ฒญ์๋ ์ฌ์ ํ ์๋ฃจ์ ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ธฐ์ด ํ.
๋ถํํ๋ ๊ฐ์ ๋ฌธ์ ์ ์ง๋ฉดํ์ต๋๋ค.
None ๋์์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ ํ์ ์ฌ์ฉ์ ์ง์ ํฌ๋งทํฐ/์ธ์ฝ๋ ๋๋ ํน์ ํ๋๊ทธ๋ฅผ ์ฝ์
/์ ๋ฌํ ์ ์๋ ๊ฒ์ด ๋ ๋์ ํจํด์ด๋ ์ต์
์ด ์๋๊น์?
@Lukasa ๋น์ ์ ์ฐ๋ฆฌ๋ณด๋ค ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๋ ์ ์๊ณ ์๋ ๊ฒ
๊ทธ๊ฒ์ด ํต์ฌ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋ @kennethreitz์์ ํด๊ฒฐ๋์ง ์์๊น์? ๊ธฐ๋ณธ๊ฐ์ 2.x ๋์์ ๋ชจ๋ฐฉํ๋๋ก ์ค์ ํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๋น ๋ฌธ์์ด์ด ์ ๋ฌ๋ ๋ ์ฌ์ ํ =๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค. ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๊ฐ๊ตฌํ ์๊ฐ์ ๋๋ค!
๊ทธ๋์ ๋๋ ์ด๊ฒ์ด ์ฌ์ ํ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๊น?
๊ฐ์ด ์๋ ๋งค๊ฐ๋ณ์๊ฐ ์๋ ๊ฒฝ์ฐ URL์ ์ผ๋ถ๋ก ๋์ดํ ์ ์์ผ๋ฉฐ ์ถ๊ฐ ๋งค๊ฐ๋ณ์๋ ?
๋ก ์์ํ๋ ๋์ &
์ถ๊ฐ๋ฉ๋๋ค.
In [3]: r = requests.get("http://www.google.com", params={'test': 'true'})
In [4]: r.url
Out[4]: 'http://www.google.com/?test=true'
In [5]: r = requests.get("http://www.google.com?test2", params={'test': 'true'})
In [6]: r.url
Out[6]: 'http://www.google.com/?test2&test=true'
์ด ๊ท์น์ ์ด๋ป์ต๋๊น?
{ key: undefined }
~ ?
_(ํฌํจ๋์ง ์์)_
{ key: null }
~ ?key
{ key: '' }
~ ?key=
{ key: 'null' }
~ ?key=null
2020๋ ... ๊ทธ๋ฆฌ๊ณ ์ฌ์ ํ ๋ฌธ์ .... SMH
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
3.0์์๋ ๋น ๋ฌธ์์ด์ =๋ก ๋ง๋ค์ง ์๋ ๊ฒ์ ๊ณ ๋ คํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.