2016-04-03 19 views
0

Benim özel kullanımım: Bir siteyi kazıyan bir kazıyıcı var, ve bir öğe verildikten sonra - Redis'te bir son kullanma süresi ile bir anahtar belirleyen bir sinyalim var. Kazıyıcı bir sonraki seferde, Redis'te bir anahtarın var olduğu tüm URL'leri yok saymalıdır.Scrapy'de bir isteği sessizce deşifre etmek mümkün mü?

İlk kısımda gayet iyi çalışıyor; ikinci kısım - Gelen istek nesnesine bakan bir process_request işlevine sahip bir DownloaderMiddleware yarattım ve onun URL'sinin Redis'te olup olmadığını kontrol ettim. Eğer öyleyse, raise bir IgnoreRequest istisnasıdır.

Bilmek istediklerim: Bir isteği yükseltmek yerine bir isteği sessizce deşifre etmenin bir yolu var mı? Estetik bir şey kadar zor bir gereklilik değil; Hata günlüklerimde bunlardan bir ton görmek istemiyorum - sadece iyi niyetli hataları görmek istiyorum.

Onların ana zamanlayıcı yinelenen filtreleme (scrapy/çekirdek/scheduler.py) için bir kludge neye benzediğini kullandığınız scrapy kaynağında bkz

:

def enqueue_request(self, request): 
    if not request.dont_filter and self.df.request_seen(request): 
     self.df.log(request, self.spider) 
     return False 
+1

