scrapy抓取,如何改写非200状态码的response返回值?
发布于 作者:苏南大叔 来源:程序如此灵动~
scrapy目前是非常火热的抓取框架,苏南大叔以前更新过这个scrapy框架的部分教程。目前,对以前的内容进行一些适当的补充。本文中,解决的问题是scrapy抓取文件的时候,会碰到一些非200状态码的情况,比如:500/301/302之类的异常请求。

大家好,这里是苏南大叔的“程序如此灵动”博客,我是苏南大叔。本文中,苏南大叔将对scrapy碰到的非200情况进行处理。希望对您有所帮助。
本文测试环境:win10,python@3.6.8,scrapy@2.5.1。
新建scrapy项目
这里先回顾一下建立scrapy的方法,scrapy项目是使用pip安装的。
pip install scrapy
创建一个新的项目su,新建一个名为example的蜘蛛,目标网站是example.com。
scrapy startproject su
cd su
scrapy genspider example example.com
然后对su/spiders/example.py编写实际的蜘蛛逻辑,并运行编写的蜘蛛代码。
scrapy crawl example结果发现,在实际的批量数据抓取过程中,一些文章页面会跳转到另外的栏目,提供的并不是苏南大叔的目标数据,导致后续逻辑出错。
解决方案
新建middleware,处理process_response函数,对于非200状态码的情况,模拟一个新的response。
su/middlewares.py:
class CheckStatus(object):
def process_response(self, response, request, spider):
if response.status != 200:
# print(response.status)
return response.replace(body="")
else:
return responsesu/settings.py:
DOWNLOADER_MIDDLEWARES = {
'su.middlewares.CheckStatus': 542,
}这里的su.middlewares.CheckStatus是有命名依据的,是上述捕获非200代码处理方案的class的名字。542只是一个比较大的值,用于控制权重的。所以,您可以修改为您喜欢的任何合理数字。
spiders/example.py里面不做任何的逻辑修改,当然,值得注意的是,当出现非200的情况时,获得的html是自己可以自定义的。上述代码里面是留空了,实际上可以替换成任何想自定义的标记。

可能的问题一
在middleware里面,如果直接修改response的body,
response.body=""会得到一个错误提示:
AttributeError: HtmlResponse.body is not modifiable, use HtmlResponse.replace() instead这里的解决方案就是使用response.replace(),这里不但可以替换body,实际上还可以替换status,url等等。这里大家可以自行试验。
response.replace(body="")
可能的问题二
不要以为上述middleware可以捕获所有的状态码了,您还可能会碰到如下类似提示信息:
Ignoring response <500>: HTTP status code is not handled or not allowed解决方案是,修改settings.py:
HTTPERROR_ALLOWED_CODES = [403,500]当然需要您根据实际情况,修改上述数组,添加新的错误状态码。如果不做上述修改的话,scrapy运行时如果碰到500状态返回值,可能会意外结束运行。

相关链接
总结
scrapy爬虫似乎很好很强大,不过对于苏南大叔来说,还是比较喜欢使用php外加phpquery来直接写,似乎思路会更加流畅。但是,拥抱新技术才是正确的选择。更多scrapy的经验文字,请点击苏南大叔的博客: