Robotparser, кажется, не правильно разобрать

голоса
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

Это забавно , потому что иногда кажется , что «работает» , а иногда, кажется, не получится , я также попробовал то же самое с robots.txt от Facebook и Stackoverflow. Является ли это ошибка из robotpaserмодуля? Или я делаю что - то здесь не так? Если да, то?

Мне было интересно , если эта ошибка была что - нибудь связанным

Задан 11/03/2013 в 14:58
источник пользователем
На других языках...                            


4 ответов

голоса
3

После нескольких поисков Google я не нашел ничего о robotparser вопроса. Я в конечном итоге с чем - то еще, я нашел модуль под названием reppy который я сделал несколько испытаний , и это , кажется , очень мощный. Вы можете установить его через пип ;

pip install reppy

Вот несколько примеров (на IPython) с использованием reppy , снова, используя 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
Ответил 11/03/2013 в 16:34
источник пользователем

голоса
2

интересный вопрос. я имел взгляд на источнике (я только питон 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'

так что это либо ошибка в библиотеке питона, или Google ломает robot.txt спецификации, включив символ «?» символ в правиле (который немного необычно).

[только в случае , если это не ясно, я скажу это снова по-другому. приведенный выше код используется библиотека robotparser как часть проверки URL. поэтому , когда URL заканчивается на «?» этот символ отбрасывается. поэтому , когда вы проверили для /catalogs/p?фактического испытания казненного для /catalogs/p. следовательно , ваш удивительный результат.]

я хотел бы предложить подав ошибку с питона людьми (вы можете разместить ссылку здесь как часть объяснения) [редактировать: спасибо]. а затем , используя другую библиотеку вы нашли ...

Ответил 11/03/2013 в 20:40
источник пользователем

голоса
1

Примерно неделю назад мы объединили коммим с ошибкой в ​​нем, что это вызывает этот вопрос. Мы просто толкнул версию 0.2.2 ПГИ и мастер в репо, включая тест регрессии для именно этого вопроса.

Версия 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')
Ответил 13/03/2013 в 18:23
источник пользователем

голоса
4

Это не ошибка, а разница в интерпретации. Согласно спецификации проекта robots.txt (который никогда не был утвержден, и не является , вероятно, будет):

Для того, чтобы оценить, если доступ к URL разрешен, робот должен пытаться соответствовать пути в разрешающих и запрещающих строк против URL, в порядке их появления в записи. Первый матч найден используется. Если совпадение не найдено, устанавливаемое по умолчанию является то, что URL не допускается.

(Раздел 3.2.2, Разрешить и Запретить линии)

Используя эту интерпретацию, а затем «/ каталоги / р?» должно быть отвергнуто, потому что есть «Disallow: / каталоги» директива ранее.

В какой-то момент, Google начал интерпретировать файл robots.txt иначе от этой спецификации. Их метод, как представляется:

Check for Allow. If it matches, crawl the page.
Check for Disallow. If it matches, don't crawl.
Otherwise, crawl.

Проблема заключается в том, что не существует никакого официального соглашения о толковании robots.txt. Я видел робот, которые используют метод Google и другие, которые используют проект стандарт с 1996 года Когда я работал искатель, я получил nastygrams от веба-мастеров, когда я использовал интерпретацию Google, потому что я пополз страниц, по их мнению, не должен сканироваться, и я получил nastygrams от других, если я использовал другую интерпретацию, так как материал, по их мнению, должен быть проиндексирован, не было.

Ответил 13/03/2013 в 18:44
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more