`open_http': 403 Запрещено (OpenURI::HTTPError) для строки Steve_Jobs, но не для любой другой строки

Я просматривал учебные пособия по Ruby, представленные на http://ruby.bastardsbook.com/, и обнаружил следующий код:

require "open-uri"

remote_base_url = "http://en.wikipedia.org/wiki"
r1 = "Steve_Wozniak"
r2 = "Steve_Jobs"
f1 = "my_copy_of-" + r1 + ".html"
f2 = "my_copy_of-" + r2 + ".html"

# read the first url
remote_full_url = remote_base_url + "/" + r1
rpage = open(remote_full_url).read

# write the first file to disk
file = open(f1, "w")
file.write(rpage)
file.close

# read the first url
remote_full_url = remote_base_url + "/" + r2
rpage = open(remote_full_url).read

# write the second file to disk
file = open(f2, "w")
file.write(rpage)
file.close

# open a new file:
compiled_file = open("apple-guys.html", "w")

# reopen the first and second files again
k1 = open(f1, "r")
k2 = open(f2, "r")

compiled_file.write(k1.read)
compiled_file.write(k2.read)

k1.close
k2.close
compiled_file.close

Код завершается со следующей трассировкой:

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:277:in `open_http': 403 Forbidden (OpenURI::HTTPError)
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:616:in `buffer_open'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:164:in `open_loop'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:162:in `catch'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:162:in `open_loop'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:132:in `open_uri'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:518:in `open'
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:30:in `open'
    from /Users/arkidmitra/tweetfetch/samecode.rb:11

Моя проблема не в том, что код дает сбой, а в том, что всякий раз, когда я меняю r2 на что-то другое, кроме Steve_Jobs, он работает. Что здесь происходит?


person Yahoo-Me    schedule 07.06.2012    source источник
comment
У вас есть прокси или что-то, что может фильтровать URL-адреса? Вы пытались попасть по «плохому» URL-адресу через что-то еще на том же компьютере, например. рысь браузер?   -  person Marc B    schedule 07.06.2012
comment
Ничего как такового. Работает даже с wget en.wikipedia.org/wiki/Steve_Jobs. Я удивлен.   -  person Yahoo-Me    schedule 07.06.2012
comment
Можете ли вы попробовать установить пользовательский агент, например open(remote_full_url, "User-Agent" => "Mozilla/5.0 (Windows NT 6.0; rv:12.0) Gecko/20100101 Firefox/12.0 FirePHP/0.7.1"), на своей стороне?   -  person vstm    schedule 07.06.2012
comment
Да, теперь это работает. Не могли бы вы объяснить, в чем была проблема? Должен ли я закрыть этот вопрос или вы предоставите ответ, а не комментарий?   -  person Yahoo-Me    schedule 07.06.2012
comment
В API-вики написано, что запросы без user-agent блокируются и 403 возвращается. Но я не могу объяснить, почему это относится только к статье Steve_Jobs (к которой даже нет доступа через API). У них также есть политика пользовательского агента, но там ничего не указано, что код ошибки 403 используется. Так что у меня действительно нет ответа, который объясняет такое поведение.   -  person vstm    schedule 07.06.2012


Ответы (2)


Я думаю, что это происходит для заблокированных записей, таких как «Стив Джобс», «Эл-Гор» и т. Д. Это указано в той же книге, на которую вы ссылаетесь:

Для некоторых страниц, таких как заблокированная запись Эла Гора, Википедия не будет отвечать на веб-запрос, если не указан User-Agent. «User-Agent» обычно относится к вашему браузеру, и вы можете увидеть это, проверив заголовки, которые вы отправляете для любого запроса страницы в вашем браузере. Предоставив пару ключ-значение «User-Agent» (в основном я использую «Ruby», и это, похоже, работает), мы можем передать ее как хеш (в примере я использую константу HEADERS_HASH) в качестве второго аргумента вызов метода.

Это указано позже на http://ruby.bastardsbook.com/chapters/web-crawling/< /а>

person Arc    schedule 18.06.2012

Ваш код отлично работает для меня (Ruby MRI 1.9.3), когда я запрашиваю существующую вики-страницу.

Когда я запрашиваю несуществующую вики-страницу, я получаю код ошибки mediawiki 404.

  • Steve_Jobs => успех
  • Steve_Austin => успех
  • Steve_Rogers => успех
  • Steve_Foo => ошибка

Википедия выполняет тонну кэширования, поэтому, если вы видите ответы на «Steve_Jobs», которые отличаются от ответов других существующих людей, то, скорее всего, это происходит потому, что Википедия кэширует статью о Стиве Джобсе, потому что он известен. , и, возможно, добавление дополнительных проверок/верификаций для защиты статьи от быстрых изменений, порчи и т. д.

Решение для вас: всегда открывайте URL-адрес со строкой пользовательского агента.

rpage = open(remote_full_url, "User-Agent" => "Whatever you want here").read

Подробности из документов Mediawiki: «Когда вы делаете HTTP-запросы к API веб-службы MediaWiki, обязательно укажите заголовок User-Agent, который правильно идентифицирует ваш клиент. Не используйте User-Agent по умолчанию, предоставленный вашей клиентской библиотекой, но создайте собственный заголовок, который включает имя и номер версии вашего клиента: что-то вроде «MyCuteBot/0.1».

В вики Викимедиа, если вы не укажете заголовок User-Agent или предоставите пустой или универсальный заголовок, ваш запрос завершится с ошибкой HTTP 403. Ознакомьтесь с нашей политикой в ​​отношении агентов пользователей».

person joelparkerhenderson    schedule 10.06.2012
comment
Таким образом, я держу пари, что ваше первоначальное тестирование других имен было выполнено с помощью браузера, и вы видите кешированные результаты для них. Когда вы нажимаете Steve_Jobs, он не кэшируется, и, поскольку вы не использовали строку UA, вы получаете 403. - person Irongaze.com; 15.06.2012
comment
Я могу последовательно воспроизвести это с помощью curl. Страница «Вакансии» возвращает 403 без UA. Если предоставлен UA, он возвращает обычный ответ 200. Я попробовал несколько других страниц, и ни на одной не было такого поведения. Странный... - person alienhard; 16.06.2012