这是一个简单的抓取蜘蛛
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
只是为了让parse2函数工作,我需要在请求方法中添加dont_filter=True作为参数。
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个声誉(可怜的我!)
发布于 2016-08-15 16:44:38
简短回答:您正在发出重复的请求。Scrapy内置了重复过滤功能,默认情况下处于打开状态。这就是parse2
不被调用的原因。当您添加该dont_filter=True
时,scrapy不会过滤掉重复的请求。所以这一次请求被处理了。
较长版本:
在Scrapy中,如果您设置了start_urls
或定义了方法start_requests()
,爬行器会自动请求这些urls并将响应传递给parse
方法,该方法是用于解析请求的默认方法。现在,您可以从这里生成新的请求,这些请求将再次由Scrapy解析。如果不设置回调,则会再次使用parse
方法。如果您设置了回调,则将使用该回调。
Scrapy也有一个内置的过滤器,可以停止重复的请求。也就是说,如果Scrapy已经抓取了一个站点并解析了响应,即使你用这个url产生了另一个请求,scrapy也不会处理它。
在本例中,url在start_urls
中。Scrapy以该url开头。它爬行站点并将响应传递给parse
。在parse
方法内部,您再次向相同url (刚刚处理的url)发出请求,但这次使用parse2
作为回调。当这个请求被产生时,scrapy将其视为副本。所以它会忽略请求,并且永远不会处理它。因此不会调用parse2
。
如果您想控制应该处理哪些scrapy.Request
以及使用哪些回调,我建议您重写urls并返回一个urls列表,而不是使用单个start_urls
属性。
https://stackoverflow.com/questions/38951878
复制相似问题