2016-04-05 5 views
3

Scrapy Version: 1.0.5Scrapy: Wie Spinne aus anderem Python-Skript läuft zweimal oder mehr

Ich habe lange gesucht, aber die meisten von Abhilfen funktionieren nicht in der aktuellen Version Scrapy.

Meine Spinne ist in jingdong_spider.py definiert, und die Schnittstelle (lernen es von Scrapy Documentation) Spinne laufen unter:

# interface 
def search(keyword): 
    configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'}) 
    runner = CrawlerRunner() 
    d = runner.crawl(JingdongSpider,keyword) 
    d.addBoth(lambda _: reactor.stop()) 
    reactor.run() # the script will block here until the crawling is finished 

Dann in temp.py werde ich die search(keyword) oben nennen Spinne laufen.

Nun das Problem: Ich rief Suche (Stichwort) einmal, und es funktionierte well.But ich es zweimal genannt, zum Beispiel

in temp.py

search('iphone') 
search('ipad2') 

berichtet:

Traceback (jüngste Aufforderung zuletzt): Datei "C: /Users/jiahao/Desktop/code/bbt_climb_plus/temp.py", Linie 7, in search ('ipad2') Datei „C: \ Benutzer \ Jiahao \ Desktop \ code \ bbt_climb_plus \ bbt_climb_plus \ Spinnen \ jingdong_spider.py " Linie 194, auf der Suche reactor.run() # das Skript hier blockiert, bis die Crawling Datei beendet ist " C: \ Python27 \ lib \ site-packages \ twisted \ internet \ base.py ", Zeile 1193, im Lauf self.startRunning (installSignalHandlers = installSignalHandlers) Datei" C: \ Python27 \ lib \ site-packages \ twisted \ internet \ base.py ", Zeile 1173, in StartRunning ReactorBase.startRunning (self) Datei "C: \ Python27 \ lib \ Site-Pakete \ twisted \ internet \ base.py", Zeile 684, in startRunning Raise error.ReactorNotRestartable() verdreht. internet.error.ReactorNotRestartable

Die erste Suche (Stichwort) ist gelungen, aber letzteres ist falsch gelaufen.

Können Sie mir helfen?

Antwort

2

Wie Pawel Miech sagte

In Ihrem Codebeispiel Sie Anrufe machen es auf jedem Funktionsaufruf twisted.reactor starten. Dies funktioniert nicht, weil es nur einen Reaktor pro Prozess gibt und Sie können es nicht zweimal starten.

Ich habe einen Weg gefunden, mein Problem zu lösen. Einfach Multiprocessing verwenden.

from multiprocessing import Process 
def run_spider(keyword): 
    if __name__ == '__main__': 
     p = Process(target=jingdong_spider.search, args=(keyword.encode('utf-8'),)) 
     p.start() 
     p.join() 

Wenn alle Probleme bei der Verwendung Python-Multiprozessing hat:

wird es sein. Sehen Sie sich die Python-Dokumentation genauer an.

+0

Obwohl es eine ungeeignete Problemumgehung ist, funktioniert es gut. Du hast meinen Tag gerettet! Ich hatte 50 Minuten Zeit, um mein Projekt arbeiten zu lassen. – alierdogan7

3

In Ihrem Codebeispiel tätigen Sie Aufrufe an twisted.reactor und starten es bei jedem Funktionsaufruf. Dies funktioniert nicht, da es nur einen Reaktor pro Prozess gibt und Sie können nicht start it twice.

Es gibt zwei Möglichkeiten, Ihr Problem zu lösen, beide beschrieben in documentation here. Entweder stecken Sie mit CrawlerRunner, aber bewegen Sie reactor.run() außerhalb Ihrer search() Funktion, um sicherzustellen, dass es nur einmal aufgerufen wird. Oder verwenden Sie CrawlerProcess und rufen Sie einfach crawler_process.start() an. Zweiter Ansatz ist einfacher, würde der Code wie folgt aussehen:

from scrapy.crawler import CrawlerProcess 
from dirbot.spiders.dmoz import DmozSpider 

def search(runner, keyword): 
    return runner.crawl(DmozSpider, keyword) 

runner = CrawlerProcess() 
search(runner, "alfa") 
search(runner, "beta") 
runner.start() 
+1

Danke. Ihre Antwort ist großartig, aber ich muss 'search (keyword)' verwenden, wenn ich etwas eingabe. d. h. "search (keyword)" muss aufgerufen werden, wenn der Benutzer etw tut (wie ein Klick-Button usw.). So kann "search (keyword)" nicht fest programmiert werden. Endlich löse ich mein Problem mit Multiprocessing. – guo

+1

Ich fürchte, ich habe es nicht klar erklärt. 'search (keyword)' kann zweimal, dreifach, vier mal aufgerufen werden ... Es kommt darauf an. – guo

Verwandte Themen