Je ne sais pas pourquoi ne pas comme un message d'erreur à plusieurs lignes (il est l'impression de retraçage de l'exception). Quoi qu'il en soit, nous pourrions personnaliser la mise en forme de la journalisation scrapy. En supposant que vous exécutiez vos scripts d'exploration par la ligne de commande scrapy
, par exemple, scrapy crawl
ou scrapy runspider
. Voici un exemple de code (version python 3) qui montre comment utiliser votre propre formateur.
import logging
import scrapy
class OneLineFormatter(logging.Formatter):
def __init__(self, *args, **kwargs):
super(OneLineFormatter, self).__init__(*args, **kwargs)
def format(self, record):
formatted = super(OneLineFormatter, self).format(record)
return formatted.replace('\n', ' ')
class TestSpider(scrapy.Spider):
name = "test"
start_urls = [
'http://www.somenxdomain.com/robots.txt',
]
def __init__(self, fmt, datefmt, *args, **kwargs):
my_formatter = OneLineFormatter(fmt=fmt, datefmt=datefmt)
root = logging.getLogger()
for h in root.handlers:
h.setFormatter(my_formatter)
super(TestSpider, self).__init__(*args, **kwargs)
@classmethod
def from_crawler(cls, crawler):
settings = crawler.settings
return cls(settings.get('LOG_FORMAT'), settings.get('LOG_DATEFORMAT'))
def parse(self, response):
pass
Et voici quelques explications.
Flux de travail de journalisation Python. Le scrapy
lui-même utilise le système de journalisation intégré python. Ainsi, vous avez besoin de quelques connaissances de base de la journalisation python, en particulier les relations entre les classes Logger
, Handler
, Filter
et Formatter
. Je suggère fortement le working flow de journalisation python.
Scrapy journalisation et paramètres. Si votre araignée est exécutée par la ligne de commande scrapy
, par exemple, scrapy crawl
ou scrapy runspider
, la fonction scrapy [configure_logging](https://docs.python.org/2/howto/logging.html#logging-flow)
est appelée pour initialiser la journalisation. L'instruction de scrapy logging pourrait donner quelques instructions sur la façon de personnaliser votre journalisation et par scrapy settings vous pourriez accéder à vos paramètres.
Comment l'exemple de code fonctionne. Le flux de travail de base est:
- D'abord, vous devez définir votre propre classe de formatage pour personnaliser la mise en forme de la journalisation. Deuxièmement, dans votre araignée, vous devez avoir accès à vos paramètres de formatage pour initialiser votre classe de formateur.
- Et enfin, dans votre araignée, vous obtenez le logger
root
et définissez votre formateur à tous les gestionnaires de root
.
Si vous écrivez votre propre script et utilisez scrapy comme API, voir [exécuter scrapy partir d'un script] (https://doc.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script), vous devez configurer l'enregistrement de votre auto.
Le formateur ci-dessus ne fonctionnera pas tant que l'araignée n'aura pas été initialisée. Voici quelques tirages:
2017-10-03 11:59:39 [scrapy.utils.log] INFO: Scrapy 1.3.3 started (bot: scrapybot)
2017-10-03 11:59:39 [scrapy.utils.log] INFO: Overridden settings: {'SPIDER_LOADER_WARN_ONLY': True}
2017-10-03 11:59:39 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
'scrapy.extensions.telnet.TelnetConsole',
'scrapy.extensions.logstats.LogStats']
2017-10-03 11:59:39 [scrapy.middleware] INFO: Enabled downloader middlewares: ['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware', 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware', 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware', 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware', 'scrapy.downloadermiddlewares.retry.RetryMiddleware', 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware', 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware', 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware', 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware', 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2017-10-03 11:59:39 [scrapy.middleware] INFO: Enabled spider middlewares: ['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware', 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware', 'scrapy.spidermiddlewares.referer.RefererMiddleware', 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware', 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2017-10-03 11:59:39 [scrapy.middleware] INFO: Enabled item pipelines: []
2017-10-03 11:59:39 [scrapy.core.engine] INFO: Spider opened
2017-10-03 11:59:39 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-10-03 11:59:39 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6024
2017-10-03 11:59:39 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <GET http://www.somenxdomain.com/robots.txt> (failed 1 times): DNS lookup failed: no results for hostname lookup: www.somenxdomain.com.
2017-10-03 11:59:39 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <GET http://www.somenxdomain.com/robots.txt> (failed 2 times): DNS lookup failed: no results for hostname lookup: www.somenxdomain.com.
2017-10-03 11:59:39 [scrapy.downloadermiddlewares.retry] DEBUG: Gave up retrying <GET http://www.somenxdomain.com/robots.txt> (failed 3 times): DNS lookup failed: no results for hostname lookup: www.somenxdomain.com.
2017-10-03 11:59:39 [scrapy.core.scraper] ERROR: Error downloading <GET http://www.somenxdomain.com/robots.txt> Traceback (most recent call last): File "/Users/xxx/anaconda/envs/p3/lib/python3.6/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks result = result.throwExceptionIntoGenerator(g) File "/Users/xxx/anaconda/envs/p3/lib/python3.6/site-packages/twisted/python/failure.py", line 393, in throwExceptionIntoGenerator return g.throw(self.type, self.value, self.tb) File "/Users/xxx/anaconda/envs/p3/lib/python3.6/site-packages/scrapy/core/downloader/middleware.py", line 43, in process_request defer.returnValue((yield download_func(request=request,spider=spider))) File "/Users/xxx/anaconda/envs/p3/lib/python3.6/site-packages/twisted/internet/defer.py", line 653, in _runCallbacks current.result = callback(current.result, *args, **kw) File "/Users/xxx/anaconda/envs/p3/lib/python3.6/site-packages/twisted/internet/endpoints.py", line 954, in startConnectionAttempts "no results for hostname lookup: {}".format(self._hostStr) twisted.internet.error.DNSLookupError: DNS lookup failed: no results for hostname lookup: www.somenxdomain.com.
2017-10-03 11:59:40 [scrapy.core.engine] INFO: Closing spider (finished)
2017-10-03 11:59:40 [scrapy.statscollectors] INFO: Dumping Scrapy stats: {'downloader/exception_count': 3, 'downloader/exception_type_count/twisted.internet.error.DNSLookupError': 3, 'downloader/request_bytes': 684, 'downloader/request_count': 3, 'downloader/request_method_count/GET': 3, 'finish_reason': 'finished', 'finish_time': datetime.datetime(2017, 10, 3, 15, 59, 40, 46636), 'log_count/DEBUG': 4, 'log_count/ERROR': 1, 'log_count/INFO': 7, 'scheduler/dequeued': 3, 'scheduler/dequeued/memory': 3, 'scheduler/enqueued': 3, 'scheduler/enqueued/memory': 3, 'start_time': datetime.datetime(2017, 10, 3, 15, 59, 39, 793795)}
2017-10-03 11:59:40 [scrapy.core.engine] INFO: Spider closed (finished)
Vous pouvez voir qu'après l'exécution de spider, tous les messages sont formatter en une ligne. (En supprimant '\n'
).
Espérons que cela serait utile.
super merci. J'ai upvoted la réponse, mais l'acceptera une fois que j'ai fini d'utiliser la solution. – comiventor