2017-09-21 8 views
0

私はpython-telegram-bot APIラッパーを使ってTelegramボットで治療用スパイダーを動こうとしています。以下のコードを使用すると、スパイダーを正常に実行してスクラップした結果をボットに転送できますが、スクリプトを実行してからは1回だけです。私がbot(telegram botコマンド)を介してスパイダーを再実行しようとすると、エラーtwisted.internet.error.ReactorNotRestartableが出ます。ねじれた反応器が治療で再開しない

from twisted.internet import reactor 
from scrapy import cmdline 
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, RegexHandler 
import logging 
import os 
import ConfigParser 
import json 
import textwrap 
from MIS.spiders.moodle_spider import MySpider 
from scrapy.utils.project import get_project_settings 
from scrapy.crawler import CrawlerRunner, CrawlerProcess 
from scrapy.utils.log import configure_logging 


# Read settings from config file 
config = ConfigParser.RawConfigParser() 
config.read('./spiders/creds.ini') 
TOKEN = config.get('BOT', 'TOKEN') 
#APP_NAME = config.get('BOT', 'APP_NAME') 
#PORT = int(os.environ.get('PORT', '5000')) 
updater = Updater(TOKEN) 

# Setting Webhook 
#updater.start_webhook(listen="0.0.0.0", 
#      port=PORT, 
#      url_path=TOKEN) 
#updater.bot.setWebhook(APP_NAME + TOKEN) 

logging.basicConfig(format='%(asctime)s -# %(name)s - %(levelname)s - %(message)s',level=logging.INFO) 

dispatcher = updater.dispatcher 

# Real stuff 

def doesntRun(bot, update): 
    #process = CrawlerProcess(get_project_settings()) 
    #process.crawl(MySpider) 
    #process.start() 
    ############ 

    configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'}) 
    runner = CrawlerRunner({ 
     'FEED_FORMAT' : 'json', 
     'FEED_URI' : 'output.json' 
     }) 

    d = runner.crawl(MySpider) 
    d.addBoth(lambda _: reactor.stop()) 
    reactor.run(installSignalHandlers=0) # the script will block here until the crawling is finished 
    #reactor.stop() 

    with open("./output.json", 'r') as file: 
     contents = file.read() 
     a_r = json.loads(contents) 
     AM = a_r[0]['AM'] 
     ... 
     ... 

     message_template = textwrap.dedent(""" 
       AM: {AM} 
       ... 
       """) 
     messageContent = message_template.format(AM=AM, ...) 
     #print messageContent 
     bot.sendMessage(chat_id=update.message.chat_id, text=messageContent) 
     #reactor.stop() 


# Handlers 
test_handler = CommandHandler('doesntRun', doesntRun) 

# Dispatchers 
dispatcher.add_handler(test_handler) 

updater.start_polling() 
updater.idle() 

私はドキュメントからのコードを使用しています:https://doc.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script

コードは次のようになります:

from twisted.internet import reactor 
import scrapy 
from scrapy.crawler import CrawlerRunner 
from scrapy.utils.log import configure_logging 

class MySpider(scrapy.Spider): 
    # Your spider definition 
    ... 

configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'}) 
runner = CrawlerRunner() 

d = runner.crawl(MySpider) 
d.addBoth(lambda _: reactor.stop()) 
reactor.run() # the script will block here until the crawling is finished 
+0

重複するhttps://stackoverflow.com/questions/39946632/reactornotrestartable-error-in-while-loop-with-scrapy – rak007

+0

リンクされた重複した質問には決定的な回答さえありません。私のコードで 'CrawlerRunner'を使用するのではなく、' CrawlerProcess'を使用しています。 –

+0

これらのヘルプhttps://stackoverflow.com/questions/1979112/connecting-twice-with-twisted-how-to-do-that-c​​orrectly、https://www.blog.pythonlibrary.org/2016/09を参照してください。/14 /再始動 - 撚り反応器/。それを行う理想的な方法は、scrapydを使用し、同じものを使用してスクレーパーをスケジュールすることです –

答えて

0

わかりましたが、私はようやく私の問題を解決しました。 doesntRun()関数の最後に

time.sleep(0.2) 
os.execl(sys.executable, sys.executable, *sys.argv) 

のPython-電報ボットAPIラッパーがan easy way to restart the bot.

を提供しています私は単に行を置きます。今では、私がbotを介して関数を呼び出すたびに、ページをスクラップし、結果を格納し、結果を転送してから、自身を再起動します。そうすることで、スパイダーを何回でも実行できるようになります。

関連する問題