Uch*_*ara 5 scrapy web-scraping scrapy-spider
这是一个简单的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)
Run Code Online (Sandbox Code Playgroud)
当您运行该程序时,parse2方法不起作用,它不会打印response.url.然后我在下面的帖子中找到了解决方案.
为什么我的第二个请求没有被我的scrapy蜘蛛的parse方法调用
它只是我需要在请求方法中添加dont_filter = True作为参数以使parse2函数工作.
yield scrapy.Request(self.start_urls[0],callback=self.parse2,dont_filter=True)
Run Code Online (Sandbox Code Playgroud)
但是在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)
Run Code Online (Sandbox Code Playgroud)
除非添加dont_filter = True,为什么我的蜘蛛不能工作?我究竟做错了什么 ?在我的第一个例子中,我的蜘蛛过滤了哪些重复的链接?
PS我可以在上面发布的QA帖子中解决这个问题,但我不能发表评论,除非我有50个声望(可怜的我!!)
简短回答:您正在提出重复请求.Scrapy内置了重复过滤功能,默认情况下处于启用状态.这就是为什么parse2不被调用.添加时dont_filter=True,scrapy不会过滤掉重复的请求.所以这次处理请求.
更长的版本:
在Scrapy中,如果您已设置start_urls或已start_requests()定义方法,则spider会自动请求这些URL并将响应传递给parse方法,该方法是用于解析请求的默认方法.现在,您可以从此处生成新请求,这些请求将再次由Scrapy解析.如果未设置回调,parse则将再次使用该方法.如果设置回调,则将使用该回调.
Scrapy还有一个内置的过滤器,可以阻止重复请求.也就是说,如果Scrapy已经抓取了一个站点并解析了响应,即使您使用该URL发出另一个请求,scrapy也不会处理它.
在你的情况下,你有网址start_urls.Scrapy从那个url开始.它抓取网站并将响应传递给parse.在该parse方法中,您再次向同一个URL发出请求(scrapy刚刚处理过),但这次是parse2作为回调.当这个请求产生时,scrapy认为这是一个副本.因此它忽略了请求并且从不处理它.所以没有打电话parse2.
如果要控制应处理哪些URL以及要使用哪个回调,我建议您覆盖start_requests()并返回列表scrapy.Request而不是使用单个start_urls属性.