ロギング(logging)¶
注釈
scrapy.log
は、Python標準ロギングの明示的な呼び出しを支援する機能とともに非推奨になりました。 新しいロギングシステムの詳細については、以下をご覧ください。
Scrapyは、イベント・ロギングに logging
を使用します。 始めるための簡単な例をいくつか紹介しますが、より高度なユース・ケースについては、Pythonの組み込みロギング・システムのドキュメントを徹底的に読むことを強くお勧めします。
ロギングはそのままで機能し、 ロギング設定 にリストされているScrapy設定である程度設定できます。
Scrapyは scrapy.utils.log.configure_logging()
を呼び出していくつかの妥当なデフォルトを設定し、コマンドを実行するときに ロギング設定 でそれらの設定を処理するため、スクリプトからScrapyを実行する で説明されているスクリプトからScrapyを実行している場合は、手動で呼び出すことをお勧めします。
ログ・レベル¶
Pythonの組み込みロギングは、特定のログメッセージの重大度を示す5つの異なるレベルを定義します。 以下は標準のもので、降順でリストされています:
logging.CRITICAL
- 致命的なエラーの場合(最高の重要度)logging.ERROR
- 通常のエラーの場合logging.WARNING
- 警告メッセージの場合logging.INFO
- 情報メッセージ用logging.DEBUG
- デバッグメッセージ用(最も低い重要度)
メッセージをログ出しする方法¶
logging.WARNING
レベルを使用してメッセージをログ出しする方法の簡単な例を次に示します:
import logging
logging.warning("This is a warning")
標準の5つのレベルのいずれかでログメッセージを発行するためのショートカットがあり、引数として指定されたレベルを取る一般的な logging.log
メソッドもあります。必要に応じて、さっきの例を次のように書き換えることができます:
import logging
logging.log(logging.WARNING, "This is a warning")
さらに、あなたはメッセージをカプセル化するためのさまざまなロガーを作成できます。(たとえば、一般的な方法は、モジュールごとに異なるロガーを作成することです)。 これらのロガーは独立して構成でき、階層構造が可能です。
前の例では、舞台裏でルート・ロガーを使用します。これは、特に指定がない限り、すべてのメッセージが伝播されるトップ・レベル・ロガーです。 logging
ヘルパーの使用は、ルート・ロガーを明示的に取得するための単なるショートカットであるため、これは最後のコード片と同等です。
import logging
logger = logging.getLogger()
logger.warning("This is a warning")
logging.getLogger
関数で名前を取得するだけで、異なるロガーを使用できます:
import logging
logger = logging.getLogger('mycustomlogger')
logger.warning("This is a warning")
最後に、 __name__
変数を使用して、作業中のモジュールのカスタム・ロガーを確保できます。これには、現在のモジュールのパスが入力されます:
import logging
logger = logging.getLogger(__name__)
logger.warning("This is a warning")
参考
- モジュール・ロギング HowTo
基本ロギング・チュートリアル(https://docs.python.org/2/howto/logging.html)
- モジュール・ロギング、 Loggers
ロガーに関する詳細なドキュメント(https://docs.python.org/2/library/logging.html#logger-objects)
スパイダーからのロギング¶
Scrapyは、各スパイダー・インスタンス内で logger
を提供します。
import scrapy
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['https://scrapy.org']
def parse(self, response):
self.logger.info('Parse function called on %s', response.url)
そのロガーはスパイダーの名前を使用して作成されますが、任意のカスタムPythonロガーを使用できます。 例えば以下です:
import logging
import scrapy
logger = logging.getLogger('mycustomlogger')
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['https://scrapy.org']
def parse(self, response):
logger.info('Parse function called on %s', response.url)
ロギング構成(configuration)¶
ロガー自身は、ロガーを介して送信されたメッセージの表示方法を管理しません。 このタスクでは、さまざまなハンドラーを任意のロガー・インスタンスにアタッチして、それらのメッセージを標準出力、ファイル、電子メールなどの適切な宛先にリダイレクトします。
デフォルトでは、Scrapyは以下の設定に基づいて、ルート・ロガーのハンドラーを設定および構成します。
ロギング設定¶
これらの設定は、ロギングの構成(configuration)に使用できます:
最初のいくつかの設定は、ログメッセージの宛先を定義します。 LOG_FILE
が設定されている場合、ルート・ロガーを介して送信されたメッセージは LOG_ENCODING
エンコーディングで LOG_FILE
という名前のファイルにリダイレクトされます。設定が解除され、 LOG_ENABLED
が True
の場合、ログメッセージは標準エラーに表示されます。 そして、 LOG_ENABLED
が False
の場合、目に見えるログ出力はありません。
LOG_LEVEL
は表示する重大度の最小レベルを決定し、指定より重大度の低いメッセージは除外されます。 ログ・レベル にリストされている可能なレベルを範囲としています。
LOG_FORMAT
と LOG_DATEFORMAT
は、すべてのメッセージのレイアウトとして使用されるフォーマット文字列を指定します。これらの文字列には、 それぞれ、 ロギングのログ・レコード属性文書 や、 日時のstrftimeおよびstrptimeディレクティブ にリストされているプレース・ホルダーを含めることができます。
LOG_SHORT_NAMES
が設定されている場合、ログはログを印刷するScrapyコンポーネントを表示しません。 デフォルトでは設定されていないため、ログにはそのログ出力の原因となるScrapyコンポーネントが含まれています。
コマンド・ライン・オプション¶
すべてのコマンドで使用できるコマンドライン引数があり、これを使用してロギングに関するScrapy設定の一部をオーバーライドできます。
--logfile FILE
LOG_FILE
をオーバーライドする
--loglevel/-L LEVEL
LOG_LEVEL
をオーバーライドする
--nolog
LOG_ENABLED
をFalse
に設定
参考
- モジュール
logging.handlers
利用可能なハンドラーに関する詳細なドキュメント
カスタム・ログ書式¶
LogFormatter
クラスを拡張し、 LOG_FORMATTER
が新しいクラスを指すようにすることで、さまざまなアクションに対してカスタム・ログ形式を設定できます。
- class scrapy.logformatter.LogFormatter[ソース]¶
さまざまなアクションのログメッセージを生成するためのクラス。
すべてのメソッドは、パラメーター
level
とmsg
とargs
をリストする辞書を返さなければなりません。これらは、logging.log
を呼び出すときにログ・メッセージを作成するために使用されます。メソッド出力の辞書キー:
level
はそのアクションのログ・レベルです。 python logging library のログレベルを使用できます。それはlogging.DEBUG
とlogging.INFO
とlogging.WARNING
とlogging.ERROR
とlogging.CRITICAL
です。msg
は異なるフォーマットのプレース・ホルダーを含むことができる文字列でなければなりません。 提供されたargs
でフォーマットされたこの文字列は、そのアクションの長いメッセージになります。args
は、msg
のフォーマット・プレース・ホルダーを持つタプルまたは辞書である必要があります。最終的なログメッセージはmsg % args
として処理されます。
各アクションのログ方法をカスタマイズしたい場合、または完全に省略したい場合、ユーザーは独自の
LogFormatter
クラスを定義できます。 アクションのロギングを省略するには、メソッドはNone
を返す必要があります。アイテムがパイプラインからドロップされたときにログ・メッセージの重大度を下げるためにカスタム・ログ・フォーマッタを作成する方法の例を次に示します:
class PoliteLogFormatter(logformatter.LogFormatter): def dropped(self, item, exception, response, spider): return { 'level': logging.INFO, # lowering the level from logging.WARNING 'msg': "Dropped: %(exception)s" + os.linesep + "%(item)s", 'args': { 'exception': exception, 'item': item, } }
- download_error(failure, request, spider, errmsg=None)[ソース]¶
スパイダーからのダウンロード・エラー・メッセージをログに記録します(通常はエンジンから送信されます)。
バージョン 2.0 で追加.
高度なカスタマイズ¶
Scrapyはstdlibロギング・モジュールを使用するため、stdlibロギングのすべての機能を使用してロギングをカスタマイズできます。
たとえば、多くの「HTTP 404」や「HTTP 500」のレスポンスを返すWebサイトをスクレイピングしていて、このようなすべてのメッセージを非表示にしたいとします:
2016-12-16 22:00:06 [scrapy.spidermiddlewares.httperror] INFO: Ignoring
response <500 http://quotes.toscrape.com/page/1-34/>: HTTP status code
is not handled or not allowed
最初に注意することはロガー名です。角括弧内に書きます。 [scrapy.spidermiddlewares.httperror]
。単に [scrapy]
を取得した場合、 LOG_SHORT_NAMES
はおそらくTrueに設定されています。Falseに設定して、クロールを再実行します。
次に、メッセージにINFOレベルがあることがわかります。非表示にするには、INFOよりも高い scrapy.spidermiddlewares.httperror
のログ・レベルを設定する必要があります。 INFOの次のレベルはWARNINGです。 スパイダー __init__
メソッド内でその設定を行うことができます:
import logging
import scrapy
class MySpider(scrapy.Spider):
# ...
def __init__(self, *args, **kwargs):
logger = logging.getLogger('scrapy.spidermiddlewares.httperror')
logger.setLevel(logging.WARNING)
super().__init__(*args, **kwargs)
あなたがこのスパイダーを再度実行すると、 scrapy.spidermiddlewares.httperror
ロガーからのINFOメッセージはなくなります。
LogRecord
データでログ・レコードをフィルタリングすることもできます。 たとえば、文字列の部分(substring)または正規表現を使用して、メッセージの内容でログ・レコードをフィルタリングできます。 logging.Filter
サブ・クラスを作成し、正規表現パターンを装備して不要なメッセージを除外します:
import logging
import re
class ContentFilter(logging.Filter):
def filter(self, record):
match = re.search(r'\d{3} [Ee]rror, retrying', record.message)
if match:
return False
Scrapyによって作成されたルート・ハンドラーにプロジェクト・レベルのフィルターをアタッチできます。これは、プロジェクトのさまざまな部分(ミドルウェア、スパイダーなど)のすべてのロガーをフィルタ処理するための便利な方法です:
import logging
import scrapy
class MySpider(scrapy.Spider):
# ...
def __init__(self, *args, **kwargs):
for handler in logging.root.handlers:
handler.addFilter(ContentFilter())
または、特定のロガーを選択して、他のロガーに影響を与えずに非表示にすることもできます:
import logging
import scrapy
class MySpider(scrapy.Spider):
# ...
def __init__(self, *args, **kwargs):
logger = logging.getLogger('my_logger')
logger.addFilter(ContentFilter())
scrapy.utils.logモジュール¶
- scrapy.utils.log.configure_logging(settings=None, install_root_handler=True)[ソース]¶
Scrapyのロギングのデフォルトを初期化します。
- パラメータ
この関数は以下のとおり動作します:
Pythonの標準ログを介したルーティング警告とtwistedのロギング
ScrapyおよびTwistedロガーにそれぞれDEBUGおよびERRORレベルを割り当てます
LOG_STDOUT設定がTrueの場合、ログは標準出力に出力されます。
install_root_handler
がTrue(デフォルト)の場合、この関数は与えられた設定( ロギング設定 参照)に従ってルート・ロガーのハンドラーも作成します。settings
引数を使用してデフォルトのオプションを上書きできます。settings
が空またはNoneの場合、デフォルトが使用されます。configure_logging
はScrapyコマンドまたはCrawlerProcess
を使用すると自動的に呼び出されますが、CrawlerRunner
を使用してカスタム・スクリプトを実行する場合は明示的に呼び出す必要があります。その場合、その使用は必須ではありませんが、推奨されます。カスタム・スクリプトを実行するときのもう1つのオプションは、ログを手動で構成することです。 これを行う時は、
logging.basicConfig()
を使用して基本的なルート・ハンドラーを設定できます。CrawlerProcess
は自動的にconfigure_logging
を呼び出すため、CrawlerRunner
と一緒にlogging.basicConfig()
のみを使用することをお勧めします。以下は、
INFO
のメッセージをファイルにリダイレクトする方法の例です:import logging logging.basicConfig( filename='log.txt', format='%(levelname)s: %(message)s', level=logging.INFO )
この方法でScrapyを使用する方法の詳細については、 スクリプトからScrapyを実行する を参照してください。