在 scrapy.Request 中添加 dont_filter=True 参数如何使我的解析方法起作用?
How does adding dont_filter=True argument in scrapy.Request make my parsing method to work ?
这是一个简单的 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。然后我在下面的线程中找到了解决方案。
Why is my second request not getting called in the parse method of my scrapy spider
只是我需要在请求方法中添加 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,否则为什么我的蜘蛛无法工作?我究竟做错了什么 ?我的蜘蛛在我的第一个例子中过滤掉了哪些重复链接?
P.S。我本可以在我上面发布的 QA 线程中解决这个问题,但除非我有 50 个声誉,否则我不能发表评论(可怜的我!!)
简答:您正在重复请求。 Scrapy 内置了默认开启的重复过滤功能。这就是 parse2
没有被调用的原因。当您添加 dont_filter=True
时,scrapy 不会过滤掉重复的请求。所以这次请求被处理了。
更长的版本:
在 Scrapy 中,如果你设置了 start_urls
或定义了方法 start_requests()
,蜘蛛会自动请求那些 url 并将响应传递给 parse
方法,这是用于解析请求的默认方法。现在你可以从这里产生新的请求,这些请求将再次被 Scrapy 解析。如果不设置回调,会再次使用parse
方法。如果您设置回调,将使用该回调。
Scrapy 还有一个内置的过滤器可以阻止重复的请求。也就是说,如果 Scrapy 已经抓取了一个站点并解析了响应,即使你用 url 产生另一个请求,scrapy 也不会处理它。
在您的例子中,您在 start_urls
中有 url。 Scrapy 以 url 开头。它抓取网站并将响应传递给 parse
。在 parse
方法中,您再次向同一个 url (scrapy 刚刚处理过)发出请求,但这次使用 parse2
作为回调。当此请求被产生时,scrapy 将其视为重复项。所以它忽略请求并且从不处理它。所以没有调用 parse2
。
如果你想控制应该处理哪些urls和使用哪个回调,我建议你覆盖start_requests()
和return列表scrapy.Request
而不是使用单个 start_urls
属性。
这是一个简单的 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。然后我在下面的线程中找到了解决方案。
Why is my second request not getting called in the parse method of my scrapy spider
只是我需要在请求方法中添加 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,否则为什么我的蜘蛛无法工作?我究竟做错了什么 ?我的蜘蛛在我的第一个例子中过滤掉了哪些重复链接?
P.S。我本可以在我上面发布的 QA 线程中解决这个问题,但除非我有 50 个声誉,否则我不能发表评论(可怜的我!!)
简答:您正在重复请求。 Scrapy 内置了默认开启的重复过滤功能。这就是 parse2
没有被调用的原因。当您添加 dont_filter=True
时,scrapy 不会过滤掉重复的请求。所以这次请求被处理了。
更长的版本:
在 Scrapy 中,如果你设置了 start_urls
或定义了方法 start_requests()
,蜘蛛会自动请求那些 url 并将响应传递给 parse
方法,这是用于解析请求的默认方法。现在你可以从这里产生新的请求,这些请求将再次被 Scrapy 解析。如果不设置回调,会再次使用parse
方法。如果您设置回调,将使用该回调。
Scrapy 还有一个内置的过滤器可以阻止重复的请求。也就是说,如果 Scrapy 已经抓取了一个站点并解析了响应,即使你用 url 产生另一个请求,scrapy 也不会处理它。
在您的例子中,您在 start_urls
中有 url。 Scrapy 以 url 开头。它抓取网站并将响应传递给 parse
。在 parse
方法中,您再次向同一个 url (scrapy 刚刚处理过)发出请求,但这次使用 parse2
作为回调。当此请求被产生时,scrapy 将其视为重复项。所以它忽略请求并且从不处理它。所以没有调用 parse2
。
如果你想控制应该处理哪些urls和使用哪个回调,我建议你覆盖start_requests()
和return列表scrapy.Request
而不是使用单个 start_urls
属性。