Scrapy: 如何从其他 python 脚本中 运行 spider 两次或更多次?

Scrapy: How to run spider from other python script twice or more?

Scrapy版本:1.0.5

我搜索了很长时间,但大多数解决方法在当前的 Scrapy 版本中都不起作用。

我的蜘蛛是在jingdong_spider.py中定义的,运行蜘蛛的接口(通过Scrapy Documentation学习)如下:

# 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

然后在temp.py我会把上面的search(keyword)调用给运行 spider.

现在的问题是:我调用了 search(keyword) 一次,它起作用了 well.But 我调用了两次,例如,

在temp.py

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

它报道:

Traceback (most recent call last): File "C:/Users/jiahao/Desktop/code/bbt_climb_plus/temp.py", line 7, in search('ipad2') File "C:\Users\jiahao\Desktop\code\bbt_climb_plus\bbt_climb_plus\spiders\jingdong_spider.py", line 194, in search reactor.run() # the script will block here until the crawling is finished File "C:\Python27\lib\site-packages\twisted\internet\base.py", line 1193, in run self.startRunning(installSignalHandlers=installSignalHandlers) File "C:\Python27\lib\site-packages\twisted\internet\base.py", line 1173, in startRunning ReactorBase.startRunning(self) File "C:\Python27\lib\site-packages\twisted\internet\base.py", line 684, in startRunning raise error.ReactorNotRestartable() twisted.internet.error.ReactorNotRestartable

第一次搜索(关键字)成功,但后者出错了

你能帮忙吗?

在您的代码示例中,您正在调用 twisted.reactor 在每次函数调用时启动它。这是行不通的,因为每个进程只有一个反应器,你不能 start it twice

有两种方法可以解决您的问题,都在 documentation here 中进行了描述。坚持使用 CrawlerRunner 但将 reactor.run() 移到 search() 函数之外,以确保它只被调用一次。或者使用 CrawlerProcess 并简单地调用 crawler_process.start()。第二种方法更简单,您的代码如下所示:

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()

正如 Pawel Miech 所说

In your code sample you are making calls to twisted.reactor starting it on every function call. This is not working because there is only one reactor per process and you cannot start it twice.

我找到了解决问题的方法。仅使用多处理。

它会像:

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()

如果大家在使用python-multiprocessing时遇到问题。最好看看 python 文档。