6

私はクローラーを作成しており、このために robots.txt パーサーを実装しています。標準の lib robotparserを使用しています。

robotparserが正しく解析していないようです。Google のrobots.txtを使用してクローラをデバッグしています。

(以下の例は IPython のものです)

In [1]: import robotparser

In [2]: x = robotparser.RobotFileParser()

In [3]: x.set_url("http://www.google.com/robots.txt")

In [4]: x.read()

In [5]: x.can_fetch("My_Crawler", "/catalogs") # This should return False, since it's on Disallow
Out[5]: False

In [6]: x.can_fetch("My_Crawler", "/catalogs/p?") # This should return True, since it's Allowed
Out[6]: False

In [7]: x.can_fetch("My_Crawler", "http://www.google.com/catalogs/p?")
Out[7]: False

「うまくいく」ように見えることもあれば、失敗するように見えることもあるので面白いです.FacebookとStackoverflowのrobots.txtでも同じことを試しました. robotpaserこれはモジュールのバグですか? それとも、ここで何か間違ったことをしていますか? もしそうなら、何?

このバグに何か関係があるのだろうかと思っていました

4

4 に答える 4

3

いくつかの Google 検索の後、 robotparser の問題について何も見つかりませんでした。私はいくつかのテストを行ったreppyと呼ばれるモジュールを見つけましたが、それは非常に強力なようです。pipでインストールできます。

pip install reppy

ここでも、 reppyを使用して (IPython で) いくつかの例を示します。Google のrobots.txtを使用しています。

In [1]: import reppy

In [2]: x = reppy.fetch("http://google.com/robots.txt")

In [3]: x.atts
Out[3]: 
{'agents': {'*': <reppy.agent at 0x1fd9610>},
 'sitemaps': ['http://www.gstatic.com/culturalinstitute/sitemaps/www_google_com_culturalinstitute/sitemap-index.xml',
  'http://www.google.com/hostednews/sitemap_index.xml',
  'http://www.google.com/sitemaps_webmasters.xml',
  'http://www.google.com/ventures/sitemap_ventures.xml',
  'http://www.gstatic.com/dictionary/static/sitemaps/sitemap_index.xml',
  'http://www.gstatic.com/earth/gallery/sitemaps/sitemap.xml',
  'http://www.gstatic.com/s2/sitemaps/profiles-sitemap.xml',
  'http://www.gstatic.com/trends/websites/sitemaps/sitemapindex.xml']}

In [4]: x.allowed("/catalogs/about", "My_crawler") # Should return True, since it's allowed.
Out[4]: True

In [5]: x.allowed("/catalogs", "My_crawler") # Should return False, since it's not allowed.
Out[5]: False

In [7]: x.allowed("/catalogs/p?", "My_crawler") # Should return True, since it's allowed.
Out[7]: True

In [8]: x.refresh() # Refresh robots.txt, perhaps a magic change?

In [9]: x.ttl
Out[9]: 3721.3556718826294

In [10]: # It also has a x.disallowed function. The contrary of x.allowed
于 2013-03-11T18:34:11.877 に答える
2

興味深い質問です。ソースを見て(Python 2.4ソースしか利用できませんが、変更されていないに違いありません)、コードは次を実行してテストされているURLを正規化します:

urllib.quote(urlparse.urlparse(urllib.unquote(url))[2]) 

これはあなたの問題の原因です:

>>> urllib.quote(urlparse.urlparse(urllib.unquote("/foo"))[2]) 
'/foo'
>>> urllib.quote(urlparse.urlparse(urllib.unquote("/foo?"))[2]) 
'/foo'

これは Python のライブラリのバグか、Google が「?」を含めることで robot.txt の仕様を破っています。ルールの文字 (これは少し変わっています)。

[念のため、別の言い方でもう一度言います。上記のコードは、URL チェックの一部として robotparser ライブラリによって使用されます。そのため、URL が「?」で終わる場合 そのキャラクターは落とされます。そのため/catalogs/p?、実際に実行されたテストを確認したところ、/catalogs/p. したがって、あなたの驚くべき結果です。]

私はpythonの人々にバグを報告することをお勧めします(説明の一部としてここへのリンクを投稿できます)[編集:ありがとう]。そして、あなたが見つけた他のライブラリを使用して...

于 2013-03-11T22:40:04.793 に答える
1

約 1 週間前に、この問題を引き起こしているバグのあるコミットをマージしました。バージョン 0.2.2 をレポの pip と master にプッシュしたところ、まさにこの問題の回帰テストが含まれていました。

バージョン 0.2 にはわずかなインターフェイスの変更が含まれています。現在は、元のインターフェイスとまったく同じインターフェイスを含む RobotsCache オブジェクトを作成する必要がありますreppy。これは主に、キャッシングを明示的にし、同じプロセス内で異なるキャッシュを持つことを可能にするためでした。しかし、見よ、それは再び機能するようになりました!

from reppy.cache import RobotsCache
cache = RobotsCache()
cache.allowed('http://www.google.com/catalogs', 'foo')
cache.allowed('http://www.google.com/catalogs/p', 'foo')
cache.allowed('http://www.google.com/catalogs/p?', 'foo')
于 2013-03-13T20:23:04.067 に答える