V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
hagezhou
V2EX  ›  Python

Python request post 参数不成功

  •  
  •   hagezhou · 2017-11-06 16:48:37 +08:00 · 7915 次点击
    这是一个创建于 2575 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用 python 的 request 来 post url,参数总是传不进去

    ···
    headers = {'content-type': 'application/json'}
    payload = {'group_name': 'env', 'host_name': '192.168.xxx.xxx'}
    r = requests.post('http://0.0.0.0:5000/xxx', data=json.dumps(payload), headers=headers)

    print(r.text)
    ···

    会返回如下:
    {
    "errors": [
    "'group_name' is a required property",
    "'host_name' is a required property"
    ],
    "message": "Unprocessable Entity"
    }

    我用 postman 去 post 就是可以的,木有任何问题,这是为什么?

    更新一下:
    用 postman 看到的 header 如下:
    Content-Length →66
    Content-Type →text/plain; charset=utf-8
    Date →Mon, 06 Nov 2017 08:56:04 GMT
    Server →Werkzeug/0.12.2 Python/2.7.14

    然后我将代码中的 headers = {'content-type': 'application/json'}改成 headers = {'Content-Type': 'text/plain'}
    然后 print r.headers,结果是
    {'Date': 'Mon, 06 Nov 2017 08:55:39 GMT',
    'Content-Length': '159',
    'Content-Type': 'application/json',
    'Server': 'Werkzeug/0.12.2 Python/2.7.14'}
    http://0.0.0.0:5000/tower/inventory

    Content-Type 并没有生效,why
    14 条回复    2017-11-07 08:42:45 +08:00
    Marmot
        1
    Marmot  
       2017-11-06 16:56:39 +08:00
    r = requests.post('http://0.0.0.0:5000/xxx', json=payload)
    hagezhou
        2
    hagezhou  
    OP
       2017-11-06 16:59:13 +08:00
    @Marmot 我根据 postman 的返回结果,把 headers = {'Content-Type': 'text/plain'} 改了,但是 print 出来的 header 中还是 json ?
    Marmot
        3
    Marmot  
       2017-11-06 17:00:33 +08:00
    还有就是有可能有些 content-type 大小写敏感。
    Marmot
        4
    Marmot  
       2017-11-06 17:01:58 +08:00
    @hagezhou 1 楼那个回复那种是 request 自己帮你处理了,你可以看一下源码。
    gimp
        5
    gimp  
       2017-11-06 17:02:16 +08:00
    r.headers 中保存的是服务器返回给你的 headers
    focusheart
        6
    focusheart  
       2017-11-06 17:04:04 +08:00
    你的调用方法参数传递不太对,看返回情况,应该是不需要用 json.dumps 把字典对象转换为字符串吧?
    参考 requests 官方的文档:
    http://cn.python-requests.org/zh_CN/latest/user/quickstart.html#post

    >>> payload = {'key1': 'value1', 'key2': 'value2'}
    >>> r = requests.post("http://httpbin.org/post", data=payload)

    直接把字典对象给 data 参数,相当提交了一个这样的表单:

    <form action="http://httpbin.org/post" method="post">
    <input type="text" name="key1" value="value1"/>
    <input type="text" name="key2" value="value2"/>
    </form>

    或者按照 1 楼的方式,会自动转 json 编码,看你的服务器端怎么要求输入格式的了。
    hagezhou
        7
    hagezhou  
    OP
       2017-11-06 17:05:47 +08:00
    @gimp python 这边返回的'Content-Type': 'application/json',这个和 postman 返回的 {'Content-Type': 'text/plain'} 还是不一致
    Marmot
        8
    Marmot  
       2017-11-06 17:06:37 +08:00
    ~/python3.5/site-packages/requests/api.py 看一下这个,你会明白很多。
    hagezhou
        9
    hagezhou  
    OP
       2017-11-06 17:12:37 +08:00
    @Marmot 翻了一下 api.py, 用 params=payload 好了,多谢
    源码注释这么写的:
    :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
    :param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`.
    Marmot
        10
    Marmot  
       2017-11-06 17:16:22 +08:00
    @hagezhou 你这个不是发的 json 吧......
    mec
        11
    mec  
       2017-11-06 17:39:03 +08:00
    调用的方式不对;
    还有,你在 request header 里的 content-type 声明跟服务器返回给你的没联系吧。。。
    dawncold
        12
    dawncold  
       2017-11-06 21:31:34 +08:00
    看起来像是服务端写得有问题,调试这种接口时可以用 https://requestb.in 这种工具
    ry_wang
        13
    ry_wang  
       2017-11-06 21:53:55 +08:00
    json= 改成 data=
    Marsss
        14
    Marsss  
       2017-11-07 08:42:45 +08:00
    用 burp 代理,抓包看发出去的数据包,和正常是哪里不一样,就知道怎么解决问题了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1305 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:55 · PVG 07:55 · LAX 15:55 · JFK 18:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.