2015-01-19 2 views
3

У меня есть ситуация, когда у меня есть CrawlSpider, который выполняет поиск результатов с использованием почтовых индексов и категорий (POST-данных). Мне нужно получить все результаты для всех категорий во всех почтовых кодах. Мой паук принимает почтовый индекс и категорию в качестве аргументов для данных POST. Я хочу программно запустить паук для каждого почтового кода/категории с помощью скрипта.Запуск нескольких пауков в одном процессе, один паук за раз

В документации объясняется, что вы можете запускать несколько пауков для каждого процесса с помощью этого примера кода здесь: http://doc.scrapy.org/en/latest/topics/practices.html#running-multiple-spiders-in-the-same-process Это то же самое, что я хочу сделать, однако я хочу, чтобы по существу очереди на пауков, чтобы запускать один за другим после предыдущего паука отделки.

Любые идеи о том, как это сделать? Кажется, что есть некоторые ответы, которые относятся к более старым версиям scrapy (~ 0.13), но архитектура изменилась, и они перестали функционировать с последней стабильностью (0.24.4)

ответ

1

Вы можете положиться на spider_closed signal, чтобы начать сканирование для следующий почтовый индекс/категория. Вот пример кода (не проверен) на основе this answer и принят для вашего прецедента:

from scrapy.crawler import Crawler 
from scrapy import log, signals 
from scrapy.settings import Settings 
from twisted.internet import reactor 

# for the sake of an example, sample postal codes 
postal_codes = ['10801', '10802', '10803'] 


def configure_crawler(postal_code): 
    spider = MySpider(postal_code) 

    # configure signals 
    crawler.signals.connect(callback, signal=signals.spider_closed) 

    # detach spider 
    crawler._spider = None 

    # configure and start the crawler 
    crawler.configure() 
    crawler.crawl(spider) 


# callback fired when the spider is closed 
def callback(spider, reason): 
    try: 
     postal_code = postal_codes.pop() 
     configure_crawler(postal_code) 
    except IndexError: 
     # stop the reactor if no postal codes left 
     reactor.stop() 


settings = Settings() 
crawler = Crawler(settings) 
configure_crawler(postal_codes.pop()) 
crawler.start() 

# start logging 
log.start() 

# start the reactor (blocks execution) 
reactor.run() 
+0

Отличный пример. После завершения первого паука и завершения обратного вызова при выполнении 'crawler.crawl (spider)' я получаю следующие следующие AssertionError: 'exceptions.AssertionError: Паук уже прикреплен. Не уверен, как справиться с этим – aaearon

+0

@aaearon спасибо за попробуйте! Я обновил код, добавляя строку для отсоединения паука от искателя, должен помочь. Хотя, это начинает быть чем-то вроде магии :) – alecxe

+0

Я нашел для того, чтобы это работало, как предполагалось, мне пришлось переместить инициализацию установки и искателя вместе с 'crawler.start()' внутри функции 'configure_crawler', иначе второй искатель начнет, но оставит место, где первый искатель не использовал новые данные, и будет зацикливаться на последнем URL-адресе. – aaearon

Смежные вопросы