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

千千 · May 03, 2018 · Last by chen replied at May 04, 2018 · 3638 hits

开发给的接口是这样的,有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 条回复 时间 点赞
Author only

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

千千 #3 · May 03, 2018 作者
ETlogic 回复

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

千千 #4 · May 03, 2018 作者
凯蒂 回复

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

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 脚本里没配,可以从这个方面尝试去看看?

千千 #6 · May 03, 2018 作者

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

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

千千 #8 · May 03, 2018 作者
雨夜狂奔 回复

POSTMAN提取python是这样滴。。。

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

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

data1还是要转成json字符串

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

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

千千 #14 · May 04, 2018 作者
tester 回复

正确代码是这样的。。请问为什么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)

千千 #15 · May 04, 2018 作者
hellohell 回复

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

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

千千 回复

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

千千 #17 · May 04, 2018 作者
tester 回复

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

#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)
千千 回复

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

两个问题

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

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

其实我也比较懵逼

看了看帖子,开始有一个地方没太想通,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. 你的参数 dump 了两次,dump 一次就够了
  2. data1 改为: data1 = {"data":{"password": "12345678","username": "xiangjin"}}
23Floor has been deleted
千千 回复


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

千千 关闭了讨论 04 May 18:18
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up