接口测试 新人问问。。python+requests 的问题,求大佬帮忙。。

千千 · 2018年05月03日 · 最后由 chen 回复于 2018年05月04日 · 3500 次阅读

开发给的接口是这样的,有 headers 的数据,用 python 不知道为啥一直报错,用 postman 可以正常调用

请问传入 headers 怎么传入?

import requests
import json
import urllib
import urllib2

url = "http://ivt3.hschefu.com:9199/login"

# headers = {'content-type': 'application/json'}
data1 = {'password': '12345678','username': 'xiangjin'}
para = json.dumps(data1)
print(para)
header1 ={'app': 'string','gps': 'string','os': 'string','token': 'string','ver': 'string'}
# print(header1)
# header2 = json.dumps(header1)
# print(header2)
# headers = {}
# headers= json.dumps(headers)
r = requests.post(url,data=para,headers= header1)


print(r.text)

最佳回复
共收到 24 条回复 时间 点赞
千千 关闭了讨论 05月04日 18:18

哎~~~用 requests 的 json 参数本身就会在 header 里加上 {'Content-Type': "application/json"} ,而且 body 里明显是 json 那就用 json 参数啊。data 参数是传 form data 用的。

23楼 已删除
  1. 你的参数 dump 了两次,dump 一次就够了
  2. data1 改为: data1 = {"data":{"password": "12345678","username": "xiangjin"}}

其实我也比较懵逼

看了看帖子,开始有一个地方没太想通,requests 在 post 提交 json 的时候不是该

requests.post(url,json='xxx',header={'Content-Type': "application/json"}

怎么

requests.post(url,data='xxx',header={'Content-Type': "application/json"}

也可以?当然 data 和 json 的实参类型不一样;

然后我做了个实验

  1. 去 github 上 clone requests 模块代码,clone 到 Download 目录;

  2. 去 requests-master/requests/adapters.py 第 435 行添加了print request.body
    ta 就变成了这样

if not chunked:
    print request.body  # 这是我添加的
    resp = conn.urlopen(
        method=request.method,
        url=url,
        body=request.body,
        headers=request.headers,
        redirect=False,
        assert_same_host=False,
        preload_content=False,
        decode_content=False,
        retries=self.max_retries,
        timeout=timeout
    )

3.然后写了代码

import sys,os
sys.path[0:0]=[os.path.expanduser('~/Downloads/requests-master/')]
print sys.path[0]

import requests
print requests.__file__


url = "http://ivt3.hschefu.com:9199/login"
headers = {
    'Content-Type': "application/json",
    }

# 第一种方式
requests.request("POST", url, json={"data":
                                      {"password": "12345678",
                                       "username": "xiangjin"}
                                    },
                              headers=headers)

# 第二种方式
payload = "{\"data\": {\"password\": \"12345678\",\"username\": \"xiangjin\"}}"
requests.request("POST", url, data=payload,
                              headers=headers)

# 第三种方式
requests.request("POST", url, data=payload)

输出是

/Users/yeap/Downloads/requests-master/
/Users/yeap/Downloads/requests-master/requests/__init__.pyc
{"data": {"username": "xiangjin", "password": "12345678"}}
{"data": {"password": "12345678","username": "xiangjin"}}
{"data": {"password": "12345678","username": "xiangjin"}}

所以基本断定这三种写法的效果是一样的,当然我推荐第一种;

至今仍看不懂 requests,我不会 py


然后连 charles 代理,一样的请求,只是第三种没有 headers 字段;

你这是在考验大家的眼力吗😂

两个问题

  1. 既然你用例 requests 为啥还要 import urllib,import urllib2
  2. r = requests.post(url,json=data,headers= headers), data=你 postman body 中所有的数据
千千 回复

你的 data1 写错了啊
data1 = {"data":{"password": "12345678","username": "xiangjin"}}

千千 #17 · 2018年05月04日 Author

亲改成你说的那样还是不行呢

#coding=utf-8
import requests
import json
import urllib
import urllib2

url = "http://ivt3.hschefu.com:9199/login"

headers = {
    'Content-Type': "application/json",
    'Cache-Control': "no-cache",
    'Postman-Token': "2075beff-527a-4eb4-a5f1-45de3d3ecab1"
    }
data1 = {"password": "12345678","username": "xiangjin"}
para = json.dumps(data1)
print(para)

r = requests.post(url,data=json.dumps(para),headers= headers)


print(r.text)
匿名 #16 · 2018年05月04日
千千 回复

你注意看 payload = "{\"data\": {\"password\": \"12345678\",\"username\": \"xiangjin\"}}" 这是字符串,而你使用的是字典类型,是不一样的,如果按照你的代码,只需要把 data= 改成 json=, 或者 r = requests.post(url,data=json.dump(para),headers= header1) 这样也是可以的,要把你的 para 数据 dump 一下

千千 #15 · 2018年05月04日 Author
hellohell 回复

导出 python 代码是这样的。。。运行到 python 可以成功执行

请问为什么要写数据格式要写/,然后 data 要用两个{}呢。。。。

千千 #14 · 2018年05月04日 Author

正确代码是这样的。。请问为什么 data 写法要写/在里面呢

import requests

url = "http://ivt3.hschefu.com:9199/login"

payload = "{\"data\": {\"password\": \"12345678\",\"username\": \"xiangjin\"}}"
headers = {
    'Content-Type': "application/json",
    }

response = requests.request("POST", url, data=payload, headers=headers)
r = requests.post(url,data=payload,headers= headers)

print(response.text)
print(r.text)

你传的是 json 数据,所以只需要改一个地方就可以了,r = requests.post(url, json=para, headers=headers)

你 json.dump 了么
r = requests.post(url,data=json.dump(para),headers= header1)

data1 还是要转成 json 字符串

注意一下 header1 要加上 Content-t
Type:application/json 键值对,postman 可以是因为你的 postman 数据选择为 json 的时候,已经自动帮你添加了。

雨夜狂奔 回复

POSTMAN 提取 python 是这样滴。。。

我照着样子修改了下代码。。还是调不通。。。

postman 直接可以导出 Python 代码,导出来看看缺少些什么

我也觉得。。有两个字段的东西。。但是又不能合在一起写进 data。。。全部写进去又报错。。
那 3 个 headers 有两个是之前调试的。。实际只有一个这个

requests.post(url,data=para,headers= header1)

这里的 headers 对应的是 http 请求头部(header),即 http 协议中的一个特殊部分。和你在 http body 里面的 json 的 header 字段值不是同一个概念。而你的 http body 一直都是缺少了 header 这个 json 字段的。

遇到这类问题,推荐你用一个通用的解决方法:抓包。先抓到 Postman 发出的正确包,然后再抓 requests 发出的包,比对这两个包的差异,改你的脚本直至两者抓包结果一致。

PS:从 postman 截图来看,有 3 个 http header 字段,但你 python 脚本里没配,可以从这个方面尝试去看看?

凯蒂 回复

亲把那个 headers 写进去了。。然后吧 body 里面的 header 的数据全部装进 data 了。。可是还是报错。。

ETlogic 回复

亲。。。我把数据全部放在 data1 里面 还是不行呢。。。。

是提交是数据里面有个叫 header 的。。。
不是你请求的 headers

仅楼主可见
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册