近期做项目遇到的问题,记录一下,也给踩这个坑的同学一点提示。
该问题是在对合作商接口API进行爬取的时候,接口需要在headers里加入签名,key值必须是小写,不然接口无法正常调用。
- 先尝试了一种方法,就是在Request里去改变headers,等不急的可以直接看最后
class Request(object_ref):
def __init__(self, url, callback=None, method='GET', headers=None, body=None,
cookies=None, meta=None, encoding='utf-8', priority=0,
dont_filter=False, errback=None, flags=None):
...
self.headers = Headers(headers or {}, encoding=encoding)
...
进入Headers类
class Headers(CaselessDict):
"""Case insensitive http headers dictionary"""
...
def normkey(self, key):
"""Normalize key to bytes"""
return self._tobytes(key.title())
...
发现其在normkey这个函数里进行了转换,于是重写了Headers和Request类,执行爬虫发现并不能成功,在response里查看了request的headers,发现也是小写了,为什么不行。
最有可能的是在请求发出后又修改成了默认的headers,使用了抓包工具验证,果然,这样思路就很清晰了。
- scrapy是基于twisted的,所以需要在这里去修改,经过查找后发现了解决方法
from twisted.web.http_headers import Headers as TwistedHeaders
TwistedHeaders._caseMappings.update({
b'sign': b'sign', # 这里的key会去匹配headers里的key,value会把匹配成功的key值进行替换
b'User-Agent': b'user-agent',
})
使用这个方法就可以将需要修改的headers的key进行修改,并不会改变其它的key值,非常好用。
网友评论