在 scrapy.Request 中添加 dont_filter=True 参数如何使我的解析方法起作用?

2023-11-22

这是一个简单的 scrapy 蜘蛛

import scrapy

class ExampleSpider(scrapy.Spider):
    name = "dmoz"
    allowed_domains = ["https://www.dmoz.org"]
    start_urls = ('https://www.dmoz.org/')

    def parse(self,response):
        yield scrapy.Request(self.start_urls[0],callback=self.parse2)

    def parse2(self, response):
        print(response.url)

当您运行程序时,parse2方法不起作用,并且不打印response.url。然后我在下面的线程中找到了解决方案。

为什么我的第二个请求没有在我的 scrapy 蜘蛛的解析方法中被调用

只是我需要在请求方法中添加 dont_filter=True 作为参数才能使 parse2 函数工作。

yield scrapy.Request(self.start_urls[0],callback=self.parse2,dont_filter=True)

但在 scrapy 文档和许多 youtube 教程中给出的示例中,他们从未在 scrapy.Request 方法中使用 dont_filter = True 参数,并且他们的第二个解析函数仍然有效。

看看这个

def parse_page1(self, response):
    return scrapy.Request("http://www.example.com/some_page.html",
                      callback=self.parse_page2)

def parse_page2(self, response):
    # this would log http://www.example.com/some_page.html
    self.logger.info("Visited %s", response.url)

为什么我的蜘蛛不能工作,除非添加 dont_filter=True ?我究竟做错了什么 ?我的蜘蛛在第一个示例中过滤了哪些重复链接?

附:我可以在上面发布的 QA 线程中解决这个问题,但除非我有 50 的声誉,否则我不允许发表评论(可怜的我!!)


简短回答:您正在提出重复的请求。 Scrapy 内置了重复过滤,默认情况下处于打开状态。这就是为什么parse2没有被叫到。当你添加它时dont_filter=True,scrapy不会过滤掉重复的请求。那么这次请求就被处理了。

更长的版本:

在Scrapy中,如果你设置了start_urls或者有方法start_requests()定义后,蜘蛛会自动请求这些 url 并将响应传递给parsemethod 这是用于解析请求的默认方法。现在你可以从这里产生新的请求,这些请求将再次被 Scrapy 解析。如果你没有设置回调,parse方法将再次使用。如果您设置了回调,则将使用该回调。

Scrapy 还有一个内置的过滤器,可以阻止重复的请求。也就是说,如果 Scrapy 已经抓取了一个站点并解析了响应,即使您使用该 url 生成另一个请求,scrapy 也不会处理它。

在你的情况下,你有网址start_urls。 Scrapy 以该 url 开头。它抓取该网站并将响应传递给parse。里面那个parse方法,您再次向同一个 url(scrapy 刚刚处理过的)发出请求,但这次使用parse2作为回调。当产生此请求时,scrapy 会将其视为重复项。因此它会忽略该请求并且从不处理它。所以没有电话parse2被制成。

如果您想控制应处理哪些网址以及要使用哪个回调,我建议您覆盖start_requests()并返回一个列表scrapy.Request而不是使用单个start_urls属性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 scrapy.Request 中添加 dont_filter=True 参数如何使我的解析方法起作用? 的相关文章

随机推荐