2017-02-15 146 views
1

我正在从python的requests库移动到scrapy,并且我在发出简单POST请求时遇到问题。我设置标题和有效载荷这样:Scrapy POST请求不起作用 - 400错误请求

headers = { 
    'Accept':'*/*', 
    'Accept-Encoding':'gzip, deflate, br', 
    'accept-language':'en_US', 
    'Connection':'keep-alive', 
    'Content-Length':'151', 
    'content-type':'application/json', 
    'Cookie':cookie, 
    'Host':host, 
    'Origin':origin, 
    'Referer':referer, 
    'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36', 
    'x-csrf-token':token 
} 

payload = {"targetLocation":{"latitude":lat,"longitude":lng}} 

然后发出请求是这样的:

def start_requests(self): 
    u = self.url 
    yield scrapy.Request(u, method='POST', 
          callback=self.parse_httpbin, 
          errback=self.errback_httpbin, 
          body=json.dumps(self.payload), 
          headers=self.headers) 

这不断给我400个状态。如果我使用与requests库完全相同的标头和有效载荷发出请求,它会给我200个状态并按预期返回一个json。

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

我在做什么错?

+2

你真的不应该设置你自己的'Content-Length'头。大多数图书馆都会为你计算。如果'scrapy'发送两次,服务器*规格要求*返回400. –

+0

就是这样!现在就像魅力一样。谢谢! :) –

+0

@ sigmavirus24这个答案很好,请将它发布在答案区。 –

回答

2

您在请求中使用的这些标头中的几个不适合使用通用HTTP库。大多数图书馆会产生这些自己:

  • 主机
  • 内容长度

具体来说,HTTP RFC中规定得很清楚,任何时候Content-Length头中发送一次以上(其中Scrapy可能做),那么响应必须是400.请求,可能不会设置它自己的内容长度标题,并推迟到你的。