我正在使用scrapy通过身份验证来抓取网站 我希望能够保存爬虫的状态,并使用
String prettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
我使用相同的命令恢复后,我希望能够登录之前 重新安排所有已保存的请求。
基本上,我想确保在安排和执行任何其他请求之前调用我的函数scrapy crawl myspider -s JOBDIR=mydir
和login()
。而且我不想使用cookies,因为它们不允许我长时间暂停爬行
我可以在after_login()
中拨打login()
,但这仅在我第一次运行抓取工具时有效。
start_requests()
底线:在重新安排之前的请求之前,当我使用class MyCrawlSpider(CrawlSpider):
# ...
START_URLS = ['someurl.com', 'someurl2.com']
LOGIN_PAGE = u'https://login_page.php'
def login(self):
return Request(url=self.LOGIN_PAGE, callback=self.login_email,
dont_filter=True, priority=9999)
def login_form(self, response):
return FormRequest.from_response(response,
formdata={'Email': 'myemail',
'Passwd': 'mypasswd'},
callback=self.after_login,
dont_filter=True,
priority=9999)
def after_login(self, response):
if "authentication failed" in response.body:
self.logger.error("Login failed")
return
else:
print("Login Successful!!")
self.is_logged_in = True
for url in self.START_URLS:
yield Request(url, callback=self.parse_artists_json, dont_filter=True)
选项继续抓取时,是否会始终调用任何回调?我将用它来调用-s JOBDIR=...
方法。
答案 0 :(得分:2)
您可以使用spider_opened
信号(more here)
此函数用于为蜘蛛和其他初始化分配资源,因此它不会指望您从那里产生Request对象。
您可以通过提供一系列待处理请求来解决此问题。这是必需的,因为scrapy不允许您手动安排请求。
然后,在恢复蜘蛛之后,您可以将登录队列作为队列中的第一个请求进行排队:
def spider_opened(self, spider):
self.spider.requests.insert(0, self.spider.login())
您还需要在蜘蛛
中添加next_request
方法
def next_request(self):
if self.requests:
yield self.requests.pop(0)
通过将所有请求添加到requests
数组中来排队所有请求,并调用next_request
添加每个方法的结尾:
def after_login(self, response):
if "authentication failed" in response.body:
self.logger.error("Login failed")
return
else:
print("Login Successful!!")
self.is_logged_in = True
if not self.requests:
for url in self.START_URLS:
self.requests.append(Request(url, callback=self.parse_artists_json, dont_filter=True)
yield self.next_request()