Je suis nouveau sur Scrapy et je cherche un moyen de l'exécuter à partir d'un script Python. J'ai trouvé 2 sources qui expliquent cela:
http://tryolabs.com/Blog/2011/09/27/calling-scrapy-python-script/
http://snipplr.com/view/67006/using-scrapy-from-a-script/
Je ne peux pas comprendre où je dois mettre mon code araignée et comment l'appeler à partir de la fonction principale. Veuillez aider. Voici l'exemple de code:
# This snippet can be used to run scrapy spiders independent of scrapyd or the scrapy command line tool and use it from a script.
#
# The multiprocessing library is used in order to work around a bug in Twisted, in which you cannot restart an already running reactor or in this case a scrapy instance.
#
# [Here](http://groups.google.com/group/scrapy-users/browse_thread/thread/f332fc5b749d401a) is the mailing-list discussion for this snippet.
#!/usr/bin/python
import os
os.environ.setdefault('SCRAPY_SETTINGS_MODULE', 'project.settings') #Must be at the top before other imports
from scrapy import log, signals, project
from scrapy.xlib.pydispatch import dispatcher
from scrapy.conf import settings
from scrapy.crawler import CrawlerProcess
from multiprocessing import Process, Queue
class CrawlerScript():
def __init__(self):
self.crawler = CrawlerProcess(settings)
if not hasattr(project, 'crawler'):
self.crawler.install()
self.crawler.configure()
self.items = []
dispatcher.connect(self._item_passed, signals.item_passed)
def _item_passed(self, item):
self.items.append(item)
def _crawl(self, queue, spider_name):
spider = self.crawler.spiders.create(spider_name)
if spider:
self.crawler.queue.append_spider(spider)
self.crawler.start()
self.crawler.stop()
queue.put(self.items)
def crawl(self, spider):
queue = Queue()
p = Process(target=self._crawl, args=(queue, spider,))
p.start()
p.join()
return queue.get(True)
# Usage
if __== "__main__":
log.start()
"""
This example runs spider1 and then spider2 three times.
"""
items = list()
crawler = CrawlerScript()
items.append(crawler.crawl('spider1'))
for i in range(3):
items.append(crawler.crawl('spider2'))
print items
# Snippet imported from snippets.scrapy.org (which no longer works)
# author: joehillen
# date : Oct 24, 2010
Merci.
Toutes les autres réponses font référence à Scrapy v0.x. Selon les documents mis à jour , Scrapy 1.0 exige:
import scrapy
from scrapy.crawler import CrawlerProcess
class MySpider(scrapy.Spider):
# Your spider definition
...
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})
process.crawl(MySpider)
process.start() # the script will block here until the crawling is finished
Bien que je ne l'ai pas essayé, je pense que la réponse peut être trouvée dans le documentation sommaire . Pour en citer directement:
from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy.settings import Settings
from scrapy import log
from testspiders.spiders.followall import FollowAllSpider
spider = FollowAllSpider(domain='scrapinghub.com')
crawler = Crawler(Settings())
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
reactor.run() # the script will block here
D'après ce que je comprends, il s'agit d'un nouveau développement dans la bibliothèque qui rend obsolètes certaines des anciennes approches en ligne (comme celle de la question).
Dans scrapy 0.19.x, vous devriez faire ceci:
from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy import log, signals
from testspiders.spiders.followall import FollowAllSpider
from scrapy.utils.project import get_project_settings
spider = FollowAllSpider(domain='scrapinghub.com')
settings = get_project_settings()
crawler = Crawler(settings)
crawler.signals.connect(reactor.stop, signal=signals.spider_closed)
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
reactor.run() # the script will block here until the spider_closed signal was sent
Notez ces lignes
settings = get_project_settings()
crawler = Crawler(settings)
Sans elle, votre araignée n'utilisera pas vos paramètres et ne sauvegardera pas les éléments. Cela m'a pris un certain temps pour comprendre pourquoi l'exemple dans la documentation ne sauvegardait pas mes articles. J'ai envoyé une demande d'extraction pour corriger l'exemple de doc.
Pour cela, il suffit d'appeler la commande directement à partir de votre script
from scrapy import cmdline
cmdline.execute("scrapy crawl followall".split()) #followall is the spider's name
Copié cette réponse de ma première réponse ici: https://stackoverflow.com/a/19060485/1402286
Lorsqu'il y a plusieurs robots d'exploration à exécuter dans un seul script python, l'arrêt du réacteur doit être géré avec précaution car le réacteur ne peut être arrêté qu'une seule fois et ne peut pas être redémarré.
Cependant, j'ai trouvé en faisant mon projet qu'en utilisant
os.system("scrapy crawl yourspider")
est le plus simple. Cela m'évitera de gérer toutes sortes de signaux, surtout lorsque j'ai plusieurs araignées.
Si les performances sont un problème, vous pouvez utiliser le multitraitement pour exécuter vos araignées en parallèle, quelque chose comme:
def _crawl(spider_name=None):
if spider_name:
os.system('scrapy crawl %s' % spider_name)
return None
def run_crawler():
spider_names = ['spider1', 'spider2', 'spider2']
pool = Pool(processes=len(spider_names))
pool.map(_crawl, spider_names)
Nous pouvons simplement utiliser
from scrapy.crawler import CrawlerProcess
from project.spiders.test_spider import SpiderName
process = CrawlerProcess()
process.crawl(SpiderName, arg1=val1,arg2=val2)
process.start()
Utilisez ces arguments à l'intérieur de l'araignée __init__
fonction avec la portée globale.