J'ai un projet scrapy qui contient plusieurs spiders. Existe-t-il un moyen de définir les pipelines à utiliser pour chaque spider ? Tous les pipelines que j'ai définis ne sont pas applicables pour chaque spider.
Merci
J'ai un projet scrapy qui contient plusieurs spiders. Existe-t-il un moyen de définir les pipelines à utiliser pour chaque spider ? Tous les pipelines que j'ai définis ne sont pas applicables pour chaque spider.
Merci
Pour ceux qui, comme moi, se demandent ce qu'est le '400' - DU DOC - "Les valeurs entières que vous attribuez aux classes dans ce paramètre déterminent l'ordre dans lequel elles sont exécutées : les éléments passent des classes de valeur inférieure aux classes de valeur supérieure. Il est d'usage de définir ces nombres dans la plage 0-1000". docs.scrapy.org/fr/latest/topics/item-pipeline.html
Je ne sais pas pourquoi ce n'est pas la réponse acceptée, cela fonctionne parfaitement, beaucoup plus propre et plus simple que la réponse acceptée. C'est exactement ce que je recherchais. Fonctionne toujours dans scrapy 1.8
Je viens de vérifier dans scrapy 1.6. Il n'est pas nécessaire de supprimer les paramètres du pipeline dans settings.py. Les custom_settings dans le spider remplacent les paramètres du pipeline dans settings.py.
Construire sur la solution de Pablo Hoffman vous pouvez utiliser le décorateur suivant sur l'objet process_item
d'un objet Pipeline afin qu'il vérifie la méthode pipeline
de votre araignée pour savoir si elle doit être exécutée ou non. Par exemple :
def check_spider_pipeline(process_item_method):
@functools.wraps(process_item_method)
def wrapper(self, item, spider):
# message template for debugging
msg = '%%s %s pipeline step' % (self.__class__.__name__,)
# if class is in the spider's pipeline, then use the
# process_item method normally.
if self.__class__ in spider.pipeline:
spider.log(msg % 'executing', level=log.DEBUG)
return process_item_method(self, item, spider)
# otherwise, just return the untouched item (skip this step in
# the pipeline)
else:
spider.log(msg % 'skipping', level=log.DEBUG)
return item
return wrapper
Pour que ce décorateur fonctionne correctement, l'araignée doit avoir un attribut pipeline avec un conteneur des objets Pipeline que vous voulez utiliser pour traiter l'élément, par exemple :
class MySpider(BaseSpider):
pipeline = set([
pipelines.Save,
pipelines.Validate,
])
def parse(self, response):
# insert scrapy goodness here
return item
Et puis dans un pipelines.py
fichier :
class Save(object):
@check_spider_pipeline
def process_item(self, item, spider):
# do saving here
return item
class Validate(object):
@check_spider_pipeline
def process_item(self, item, spider):
# do validating here
return item
Tous les objets Pipeline devraient toujours être définis dans ITEM_PIPELINES dans les paramètres (dans l'ordre correct -- il serait bien de changer pour que l'ordre puisse être spécifié sur le Spider, aussi).
Les autres solutions données ici sont bonnes, mais je pense qu'elles pourraient être lentes, parce que nous ne sommes pas vraiment pas Nous n'utilisons pas le pipeline par araignée, mais nous vérifions si un pipeline existe à chaque fois qu'un élément est renvoyé (et dans certains cas, cela peut atteindre des millions).
Une bonne façon de désactiver (ou d'activer) complètement une fonctionnalité par araignée est d'utiliser custom_setting
y from_crawler
pour toutes les extensions de ce type :
pipelines.py
from scrapy.exceptions import NotConfigured
class SomePipeline(object):
def __init__(self):
pass
@classmethod
def from_crawler(cls, crawler):
if not crawler.settings.getbool('SOMEPIPELINE_ENABLED'):
# if this isn't specified in settings, the pipeline will be completely disabled
raise NotConfigured
return cls()
def process_item(self, item, spider):
# change my item
return item
paramètres.py
ITEM_PIPELINES = {
'myproject.pipelines.SomePipeline': 300,
}
SOMEPIPELINE_ENABLED = True # you could have the pipeline enabled by default
spider1.py
class Spider1(Spider):
name = 'spider1'
start_urls = ["http://example.com"]
custom_settings = {
'SOMEPIPELINE_ENABLED': False
}
Comme vous le vérifiez, nous avons spécifié custom_settings
qui remplacera les éléments spécifiés dans settings.py
et nous désactivons SOMEPIPELINE_ENABLED
pour cette araignée.
Maintenant, quand vous exécutez ce spider, vérifiez quelque chose comme :
[scrapy] INFO: Enabled item pipelines: []
Maintenant, scrapy a complètement désactivé le pipeline, sans se soucier de son existence pendant toute la durée de l'exécution. Vérifiez que cela fonctionne aussi pour scrapy extensions
y middlewares
.
Je peux penser à au moins quatre approches :
scrapy settings
entre chaque invocation de votre araignéedefault_settings['ITEM_PIPELINES']
sur votre classe de commande à la liste de pipeline que vous voulez pour cette commande. Voir ligne 6 de cet exemple .process_item()
vérifie contre quelle araignée il est exécuté, et ne fait rien s'il doit être ignoré pour cette araignée. Voir le exemple d'utilisation des ressources par araignée pour vous aider à démarrer. (Cette solution semble être laide car elle couple étroitement les spiders et les pipelines d'articles. Vous ne devriez probablement pas utiliser celle-ci). Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
3 votes
Merci pour votre très bonne question. Veuillez sélectionner une réponse pour tous les futurs googleurs. La réponse fournie par mstringer a très bien fonctionné pour moi.