2012-03-14 15 views
9

Mamy system napisany ze scrapy do przeszukiwania kilku stron internetowych. Istnieje kilka pająków i kilka kaskadowych potoków dla wszystkich elementów przekazywanych przez wszystkie roboty. Jeden z komponentów rurociągu wysyła zapytanie do serwerów google pod adresem geokodowania. Google nakłada limit 2500 żądań dziennie na adres IP i grozi zakazywaniem adresu IP, jeśli będzie kontynuował wysyłanie zapytań do google, nawet po tym, jak Google odpowiedział ostrzeżeniem: "OVER_QUERY_LIMIT".Jak zatrzymać wszystkie pająki i silnik natychmiast po spełnieniu warunku w rurociągu?

Dlatego chcę wiedzieć o jakimkolwiek mechanizmie, z którego mogę się odwołać w ramach rurociągu, który będzie całkowicie i natychmiast zatrzymać wszystkie dalsze indeksowania/przetwarzania wszystkich pająków, a także silnika głównego.

Sprawdziłem inne podobne pytania i odpowiedzi na nie nie pracowali:

from scrapy.project import crawler 
crawler._signal_shutdown(9,0) #Run this if the cnxn fails. 

to nie działa jak potrzeba czasu na pająka, aby zatrzymać wykonanie, a tym samym wiele innych żądań skierowanych do google (które może potencjalnie zablokować mój adres IP)

import sys 
sys.exit("SHUT DOWN EVERYTHING!") 

ten nie działa w ogóle; przedmioty przechowywać uzyskiwanie generowane i przekazywane do rurociągu, choć dziennik wymiotuje sys.exit() -> exceptions.SystemExit podniesiony (bez efektu)

crawler.engine.close_spider(self, 'log message') 

ten ma ten sam problem, co pierwszy wspomniany wyżej przypadek.

Próbowałem:

scrapy.project.crawler.engine.stop() 

bezskutecznie

EDIT: Jeśli robię w rurociągu:

od importu scrapy.contrib.closespider CloseSpider

co powinienem przekazać jako argument "robota" do funkcji CloseSpider init() z zakresu mojego potoku?

Odpowiedz

12

Możesz raise a CloseSpider exception zamknąć pająka. Jednak nie sądzę, że to będzie działać z potoku.

EDIT: avaleske zauważa w komentarzach do tej odpowiedzi, że był w stanie podnieść wyjątek CloseSpider z potoku. Najrozsądniej byłoby z tego skorzystać.

Podobna sytuacja została opisana na grupy Użytkownicy Scrapy, in this thread.

cytuję:

Aby zamknąć pająka dla każdej części kodu należy użyć engine.close_spider metody. Zobacz to rozszerzenie dla użytkowania przykład: https://github.com/scrapy/scrapy/blob/master/scrapy/contrib/closespider.py#L61

można napisać własne rozszerzenia, podczas gdy patrząc na closespider.py jako przykład, który będzie zamknięty pająka czy dany warunek został spełniony.

Innym "hack" byłoby ustawić flagę na pająka w rurociągu. Na przykład:

rurociąg:

def process_item(self, item, spider): 
    if some_flag: 
     spider.close_down = True 

pająk:

def parse(self, response): 
    if self.close_down: 
     raise CloseSpider(reason='API usage exceeded') 
+0

Dzięki za posta. Sądzę, że to zamknie pająk, jak w pierwszym przykładzie pokazanym powyżej, ale wymaga to czasu i kilka elementów z każdego zaplanowanego pająka nadal będzie przebiegać przez rurociąg. Co oznacza, że ​​100% zapytań będzie nadal robionych do google po otrzymaniu ostrzeżenia ... Jak zabić całość? Jeśli w ogóle nie ma sposobu, użyję "hacka"! Wielkie dzięki!!! – aniketd

+0

Również klasa CloseSpider przyjmuje argument "przeszukiwacza". W moim rurociągu i jego zakresie jaki obiekt powinien zostać przekazany? – aniketd

+1

Nie jestem do końca pewien, o co ci chodzi; ale ten dokument o rozszerzeniach może pomóc: http://doc.scrapy.org/en/latest/topics/extensions.html i dokument dotyczący potoków: http://doc.scrapy.org/en/latest/topics/item -pipeline.html. Chciałbym przekazać pająk do rurociągu, ustawić flagę i podnieść wyjątek CloseSpider w pająku. –

Powiązane problemy