Scrapy在CrawlerProcess()之前运行Spider

时间:2018-02-15 11:48:14

标签: python-3.x web-scraping scrapy

我已经生成了一个新项目并且有一个包含我的蜘蛛的Python文件。 布局是:

import scrapy
from scrapy.http import *
import json
from scrapy.selector import HtmlXPathSelector
from scrapy.selector import Selector
import unicodedata
from scrapy import signals
from pydispatch import dispatcher
from scrapy.crawler import CrawlerProcess
from scrapy.item import Item, Field

class TrainerItem(Item):
    name = Field()
    brand = Field()
    link = Field()
    type = Field()
    price = Field()
    previous_price = Field()
    stock_img = Field()
    alt_img = Field()
    size = Field()

class SchuhSpider(scrapy.Spider):

    name = "SchuhSpider"
    payload = {"hash": "g=3|Mens,&c2=340|Mens Trainers&page=1&imp=1&o=new&",
               "url": "/imperfects/", "type": "pageLoad", "NonSecureUrl": "http://www.schuh.co.uk"}
    url = "http://schuhservice.schuh.co.uk/SearchService/GetResults"
    headers = {'Content-Type': 'application/json; charset=UTF-8'}

    finalLinks = []

    def start_requests(self):
        dispatcher.connect(self.quit, signals.spider_closed)
        yield scrapy.Request(url=self.url, callback=self.parse, method="POST", body=json.dumps(self.payload), headers=self.headers)


    def parse(self, response):
        ... do stuff ..

    def quit(self, spider):
        print(spider.name + " is about to die, here are your trainers..")

process = CrawlerProcess()
process.crawl(SchuhSpider)
process.start()
print("We Are Done.")

我使用以下方式运行此蜘蛛:

scrapy crawl SchuhSpider

我遇到的问题是:

  

twisted.internet.error.ReactorNotRestartable

这是因为蜘蛛实际上跑了两次。一旦开始(我收到了所有的POST请求),那么它就会说" SchuhSpider即将死去,这里有你的培训师......"。

然后它第二次打开蜘蛛,大概是当它完成过程时。

我的问题是:如何在脚本运行时让蜘蛛停止自动运行?

即使我跑:

scrapy list

它运行整个蜘蛛(我的所有POST请求都通过)。我担心我会遗漏一些明显但我无法看到的东西。

1 个答案:

答案 0 :(得分:0)

您可以通过两种方式混合运行蜘蛛。一种方法是现在就这样做,即使用

scrapy crawl SchuhSpider

命令。这样,不要(或者更好的是你不必)包含代码

process = CrawlerProcess()
process.crawl(SchuhSpider)
process.start()
print("We Are Done.")

因为只有当你想从脚本运行蜘蛛时才会这样做(参见documentation)。

如果你想保留以任何一种方式运行它的可能性,只需像上面这样包装上面的代码

if __name__ == '__main__':
    process = CrawlerProcess()
    process.crawl(SchuhSpider)
    process.start()
    print("We Are Done.")

以便在刚刚加载模块时不会运行(使用scrapy crawl运行它时的情况)。