2015-04-28 1 views
2

Я разбираю большой XML-файл с помощью scrapy и выдаю запрос и элемент на каждом узле (я вхожу в него) из XML.Scrapy не выполняет запросы во время обработки XML

Что происходит, так это то, что XML-файл сначала полностью обрабатывается, и элементы, которые я сдаю, успешно передают мои конвейеры элементов, и после того, как это сделано, scrapy начинает обрабатывать все запросы, которые я дал вместе с элементами.

Я хочу, чтобы эта процедура выполняла запросы немедленно, когда я их возвращаю, а не после анализа всего XML.

Scrapy doesn't seem to be doing DFO

Этот ответ предлагает использовать

# change to breadth first 
DEPTH_PRIORITY = 1 
SCHEDULER_DISK_QUEUE = 'scrapy.squeue.PickleFifoDiskQueue' 
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeue.FifoMemoryQueue' 

, который я сделал, но, к сожалению, не принесли никакого эффекта (то есть запросы не выполняются immedeately либо).

Logfile выглядит следующим образом: (фильтруется для элементов)

2015-04-28 12:37:15+0200 [scraper] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 
2015-04-28 12:38:15+0200 [scraper] INFO: Crawled 2 pages (at 2 pages/min), scraped 6375 items (at 6375 items/min) 
2015-04-28 12:39:15+0200 [scraper] INFO: Crawled 2 pages (at 0 pages/min), scraped 11619 items (at 5244 items/min) 
2015-04-28 12:40:15+0200 [scraper] INFO: Crawled 2 pages (at 0 pages/min), scraped 14302 items (at 2683 items/min) 

код выглядит примерно так:

class XMLSpider(scrapy.Spider): 
    start_urls = [big_xml_url] 
    def parse(self, response): 
     with tempfile.TemporaryFile() as tmpfile: 
      tmpfile.write(response.body) 
      tmpfile.seek(0) 
      for event, elem in ET.iterparse(tmpfile, ('end',)): 
       if elem.tag == 'interesting_tag': 
        ret = self.parse_node(response, elem) 
        try: 
         for item in ret: 
          yield item 
        except TypeError: 
         if ret: # check if item is not None 
          yield ret 

        elem.clear() 
    def parse_node(self, response, elem): 
    yield Item(elem.find(), elem.find()) 
    yield Request(url=elem.find(urlfield), callback=self.parse_detail) 
    def parse_detail(self, response): 
    # This code is executed in the very end unfortunately... 
+0

Почему имеет значение, в каком порядке они выполнены? Процесс является асинхронным без цели, но все запросы будут выполняться, когда это будет лучше всего. – bosnjak

+0

Это имеет значение, потому что разбор XML (и получение предметов) стоит около 7 часов. Это 7 часов, в течение которых сервер не попал, и я хочу поразить его как можно более сбалансированным. На самом деле, сейчас искатель нуждается в этих 7 часах больше, чем нужно. – moritzschaefer

+1

Можете ли вы показать свой код паука? Минимальный пример. – bosnjak

ответ

0

Ну, почему бы не попробовать вернуть как товар и запрос от метода parse_node ? В этом случае вы знаете, что первым элементом является Item или None, второй - Request или None. Если запрос не None, вы получаете запрос на дальнейшее выполнение и сохраняете элементы в коллекции и получаете их при завершении цикла for.

В качестве альтернативы вы можете вручную скачать URL-адрес, который вы найдете, и вызвать parse_detail с результатом (который, конечно же, не будет Scrapy Response).

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