背景:同样的url, headers, payload进行post请求,requests可以正确的拿到数据,而scrapy则无法通过验证。
通过抓包发现,scrapy所发出的请求头首字母均为大写,在postman
中将请求头的各个key改为小写后能正确拿到请求数据。
原因:
scrapy的Request对象通过传入的headers字典初始化了一个scrapy.http.Headers对象,Headers的实例会将各个key调用title方法将各个单词的首字母大写。
然而在github上寻找相关的issue时,发现虽然scrapy在这里进行了key的格式化,但是即使我们在scrapy这里保持小写,也会在通过twisted的时候,twisted框架会将headers中的key首字母大写。
https://github.com/scrapy/scrapy/issues/2711
https://twistedmatrix.com/documents/8.2.0/api/twisted.web.http_headers.Headers.html#getAllRawHeaders
因此在Scrapy这里是没有必要做什么操作的,那如果要解决这种问题,我们可以更新TwistedHeaders的请求头映射关系。
在spider代码中加上下面一段代码,headers中的这些字段就会保持小写。
from twisted.web.http_headers import Headers as TwistedHeaders
TwistedHeaders._caseMappings.update({
b'cache-control': b'cache-control',
b'accept': b'accept',
b'charset': b'charset',
b'user-agent': b'user-agent',
b'host': b'host',
b'accept-language': b'accept-language',
b'content-type': b'content-type'
})