programa - ejecutar un script desde python
Cómo ejecutar Scrapy desde dentro de una secuencia de comandos de Python (6)
Soy nuevo en Scrapy y estoy buscando una forma de ejecutarlo desde un script de Python. Encontré 2 fuentes que explican esto:
http://tryolabs.com/Blog/2011/09/27/calling-scrapy-python-script/
http://snipplr.com/view/67006/using-scrapy-from-a-script/
No puedo entender dónde debería poner mi código de araña y cómo llamarlo desde la función principal. Por favor ayuda. Este es el código de ejemplo:
# 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 __name__ == "__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
Gracias.
Aunque no lo he probado, creo que la respuesta se puede encontrar en la documentación de scrapy . Para citar directamente de ella:
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
Por lo que veo, este es un nuevo desarrollo en la biblioteca que hace que algunos de los enfoques anteriores en línea (como el de la pregunta) sean obsoletos.
Cuando se deben ejecutar múltiples rastreadores dentro de una secuencia de comandos python, la parada del reactor debe manejarse con precaución, ya que el reactor solo puede detenerse una vez y no puede reiniciarse.
Sin embargo, mientras hacía mi proyecto encontré que usar
os.system("scrapy crawl yourspider")
es el más fácil Esto me ahorrará manejar todo tipo de señales, especialmente cuando tengo múltiples arañas.
Si el rendimiento es una preocupación, puede usar multiproceso para ejecutar sus arañas en paralelo, algo así como:
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)
En scrapy 0.19.x debes hacer esto:
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
Tenga en cuenta estas líneas
settings = get_project_settings()
crawler = Crawler(settings)
Sin él, su araña no usará su configuración y no guardará los elementos. Me tomó un tiempo averiguar por qué el ejemplo en la documentación no guardaba mis artículos. Envié una solicitud de extracción para corregir el ejemplo del documento.
Uno más para hacerlo es simplemente llamar al comando directamente desde su script
from scrapy import cmdline
cmdline.execute("scrapy crawl followall".split()) #followall is the spider''s name
Copié esta respuesta de mi primera respuesta aquí: https://.com/a/19060485/1402286
Si desea ejecutar un rastreo simple, es fácil simplemente ejecutando el comando:
scrapy crawl. Hay otras opciones para exportar sus resultados para almacenar en algunos formatos como: Json, xml, csv.
scrapy crawl -o result.csv o result.json o result.xml.
es posible que desee probarlo
Todas las demás respuestas hacen referencia a Scrapy v0.x. De acuerdo con los documentos actualizados , 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
# -*- coding: utf-8 -*-
import sys
from scrapy.cmdline import execute
def gen_argv(s):
sys.argv = s.split()
if __name__ == ''__main__'':
gen_argv(''scrapy crawl abc_spider'')
execute()
Ponga este código en la ruta, puede ejecutar scrapy crawl abc_spider
desde la línea de comandos. (Probado con Scrapy == 0.24.6)