Промежуточный паук в порции не называется
Я адаптировал код с помощью Middleware, чтобы игнорировать дубликаты в Scrapy.
from scrapy.exceptions import DropItem
from scrapy import log
import os.path
class IgnoreDuplicates():
def __init__(self):
self._cu_file = open("crawled_urls.txt", "a+")
self._crawled_urls = set([line.strip() for line in self._cu_file.readlines()])
def process_request(self, request, spider):
if request.url in self._crawled_urls:
raise DropItem("Duplicate product scrape caught by IgnoreDuplicates at <%s>" % (url))
else:
self._crawled_urls.add(request.url)
self._cu_file.write(request.url + '\n')
log.msg("IgnoreDuplicates recorded this url " + request.url, level=log.DEBUG)
return None
Я также добавил модуль промежуточного программного обеспечения в settings.py:
SPIDER_MANAGER_CLASS = 'slybot.spidermanager.SlybotSpiderManager'
EXTENSIONS = {'slybot.closespider.SlybotCloseSpider': 1}
ITEM_PIPELINES = {'slybot.dupefilter.DupeFilterPipeline': 1}
SPIDER_MIDDLEWARES = {'slybot.middleware.IgnoreDuplicates': 500, 'slybot.spiderlets.SpiderletsMiddleware': 999} # as close as possible to spider output
PLUGINS = ['slybot.plugins.scrapely_annotations.Annotations']
SLYDUPEFILTER_ENABLED = True
PROJECT_DIR = 'slybot-project'
FEED_EXPORTERS = {
'csv': 'slybot.exporter.SlybotCSVItemExporter',
}
CSV_EXPORT_FIELDS = None
try:
from local_slybot_settings import *
except ImportError:
pass
Функция process_request не вызывается. Я попытался изменить значение ключа промежуточного программного обеспечения в settings.py, чтобы оно выполнялось до и после SpiderletsMiddleware. Но исключение и сообщение журнала не отображаются в выходных данных.
Как убедиться, что промежуточное программное обеспечение называется?
1 ответ
Функция обратного вызова отличается для промежуточного программного обеспечения паука. Я использовал код из этого фрагмента в качестве ссылки: http://snipplr.com/view/67018/middleware-to-avoid-revisiting-already-visited-items/
Вот рабочая версия кода промежуточного программного обеспечения, который я разместил в вопросе.
from scrapy.http import Request
from scrapy import log
import os.path
class IgnoreVisitedItems(object):
def __init__(self):
# Load the URLs that have already been crawled
self._cu_file = open("crawled_urls.txt", "a+")
self._crawled_urls = set([line.strip() for line in self._cu_file.readlines()])
def process_spider_output(self, response, result, spider):
ret = []
for x in result:
# Find the URL in the result or response
url = None
if isinstance(x, Request):
url = x.url
else:
url = response.request.url
# Check if the URL has been crawled, and add
# it to the list of crawled URLs.
if url in self._crawled_urls:
log.msg("Ignoring already visited: %s" % url,
level=log.INFO, spider=spider)
else:
log.msg("Adding %s to list of visited urls" % url,
level=log.INFO, spider=spider)
self._cu_file.write(url + '\n')
self._crawled_urls.add(url)
ret.append(x)
return ret