【问题标题】:`open_http': 403 Forbidden (OpenURI::HTTPError) for the string "Steve_Jobs" but not for any other string`open_http': 403 Forbidden (OpenURI::HTTPError) for the string "Steve_Jobs" 但不适用于任何其他字符串
【发布时间】:2012-06-11 03:22:02
【问题描述】:

我正在阅读http://ruby.bastardsbook.com/ 提供的 Ruby 教程,我遇到了以下代码:

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 以外的任何内容时,它都能正常工作。这里发生了什么?

【问题讨论】:

  • 有代理或可能过滤 url 的东西吗?您是否尝试过通过同一台机器上的其他东西点击“坏”网址,例如lynx 浏览器?
  • 没什么。甚至可以使用 wget "en.wikipedia.org/wiki/Steve_Jobs"。我很惊讶。
  • 您可以尝试设置像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") 这样的用户代理吗?
  • 是的,现在可以使用了。你能解释一下是什么问题吗?我应该结束这个问题还是你会提供答案而不是评论?
  • API-wiki 中它说没有用户代理的请求被阻止并返回403。但我无法真正解释为什么这只适用于“Steve_Jobs”文章(甚至无法使用 API 访问)。他们也有一个user-agent policy,但没有任何迹象表明使用了 403 错误代码。所以我真的没有答案来解释这种行为。

标签: ruby open-uri http-error


【解决方案1】:

当我请求一个存在的 wiki 页面时,您的代码运行良好(Ruby MRI 1.9.3)。

当我请求一个不存在的 wiki 页面时,我收到 mediawiki 404 错误代码。

  • Steve_Jobs => 成功
  • Steve_Austin => 成功
  • Steve_Rogers => 成功
  • Steve_Foo => 错误

Wikipedia 进行了 ton 的缓存,因此如果您看到对“Steve_Jobs”的响应与其他确实存在的人不同,那么最好猜测这是因为 wikipedia 正在缓存 Steve Jobs 文章因为他很有名,并且可能会添加额外的检查/验证以保护文章免受快速更改、损坏等。

您的解决方案:始终使用用户代理字符串打开 url。

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

Mediawiki 文档中的详细信息:“当您向 MediaWiki Web 服务 API 发出 HTTP 请求时,请务必指定正确标识您的客户端的 User-Agent 标头。不要使用您的客户端提供的默认 User-Agent库,但组成一个自定义标头,其中包含客户端的名称和版本号:类似于“MyCuteBot/0.1”。

在 Wikimedia wiki 上,如果您不提供 User-Agent 标头,或者您提供空的或通用的标头,您的请求将失败并出现 HTTP 403 错误。请参阅我们的用户代理政策。”

【讨论】:

  • 因此,我打赌您对其他名称的初始测试是使用浏览器完成的,并且您会看到这些名称的缓存结果。当你点击“Steve_Jobs”时,它没有被缓存,因为你没有使用 UA 字符串,所以你得到了 403。
  • 我可以通过 curl 始终如一地重现这一点。 Jobs 页面返回 403 w/o UA。如果提供了 UA,则它返回正常的 200 响应。我尝试了其他几页,但没有一个有这种行为。奇怪...
【解决方案2】:

我认为这发生在像“史蒂夫乔布斯”、“阿尔戈尔”等被锁定的条目上。这在你所指的同一本书中有所说明:

对于某些页面——例如 Al Gore 的锁定条目——维基百科将 如果未指定 User-Agent,则不响应 Web 请求。这 “用户代理”通常是指您的浏览器,您可以通过 检查您为浏览器中的任何页面请求发送的标头。 通过提供“User-Agent”键值对,(我基本上使用“Ruby” 它似乎有效),我们可以将它作为哈希传递(我使用常量 示例中的 HEADERS_HASH)作为方法的第二个参数 打电话。

稍后在http://ruby.bastardsbook.com/chapters/web-crawling/指定

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 2016-05-27
    • 2013-06-23
    • 1970-01-01
    相关资源
    最近更新 更多