我們知道,HTTP請求的 POST 方式,提交上去的數據有很多種格式。例如JSON
/form-data
/x-www-form-urlencoded
等等。我們在 Postman 的 POST 請求里面,可以看到這些數據格式,如下圖所示:
雖然同樣都是 POST 方式,但是有些網站只能使用特定的格式才能正常返回數據。我們來看一個例子,現在向網址:http://exercise.kingname.info/ajax_1_postbackend
POST 提交一個 JSON 字符串:{“name”:”xx”,”age”:24}
可以正常得到返回:
但如果提交的數據格式不是 JSON,而是form-data
,那么就會報錯,如下圖所示:
這也就是為什么在使用 requests 的時候,post 方法的第二個參數有data=
和json=
的區別,如下圖所示:
在使用 Scrapy 的時候,很多人都知道怎么提交 GET 請求,但卻不太清楚怎么提交 POST 請求。如果你在網上搜索,那么,你會看到有兩種回答:
第一種回答,會建議你使用scrapy.FormRequest
。但這個方法提交的數據是form-data
格式,如果網站需要接收 JSON 格式的數據,那么提交就會失敗。
第二種回答,會建議你使用scrapy.Request(url, method='POST', body=json.dumps(xxx))
。這種方式確實可以成功提交 JSON 數據,但寫起來比較麻煩。
但如果你看過 Scrapy 的官方文檔Requests and Responses[1],你就會知道,實際上 Scrapy 原本就提供了一個專門用來POST 提交 JSON 數據的方式——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) def parse(self, response, *args, **kwargs): print(response.body.decode())
運行效果如下圖所示:
JsonRequest
本來就是scrapy.Request
的一個子類,所以所有能在scrapy.Request
使用的參數,都可以直接在JsonRequest
中使用。同時,它額外支持兩個參數,分別是data
和dumps_kwargs
。其中data
參數的值就是一個可以被json.dumps
序列化的對象,例如字典或者列表。而dumps_kwargs
里面的參數,就是 json.dumps
支持的那些參數,例如ensure_ascii=False
、sort_keys=True
等等。
大家遇到問題多看官方文檔,少在網上搜索些雜七雜八裝逼貨的爛博客。官方文檔是你最好的朋友。
參考資料
[1]
Requests and Responses: https://doc.scrapy.org/en/latest/topics/request-response.html#jsonrequest
未聞 Code技術交流群開放啦!群里既有國內一二線大廠在職員工,也有國內外高校在讀學生,既有十多年碼齡的編程老鳥,也有中小學剛剛入門的新人,學習氛圍良好!想入群的同學,請添加我的微信“mekingname”,備注“粉絲群”(謝絕廣告黨,非誠勿擾!)~
轉自:微信公眾號:未聞 Code