2017-01-05 14 views
3
再開可能

Scrapy - 原子炉ではないと

process = CrawlerProcess(get_project_settings()) 
process.crawl(*args) 
# the script will block here until the crawling is finished 
process.start() 

が、私はそうのようなweb_crawler(self)機能、にこのコードを移動したので、::

私はいつもsucessfullyこのプロセスを実行してきました

from twisted.internet import reactor 
from scrapy.crawler import CrawlerProcess 

def web_crawler(self): 
    # set up a crawler 
    process = CrawlerProcess(get_project_settings()) 
    process.crawl(*args) 
    # the script will block here until the crawling is finished 
    process.start() 

    # (...) 

    return (result1, result2) 

などのクラスインスタンス化を使用してメソッドを呼び出すように開始しました。

def __call__(self): 
    results1 = test.web_crawler()[1] 
    results2 = test.web_crawler()[0] 

とランニング:

test() 

私は、次のエラーを取得しています:

Traceback (most recent call last): 
    File "test.py", line 573, in <module> 
    print (test()) 
    File "test.py", line 530, in __call__ 
    artists = test.web_crawler() 
    File "test.py", line 438, in web_crawler 
    process.start() 
    File "/Library/Python/2.7/site-packages/scrapy/crawler.py", line 280, in start 
    reactor.run(installSignalHandlers=False) # blocking call 
    File "/Library/Python/2.7/site-packages/twisted/internet/base.py", line 1194, in run 
    self.startRunning(installSignalHandlers=installSignalHandlers) 
    File "/Library/Python/2.7/site-packages/twisted/internet/base.py", line 1174, in startRunning 
    ReactorBase.startRunning(self) 
    File "/Library/Python/2.7/site-packages/twisted/internet/base.py", line 684, in startRunning 
    raise error.ReactorNotRestartable() 
twisted.internet.error.ReactorNotRestartable 

何が間違っていますか?

+0

スクリプトごとに2回 "web_crawler()"を実行していますか?ねじれた反応器を2回以上始動することはできません。 – Rejected

+0

私は気付いていません。私がやっていることは、クラス関数でクローラ関数を定義し、__call__メソッドでプロセスを実行することです。 'results' = test.web_crawler()のようになります。 –

+0

@Rejected私は質問を編集しました、ありがとう –

答えて

4

あなたは原子炉を再起動することはできませんが、あなたはでそれを複数回実行することができますその後

print('first run:') 
run_spider() 

print('\nsecond run:') 
run_spider() 

ん実行を実行している

import scrapy 
import scrapy.crawler as crawler 
from multiprocessing import Process, Queue 
from twisted.internet import reactor 

# your spider 
class QuotesSpider(scrapy.Spider): 
    name = "quotes" 
    start_urls = ['http://quotes.toscrape.com/tag/humor/'] 

    def parse(self, response): 
     for quote in response.css('div.quote'): 
      print(quote.css('span.text::text').extract_first()) 


# the wrapper to make it run more times 
def run_spider(): 
    def f(q): 
     try: 
      runner = crawler.CrawlerRunner() 
      deferred = runner.crawl(QuotesSpider) 
      deferred.addBoth(lambda _: reactor.stop()) 
      reactor.run() 
      q.put(None) 
     except Exception as e: 
      q.put(e) 

    q = Queue() 
    p = Process(target=f, args=(q,)) 
    p.start() 
    result = q.get() 
    p.join() 

    if result is not None: 
     raise result 


print('first run:') 
run_spider() 

print('\nsecond run:') 
run_spider() 

:別のプロセスをforkその二回:

first run: 
“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.” 
“A day without sunshine is like, you know, night.” 
... 

second run: 
“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.” 
“A day without sunshine is like, you know, night.” 
... 
+0

それは私のために働いた....ありがとう。 – Prateek

1

Scrapy documentationごとに、CrawlerProcessクラスのstart()方法は以下のとおりん:

"[...] starts a Twisted reactor, adjusts its pool size to REACTOR_THREADPOOL_MAXSIZE, and installs a DNS cache based on DNSCACHE_ENABLED and DNSCACHE_SIZE."

ツイスト原子炉を再起動することはできませんので、あなたが受けているエラーは、Twistedによってスローされています。大量のグローバルを使用しています。たとえジミーリグを使ってコードを再起動しても(それは終わったと思いますが)、動作する保証はありません。

正直言って、原子炉を再始動する必要があると思うなら、間違ったことをしている可能性が高いです。

あなたのやりたいことに応じて、ドキュメントのRunning Scrapy from a Scriptも確認します。

1

間違いは、このコードである:

def __call__(self): 
    result1 = test.web_crawler()[1] 
    result2 = test.web_crawler()[0] # here 

web_crawler()は二つの結果を返し、@Rejectedで指摘したようにその目的のためには、原子炉を再起動し、二回のプロセスを起動しようとしています。

1つのプロセスを実行し、結果を取得し、タプルで両方の結果を保存するには、ここに行くための方法です:

def __call__(self): 
    result1, result2 = test.web_crawler() 
0

これはreactor.run()またはprocess.start()後のコードの下に入れて、私の問題を解決しました:

time.sleep(0.5) 

os.execl(sys.executable, sys.executable, *sys.argv) 
+0

コードブロックをハイライトし、ctrl + K(windows)またはcommand + K(mac)を押してコードブロックを囲むことで、 – 0TTT0

0

をこれは私がReactorNotRestartableエラーとの戦いに勝つためにのために役立ったものです:last answer from the author of the question
0)pip install crochet
1)import from crochet import setup
2)setup() - ファイルの先頭にある
3)2を削除するライン:
A)d.addBoth(lambda _: reactor.stop())
B)reactor.run()

私はこのエラーと同じ問題を抱えていたし、それについてここではすべての質問を読んで、この問題を解決するため4+時間を費やしています。最後にそれを発見し、それを共有します。それが私がこれを解決した方法です。別のクモを選択し、[ -

#some more imports 
from crochet import setup 
setup() 

def run_spider(spiderName): 
module_name="first_scrapy.spiders.{}".format(spiderName) 
scrapy_var = import_module(module_name) #do some dynamic import of selected spider 
spiderObj=scrapy_var.mySpider()   #get mySpider-object from spider module 
crawler = CrawlerRunner(get_project_settings()) #from Scrapy docs 
crawler.crawl(spiderObj)       #from Scrapy docs 

このコードは、私はちょうどrun_spider関数に渡され、その名前とし、仕上げを解体した後に実行するためにどのようなクモを選択することができます:Scrapy docs左からのみ意味のある行は、この私のコードでは2つの最後の行ですもう一度実行してください。
これは私の助けとして、これが誰かを助けることを願っています:)

関連する問題