Python:带有自定义头的请求失败

2024-10-03 04:30:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些问题,使一个自定义标题后的要求。 我使用Requests库作为端点jsonplaceholder,在这里您可以为POST请求获得一个假JSON。你知道吗

我把我的剧本叫做

py request.py

//请求.py你知道吗

import requests
import json
from pprint import pprint

def postReqCustom( url, headers, data):
    print('Making request to: ', url)
    r = requests.post(url, headers=headers, data=data)

    print('status code: ' + str(r.status_code))

    response = r.json()
    pprint(response)

def postReq( url, data):
    print('Making request to: ', url)
    r = requests.post(url, data=data)

    print('status code: ' + str(r.status_code))

    response = r.json()
    pprint(response)

headers = {'content-type': 'application/json'}

data = {
            "title": "foo",
            "body": "bar",
            "userId": 1
            }
post_url = "https://jsonplaceholder.typicode.com/posts"

#postReq(post_url, data) #ok
postReqCustom(post_url, headers, data) #error

对于postReq,我没有得到任何错误(状态代码201),但是当我尝试使用自定义头postReqCustom时,我得到以下错误:

Making request to:  https://jsonplaceholder.typicode.com/posts
status code: 500
Traceback (most recent call last):
  File "request.py", line 55, in <module>
    postReqCustom(post_url, headers, payload)
  File "request.py", line 24, in postReqCustom
    response = r.json()
  File "C:\Users\Samy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 892, in json
    return complexjson.loads(self.text, **kwargs)
  File "C:\Users\Samy\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "C:\Users\Samy\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Users\Samy\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Tags: inpyjsonurldataresponserequeststatus
2条回答

问题是您正在使用data=data。作为the docs explain,如果使用此参数并传递除字符串以外的任何内容,1它对数据进行形式编码,如下所示:

title=foo&body=bar&userId=1

默认情况下,它还将Content-Type头设置为application/x-www-form-urlencoded,因此一切正常。你知道吗

但是如果您用application/json覆盖这个头,那么现在您将把主体title=foo&body=bar&userId=1传递给服务器,并告诉它将其解码为JSON。当然会失败,所以服务器给您一个错误也就不足为奇了。2


如果希望值采用JSON编码而不是表单编码,请使用json参数,而不是data参数:

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

这个JSON对您的数据进行编码,如下所示:

{"title": "foo", "body": "bar", "userId": 1}

它也会将Content-Type默认为application/json,这样一切都会正常工作。当然,如果您用相同的值覆盖相同的头,它仍然可以正常工作。你知道吗


如果您想手动进行编码并发送您编码的任何字符串,可以使用data,但是您必须发送一个字符串。例如(取自同一文档部分):

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

1。Unicode str和编码的bytesbytes类型在这里都被视为字符串,但这在快速入门教程中没有解释。

2。当然,一个真正的服务器应该,也可能会,返回一个400 Bad Request,而不是试图做一些没有意义的事情,得到一个意外的错误,仅仅用一个500 Internal Server Error来划船。

在浏览了代码之后,我可以说您正确地实现了自定义头。在查看了您用来模拟REST端点的服务之后,它似乎不接受application/json MIME类型。以下是端点接受的内容:

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

在将剪报中的标题dict改为“Content Type”:“text/xml”之后,一切都很顺利(得到201分):

import requests
import json
from pprint import pprint

def postReqCustom( url, headers, data):
    print('Making request to: ', url)
    r = requests.post(url, headers=headers, data=data)

    print('status code: ' + str(r.status_code))

    response = r.raise_for_status()
    pprint(response)

def postReq( url, data):
    print('Making request to: ', url)
    r = requests.post(url, data=data)

    print('status code: ' + str(r.status_code))

    response = r.json()
    pprint(response)

headers = {'content-type': 'application/xml'}

data = {
            "title": "foo",
            "body": "bar",
            "userId": 1
            }
post_url = "https://jsonplaceholder.typicode.com/posts"
postReqCustom(post_url, headers, data)

相关问题 更多 >