ロギング(logging)¶
注釈
scrapy.log
は、Python標準ロギングの明示的な呼び出しを支援する機能とともに非推奨になりました。 新しいロギングシステムの詳細については、以下をご覧ください。
Scrapyは、イベント・ロギングにPythonの組み込みロギング・システム(Python's builtin logging system)を使用します。 始めるための簡単な例をいくつか紹介しますが、より高度なユース・ケースについては、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://scrapinghub.com']
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://scrapinghub.com']
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
は、すべてのメッセージのレイアウトとして使用されるフォーマット文字列を指定します。これらの文字列には、 それぞれ、ロギングのログ・レコード属性文書(logging's logrecord attributes docs) や、日時のstrftimeおよびstrptimeディレクティブ(datetime's strftime and strptime directives) にリストされているプレース・ホルダーを含めることができます。
LOG_SHORT_NAMES
が設定されている場合、ログはログを印刷するScrapyコンポーネントを表示しません。 デフォルトでは設定されていないため、ログにはそのログ出力の原因となるScrapyコンポーネントが含まれています。
コマンド・ライン・オプション¶
すべてのコマンドで使用できるコマンドライン引数があり、これを使用してロギングに関するScrapy設定の一部をオーバーライドできます。
--logfile FILE
LOG_FILE
をオーバーライドする
--loglevel/-L LEVEL
LOG_LEVEL
をオーバーライドする
--nolog
LOG_ENABLED
をFalse
に設定
参考
- logging.handlers モジュール
利用可能なハンドラーに関する詳細なドキュメント
カスタム・ログ書式¶
LogFormatter
クラスを拡張し、 LOG_FORMATTER
が新しいクラスを指すようにすることで、さまざまなアクションに対してカスタム・ログ形式を設定できます。
高度なカスタマイズ¶
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メッセージはなくなります。