我正在抓取搜索结果页面并从同一页面抓取标题和链接信息。作为一个搜索页面,我也有链接到下一页,我在SgmlLinkExtractor中指定了允许。
问题的描述是,在第1页,我找到了Page2和Page3的链接进行抓取,它完美无缺。但是当它抓取第二页时,它再次链接到Page1(上一页)和Page3(下一页)。因此,它再次使用引用来抓取Page1作为Page2并进入循环。
scrapy版本,我使用的是0.17。
我在网上搜索了答案,并尝试了以下方法, 1)
Rule(SgmlLinkExtractor(allow=("ref=sr_pg_*")), callback="parse_items_1", unique= True, follow= True),
但是唯一命令未被识别为有效参数。
2) 我试图在设置中指定默认过滤器为DUPEFILTER_CLASS = RFPDupeFilter
DUPEFILTER_CLASS = RFPDupeFilter
NameError: name 'RFPDupeFilter' is not defined
3)我也尝试过一个自定义过滤器,我在网上找到了这个片段,但是对它并不了解。代码如下。已捕获访问ID和状态,但它无法识别已爬网的页面。
注意:该片段是从网上复制的,我没有太多详细信息,
from scrapy import log
from scrapy.http import Request
from scrapy.item import BaseItem
from scrapy.utils.request import request_fingerprint
from Amaze.items import AmazeItem
class IgnoreVisitedItems(object):
FILTER_VISITED = 'filter_visited'
VISITED_ID = 'visited_id'
CONTEXT_KEY = 'visited_ids'
def process_spider_output(self, response, result, spider):
context = getattr(spider, 'context', {})
visited_ids = context.setdefault(self.CONTEXT_KEY, {})
ret = []
for x in result:
visited = False
if isinstance(x, Request):
if self.FILTER_VISITED in x.meta:
visit_id = self._visited_id(x)
if visit_id in visited_ids:
log.msg("Ignoring already visited: %s" % x.url,
level=log.INFO, spider=spider)
visited = True
elif isinstance(x, BaseItem):
visit_id = self._visited_id(response.request)
if visit_id:
visited_ids[visit_id] = True
x['visit_id'] = visit_id
x['visit_status'] = 'new'
if visited:
ret.append(MyItem(visit_id=visit_id, visit_status='old'))
else:
ret.append(x)
return ret
def _visited_id(self, request):
return request.meta.get(self.VISITED_ID) or request_fingerprint(request)
我的目的是让蜘蛛本身忽略已经被抓取的网页,而不是将抓取的网页放在列表中,并在每次页面被列入或不与列表匹配时进行匹配。
对此有任何想法。
答案 0 :(得分:1)
您没有给出Spider的代码示例,但是,在调用dont_filter = True
方法时,您可能会传递参数Request
。尝试明确指定Request(dont_filter=False)
。这向蜘蛛指出他不必重复相同的请求。