robotparser – インターネットスパイダーのアクセス制御

目的:インターネットスパイダーを制御する robots.txt ファイルを解析する
利用できるバージョン:2.1.3 以上

robotparser は、あるユーザエージェントがリソースへアクセスできるかどうかをチェックするシンプルな仕組みを含む robots.txt ファイルフォーマットのパーサを実装します。それはスパイダー、もしくは他のクローラーアプリケーションの動作を調整したり、制限したりする必要があることを想定しています。

Note

robotparser モジュールは Python 3.0 で urllib.robotparser に変更されました。 robotparser を使用する既存のコードは 2to3 で変更されます。

robots.txt

robots.txt ファイルフォーマットは、web を自動徘徊してリソースへアクセスするプログラム(“スパイダー” や “クローラー” 等)向けのシンプルなテキストベースのアクセス制御システムです。そのファイルは、ユーザエージェントがアクセスする必要のない URL リスト(または URL の接頭辞)をそういったプログラム向けに提供し、ユーザエージェントの識別子を指定するレコードで構成されます。

これは http://www.doughellmann.com/robots.txt ファイルです。

User-agent: *
Disallow: /admin/
Disallow: /downloads/
Disallow: /media/
Disallow: /static/
Disallow: /codehosting/

検索エンジンが私のサイトの重いページをインデクシングしようとすると、サーバが高負荷になるので、そういったページへのアクセスを制限しています。もっと詳細なサンプルとしては The Web Robots Page を参照してください。

シンプルなサンプル

前節のデータを使用して、シンプルなクローラが RobotFileParsercan_fetch() メソッドでページをダウンロードできるかどうかテストします。

import robotparser
import urlparse

AGENT_NAME = 'PyMOTW'
URL_BASE = 'http://www.doughellmann.com/'
parser = robotparser.RobotFileParser()
parser.set_url(urlparse.urljoin(URL_BASE, 'robots.txt'))
parser.read()

PATHS = [
    '/',
    '/PyMOTW/',
    '/admin/',
    '/downloads/PyMOTW-1.92.tar.gz',
    ]

for path in PATHS:
    print '%6s : %s' % (parser.can_fetch(AGENT_NAME, path), path)
    url = urlparse.urljoin(URL_BASE, path)
    print '%6s : %s' % (parser.can_fetch(AGENT_NAME, url), url)
    print

can_fetch() への URL 引数はそのサイトのルートへの相対パスか、完全な URL で指定します。

$ python robotparser_simple.py
  True : /
  True : http://www.doughellmann.com/

  True : /PyMOTW/
  True : http://www.doughellmann.com/PyMOTW/

  True : /admin/
  True : http://www.doughellmann.com/admin/

 False : /downloads/PyMOTW-1.92.tar.gz
 False : http://www.doughellmann.com/downloads/PyMOTW-1.92.tar.gz

長時間処理するスパイダー

リソースをダウンロードする処理に長時間かかる、もしくはダウンロード中に一時停止するように調整されたアプリケーションは、既にダウンロード済みのコンテンツの age ヘッダに基づいて定期的に新しい robots.txt ファイルをチェックすると良いです。この age の時間は自動的に制御されませんが、簡単にその時間を記録する便利なメソッドがあります。

import robotparser
import time
import urlparse

AGENT_NAME = 'PyMOTW'
parser = robotparser.RobotFileParser()
# ローカルコピーを使用する
parser.set_url('robots.txt')
parser.read()
parser.modified()

PATHS = [
    '/',
    '/PyMOTW/',
    '/admin/',
    '/downloads/PyMOTW-1.92.tar.gz',
    ]

for n, path in enumerate(PATHS):
    print
    age = int(time.time() - parser.mtime())
    print 'age:', age,
    if age > 1:
        print 're-reading robots.txt'
        parser.read()
        parser.modified()
    else:
        print
    print '%6s : %s' % (parser.can_fetch(AGENT_NAME, path), path)
    # Simulate a delay in processing
    time.sleep(1)

この極端なサンプルは、1秒後に新たな robots.txt ファイルをダウンロードします。

$ python robotparser_longlived.py

age: 0
  True : /

age: 1
  True : /PyMOTW/

age: 2 re-reading robots.txt
 False : /admin/

age: 1
 False : /downloads/PyMOTW-1.92.tar.gz

長時間処理するアプリケーションの “もっと良い” 実装は、そのファイルをダウンロードする前にファイル更新時刻をリクエストします。ただ、普通は robots.txt ファイルのサイズはかなり小さいので、再読み込みしてもそう大きな負荷にはなりません。

See also

robotparser
本モジュールの標準ライブラリドキュメント
The Web Robots Page
robots.txt のフォーマット説明
Bookmark and Share