sen paylaşabilir miyim? ve bunun yerine ne yapmak istersiniz? Varsayılan yinelenen filtreleme hakkında, varsayılan [aslında isteğe bağlı olarak kanonikleştirilmiş URL, HTTP yöntemi, gövde ve üstbilgileri] (isteğe bağlı olarak parmak izi) [https://github.com/scrapy/scrapy/blob/75cd056223a5a8da87a361aee42a541afcf27553/scrapy] temel alınarak oldukça basittir. /utils/request.py#L19)), ancak [dupefilter özelleştirilebilir] (http://doc.scrapy.org/en/latest/topics/settings.html?#std:setting-DUPEFILTER_CLASS). Tasarımın nasıl geliştirileceği veya basitleştirileceği veya nasıl netleştirileceği hakkında fikirleriniz varsa, Github hakkında bir tartışma açmaktan çekinmeyin. –

+0

HATA: Hata işleyicisinde yakalanan hata: > Traceback (son çağrı son): Dosya "/Library/Python/2.7/site-packages/scrapy/utils/signal.py", satır 26, send_catch_log içinde * argümanlar, ** adlı Dosya "/Library/Python/2.7/site-packages/scrapy/xlib/pydispatch/robustapply.py", 57 numaralı satır, robustApply dönüş alıcısı (* argümanlar, ** adlı) Dosyası ".../deferred ".py, hat 22, process_request zam IgnoreRequest içinde IgnoreRequest ('URL ertelenir'): ' def __init __ (self, paletli): URL Benim katman şöyle – infomaniac

+0

ertelenir self.client = Redis () self.crawler = paletli self.crawler.signals.connect (self.process_request, signals.request_scheduled) def process_request (self, istek, örümcek): self.client.is_deferred değilse (Request.Url): # URL ertelenmiş değildir , normal olarak devam edin İade yok zam IgnoreRequest ('URL' ertelendi ') ' – infomaniac

cevap

0

scrapy Python modülü kullanan logging, bir şeyler atmak için. İstediğiniz şey sadece estetik bir şeydir, görmek istemediğiniz şeyleri filtrelemek için logging filter yazabilirsiniz. Yorumlarınız

def __init__(self, crawler): 
    self.client = Redis() 
    self.crawler = crawler 
    self.crawler.signals.connect(self.process_request, signals.request_scheduled) 

def process_request(self, request, spider): 
    if not self.client.is_deferred(request.url): # URL is not deferred, proceed as normal 
     return None 
    raise IgnoreRequest('URL is deferred') 

sorun dan OP'sinden

3

Ara Katman kodu signals.request_scheduled eklediğiniz sinyal işleyicisi ile olduğunu. it will appear in the logs Bir istisna ortaya çıkarsa, burada process_request'u sinyal işleyicisi olarak kaydetmenin doğru (veya istemeden) olmadığına inanıyorum.

from scrapy import log, signals 
from scrapy.exceptions import IgnoreRequest 

class TestMiddleware(object): 

    def __init__(self, crawler): 
     self.counter = 0 

    @classmethod 
    def from_crawler(cls, crawler): 
     o = cls(crawler) 
     crawler.signals.connect(o.open_spider, signals.spider_opened) 

     # this raises an exception always and will trigger errors in the console 
     crawler.signals.connect(o.process, signals.request_scheduled) 
     return o 

    def open_spider(self, spider): 
     spider.logger.info('TestMiddleware.open_spider()') 

    def process_request(self, request, spider): 
     spider.logger.info('TestMiddleware.process_request()') 
     self.counter += 1 
     if (self.counter % 2) == 0: 
      raise IgnoreRequest("ignoring request %d" % self.counter) 

    def process(self, *args, **kwargs): 
     raise Exception 

konsolu bununla bir örümcek çalıştırırken ne diyor bakın: Ben gördüğü her isteğini görmezden bu benzer (non-doğru) testi katman, ile konsol hataları yeniden açabiliyorum

ara katman: code is here.

$ cat middlewares.py 
from scrapy import log, signals 
from scrapy.exceptions import IgnoreRequest 

class TestMiddleware(object): 

    def __init__(self, crawler): 
     self.counter = 0 

    @classmethod 
    def from_crawler(cls, crawler): 
     o = cls(crawler) 
     crawler.signals.connect(o.open_spider, signals.spider_opened) 
     return o 

    def open_spider(self, spider): 
     spider.logger.info('TestMiddleware.open_spider()') 

    def process_request(self, request, spider): 
     spider.logger.info('TestMiddleware.process_request()') 
     self.counter += 1 
     if (self.counter % 2) == 0: 
      raise IgnoreRequest("ignoring request %d" % self.counter) 

IgnoreRequest günlüklerinde basılmış değil ama sonunda istatistiklerinde istisna sayımları:

bununla karşılaştırın Günlüklerinize gördükleri

$ scrapy crawl httpbin 
2016-04-06 00:27:24 [scrapy] INFO: Scrapy 1.1.0rc3 started (bot: mwtest) 
(...) 
2016-04-06 00:27:24 [scrapy] INFO: Enabled downloader middlewares: 
['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware', 
'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware', 
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware', 
'scrapy.downloadermiddlewares.retry.RetryMiddleware', 
'mwtest.middlewares.TestMiddleware', 
'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware', 
'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware', 
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware', 
'scrapy.downloadermiddlewares.redirect.RedirectMiddleware', 
'scrapy.downloadermiddlewares.cookies.CookiesMiddleware', 
'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware', 
'scrapy.downloadermiddlewares.stats.DownloaderStats'] 
(...) 
2016-04-06 00:27:24 [scrapy] INFO: Spider opened 
2016-04-06 00:27:24 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 
2016-04-06 00:27:24 [httpbin] INFO: TestMiddleware.open_spider() 
2016-04-06 00:27:24 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023 
2016-04-06 00:27:24 [httpbin] INFO: TestMiddleware.process_request() 
2016-04-06 00:27:24 [httpbin] INFO: TestMiddleware.process_request() 
2016-04-06 00:27:24 [httpbin] INFO: TestMiddleware.process_request() 
2016-04-06 00:27:24 [httpbin] INFO: TestMiddleware.process_request() 
2016-04-06 00:27:24 [httpbin] INFO: TestMiddleware.process_request() 
2016-04-06 00:27:24 [scrapy] DEBUG: Crawled (200) <GET http://www.httpbin.org/user-agent> (referer: None) 
2016-04-06 00:27:25 [scrapy] DEBUG: Crawled (200) <GET http://www.httpbin.org/> (referer: None) 
2016-04-06 00:27:25 [scrapy] DEBUG: Crawled (200) <GET http://www.httpbin.org/headers> (referer: None) 
2016-04-06 00:27:25 [scrapy] INFO: Closing spider (finished) 
2016-04-06 00:27:25 [scrapy] INFO: Dumping Scrapy stats: 
{'downloader/exception_count': 2, 
'downloader/exception_type_count/scrapy.exceptions.IgnoreRequest': 2, 
'downloader/request_bytes': 665, 
'downloader/request_count': 3, 
'downloader/request_method_count/GET': 3, 
'downloader/response_bytes': 13006, 
'downloader/response_count': 3, 
'downloader/response_status_count/200': 3, 
'finish_reason': 'finished', 
'finish_time': datetime.datetime(2016, 4, 5, 22, 27, 25, 596652), 
'log_count/DEBUG': 4, 
'log_count/INFO': 13, 
'log_count/WARNING': 1, 
'response_received_count': 3, 
'scheduler/dequeued': 5, 
'scheduler/dequeued/memory': 5, 
'scheduler/enqueued': 5, 
'scheduler/enqueued/memory': 5, 
'start_time': datetime.datetime(2016, 4, 5, 22, 27, 24, 661345)} 
2016-04-06 00:27:25 [scrapy] INFO: Spider closed (finished) 
İlgili konular