摄影:产品经理
某种贝类的肉
我们知道,HTTP请求的 POST 方式,提交上去的数据有很多种格式。例如 JSON / form-data / x-www-form-urlencoded 等等。我们在 Postman 的 POST 请求里面,可以看到这些数据格式,如下图所示:
JSON
form-data
x-www-form-urlencoded
虽然同样都是 POST 方式,但是有些网站只能使用特定的格式才能正常返回数据。我们来看一个例子,现在向网址: http://exercise.kingname.info/ajax_1_postbackend POST 提交一个 JSON 字符串: {“name”:”xx”,”age”:24} 可以正常得到返回:
http://exercise.kingname.info/ajax_1_postbackend
{“name”:”xx”,”age”:24}
但如果提交的数据格式不是 JSON,而是 form-data ,那么就会报错,如下图所示:
这也就是为什么在使用 requests 的时候,post 方法的第二个参数有 data= 和 json= 的区别,如下图所示:
data=
json=
在使用 Scrapy 的时候,很多人都知道怎么提交 GET 请求,但却不太清楚怎么提交 POST 请求。如果你在网上搜索,那么,你会看到有两种回答:
第一种回答,会建议你使用 scrapy.FormRequest 。但这个方法提交的数据是 form-data 格式,如果网站需要接收 JSON 格式的数据,那么提交就会失败。
scrapy.FormRequest
第二种回答,会建议你使用 scrapy.Request(url, method='POST', body=json.dumps(xxx)) 。这种方式确实可以成功提交 JSON 数据,但写起来比较麻烦。
scrapy.Request(url, method='POST', body=json.dumps(xxx))
但如果你看过 Scrapy 的官方文档 Requests and Responses[1] ,你就会知道,实际上 Scrapy 原本就提供了一个专门用来POST 提交 JSON 数据的方式—— JsonRequest 。它的位置在 scrapy.http.JsonRequest 。并且使用起来跟 scrapy.Request 一样简单:
JsonRequest
scrapy.http.JsonRequest
scrapy.Request
import scrapy from scrapy.http import JsonRequest class ExampleSpider(scrapy.Spider): name = 'example' allowed_domains = ['xxx.com'] # start_urls = ['http://xxx.com/'] def start_requests(self): body = { 'name': 'kingname', 'age': 28 url = 'http://exercise.kingname.info/ajax_1_postbackend' yield JsonRequest(url, data=body, callback=self.parse)