为什么Scrapy爬取目标URL前先请求其他地址?如何规避无效爬取?
问题原因判断
请求失败确实和Referer请求头缺失相关,同时还有两个额外因素共同导致了无效请求:
- Scrapy默认开启robots协议校验,会在所有业务请求前先尝试拉取目标站点的
robots.txt,该请求没有携带认证头直接返回401 - 你通过
start_urls定义的初始请求,默认不会携带你自定义的Authorization和Referer头,所以首次请求目标地址也会返回401
解决方案
按照以下两步修改即可实现首次请求直接成功:
- 关闭robots.txt自动爬取
在爬虫类中添加自定义配置,关闭robots协议校验逻辑,避免多余请求:
custom_settings = { "ROBOTSTXT_OBEY": False }
- 重写
start_requests方法替代默认初始请求逻辑
不要用start_urls生成默认请求,直接重写该方法,首次请求就带上所有需要的请求头,不需要等待第一次401返回后再发起二次请求。
修改后的完整代码如下:
import scrapy class ScrapperSpider(scrapy.Spider): handle_httpstatus_list = [401] name = "scrapper" auth = "Basic YWRtaW46YWRtaW4=" # 关闭robots.txt请求 custom_settings = { "ROBOTSTXT_OBEY": False } target_url = "http://192.168.1.1/adslconfig.htm" # 重写初始请求方法 def start_requests(self): yield scrapy.Request( self.target_url, headers={'Authorization': self.auth, 'Referer': self.target_url}, callback=self.after_login ) def after_login(self, response): # 此处填写原有业务处理逻辑 pass
修改后爬虫启动会直接携带认证头和Referer请求目标地址,不会产生多余的无效请求,首次请求即可拿到200状态码的响应。
内容的提问来源于stack exchange,提问作者bzmind
相关产品推荐
相关产品推荐

