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

问题描述:

下面是一个简单scrapy蜘蛛如何在scrapy.Request中添加dont_filter = True参数使我的解析方法起作用?

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。然后我在下面的线程中找到了这个解决方案。

Why is my second request not getting called in the parse method of my scrapy spider

它只是我需要添加dont_filter =真在请求方法的参数,使parse2功能工作。

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

但在scrapy文档和很多在YouTube上的教程中给出的例子,他们从来没有使用过dont_filter = True参数在scrapy.Request方法仍然是他们的第二解析功能的工作原理。

看看这个

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 =真被添加?我究竟做错了什么 ?我的蜘蛛在第一个例子中过滤的重复链接是什么?

P.S.我可以在我上面发布的QA线程中解决这个问题,但是我不允许发表评论,除非我有50个声望(可怜我!!)

+0

你有两次下载同一页面的原因吗?Scrapy会过滤您的请求,因此您不会最终抓取相同的页面,'dont_filter'完全意味着忽略此过滤器。 – Granitosaurus

+0

与你的问题没有关系,但可能很快就会咬你:'allowed_domains'应该列出域名,而不是URL,所以它应该是'allowed_domains = [“dmoz.org”]' –

简短回答:您正在进行重复请求。 Scrapy内置了默认打开的重复筛选。这就是为什么parse2没有被调用。当您添加dont_filter=True时,scrapy不会过滤出重复的请求。所以这次请求被处理。

较长版本:

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

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

就你而言,你的网址为start_urls。 Scrapy从该网址开始。它抓取该网站并将响应传递给parse。在parse方法的内部,您再次向相同的网址(刚刚处理的scrapy)发出请求,但这次是parse2作为回调。当这个请求被取消时,scrapy认为这是重复的。所以它忽略了请求并且从不处理它。所以没有拨打电话parse2

如果要控制哪些URL应该被处理且回调使用,我建议你重写start_requests()并返回,而不是使用单start_urls属性scrapy.Request列表。

+0

我想你的意思是重写'start_requests', get_start_urls'不是你最后一段中的东西。 – Granitosaurus

+0

我的不好,是的,我正在更新答案。我从记忆中写下,忘了名字。 – masnun

+0

我从未想过'start_urls'中的网址会被自动解析。非常感谢您的帮助和时间 –