Python 如何改变深度限制,而与刮痧爬行?
我想禁用爬行器中某个方法的深度检查和迭代,或者在爬行时更改深度限制。以下是我的一些代码:Python 如何改变深度限制,而与刮痧爬行?,python,scrapy,Python,Scrapy,我想禁用爬行器中某个方法的深度检查和迭代,或者在爬行时更改深度限制。以下是我的一些代码: def start_requests(self): if isinstance(self.vuln, context.GenericVulnerability): yield Request( self.vuln.base_url, callback=self.determine_aliases,
def start_requests(self):
if isinstance(self.vuln, context.GenericVulnerability):
yield Request(
self.vuln.base_url,
callback=self.determine_aliases,
meta=self._normal_meta,
)
else:
for url in self.vuln.entrypoint_urls:
yield Request(
url, callback=self.parse, meta=self._patch_find_meta
)
@inline_requests
def determine_aliases(self, response):
vulns = [self.vuln]
processed_vulns = set()
while vulns:
vuln = vulns.pop()
if vuln.vuln_id is not self.vuln.vuln_id:
response = yield Request(vuln.base_url)
processed_vulns.add(vuln.vuln_id)
aliases = context.create_vulns(*list(self.parse(response)))
for alias in aliases:
if alias.vuln_id in processed_vulns:
continue
if isinstance(alias, context.GenericVulnerability):
vulns.append(alias)
else:
logger.info("Alias discovered: %s", alias.vuln_id)
self.cves.add(alias)
yield from self._generate_requests_for_vulns()
def _generate_requests_for_vulns(self):
for vuln in self.cves:
for url in vuln.entrypoint_urls:
yield Request(
url, callback=self.parse, meta=self._patch_find_meta
)
我的程序是这样的,用户可以给出他们需要/想要的深度限制作为输入。在某些情况下,我的默认解析方法允许递归抓取链接
define_别名是一种预处理方法,由_generate_requests_for_vulns生成的请求是针对实际解决方案的
如您所见,我从响应中提取了所需的数据,并从determine_alias将其存储在spider类的set属性“cves”中。完成后,我将生成请求w/r/t,其中数据来自为Vuln生成请求
这里的问题是,要么产生来自determine_别名的请求,要么在回调时调用determine_别名来迭代深度。因此,当我从_生成_请求_为_vulns生成进一步爬行的请求时,我的深度限制比预期的要快
请注意,实际的爬网解决方案是从\u generate\u requests\u为\u vulns生成的请求开始的,因此给定的深度限制应该只应用于这些请求。我通过创建一个中间件将深度重置为0来解决这个问题。我在请求中传递了一个元参数,其中“reset_depth”为True,中间件根据该参数更改请求的depth参数
class DepthResetMiddleware(object):
def process_spider_output(self, response, result, spider):
for r in result:
if not isinstance(r, Request):
yield r
continue
if (
"depth" in r.meta
and "reset_depth" in r.meta
and r.meta["reset_depth"]
):
r.meta["depth"] = 0
yield r
请求应该以如下方式从爬行器中产生:
yield Request(url, meta={"reset_depth": True})
然后将中间件添加到您的设置中。顺序很重要,因为这个中间件应该在安装DepthMiddleware之前执行。因为默认的DepthMiddleware顺序是900,所以我在CrawlerProcess中将DepthResetMiddleware的顺序设置为850,如下所示:
"SPIDER_MIDDLEWARES": {
"patchfinder.middlewares.DepthResetMiddleware": 850
}
不知道这是否是最好的解决方案,但它确实有效。另一种选择可能是扩展DepthMiddleware并在那里添加此功能。当达到深度限制时会发生什么?你得到最大递归限制了吗@HåkenLid当我到达深度限制时,Scrapy忽略了在该深度可能产生的任何进一步请求。我没有递归限制。