【问题标题】:Python urllib2.HTTPError: HTTP Error 503: Service Unavailable on valid websitePython urllib2.HTTPError:HTTP 错误 503:有效网站上的服务不可用
【发布时间】:2014-09-19 14:16:59
【问题描述】:

我一直在使用亚马逊的产品广告 API 来生成包含给定书籍价格的网址。我生成的一个网址如下:

http://www.amazon.com/gp/offer-listing/0415376327%3FSubscriptionId%3DAKIAJZY2VTI5JQ66K7QQ%26tag%3Damaztest04-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0415376327

当我单击链接或将链接粘贴到地址栏时,网页加载正常。但是,当我执行以下代码时出现错误:

url = "http://www.amazon.com/gp/offer-listing/0415376327%3FSubscriptionId%3DAKIAJZY2VTI5JQ66K7QQ%26tag%3Damaztest04-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0415376327"
html_contents = urllib2.urlopen(url)

错误是 urllib2.HTTPError: HTTP Error 503: Service Unavailable。首先,我不明白为什么自从网页成功加载后我什至会收到这个错误。

另外,我注意到的另一个奇怪的行为是,以下代码有时会出现,有时不会给出所述错误:

html_contents = urllib2.urlopen("http://www.amazon.com/gp/offer-listing/0415376327%3FSubscriptionId%3DAKIAJZY2VTI5JQ66K7QQ%26tag%3Damaztest04-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0415376327")

我完全不知道这种行为是如何发生的。有什么解决方法或解决方法吗?我的目标是读取 url 的 html 内容。

编辑

我不知道为什么堆栈溢出会更改我的代码以将我在代码中上面列出的亚马逊链接更改为 rads.stackoverflow。无论如何,忽略 rads.stackoverflow 链接并在引号之间使用我上面的链接。

【问题讨论】:

  • 如果我没记错的话,rads.stackoverflow.com 是(或曾经是)SO 实施然后废弃的广告服务。很可能存在某种使用限制(推荐人、客户等等)
  • 出于某种随机原因,我不知道为什么链接更改为包含堆栈溢出标记。但是,如果我将复制和粘贴链接保留在地址栏上,网站就可以正常工作。
  • 啊,我明白了!不错 :) 这一定是 SO 注释解析器。

标签: python urllib2


【解决方案1】:

亚马逊拒绝 urllib2 的默认用户代理。一种解决方法是使用 requests 模块

import requests
page = requests.get("http://www.amazon.com/gp/offer-listing/0415376327%3FSubscriptionId%3DAKIAJZY2VTI5JQ66K7QQ%26tag%3Damaztest04-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0415376327")
html_contents = page.text

如果你坚持使用 urllib2,可以通过以下方式伪造标头:

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
response = opener.open('http://www.amazon.com/gp/offer-listing/0415376327%3FSubscriptionId%3DAKIAJZY2VTI5JQ66K7QQ%26tag%3Damaztest04-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0415376327')
html_contents = response.read()

不用担心 stackoverflow 会编辑 URL。他们解释说他们正在这样做here

【讨论】:

  • 由于某种奇怪的原因,链接更改为包含堆栈溢出标记。但是,如果您复制并粘贴地址栏上的链接,一切正常。您可以使用我的以下链接更新您的答案,看看它是否有效,因为它对我不起作用?
  • Stack Overflow 正在压缩较长的链接或任何外部链接,以便以更简洁的方式显示内容。这也可能是出于将实际链接粘贴到可以在界面上格式化为代码的安全漏洞。在您的真实代码中,放置您喜欢的任何链接,一切都应该可以正常工作。
  • python 3 版本?
【解决方案2】:

这是因为亚马逊不允许自动访问他们的数据,所以他们拒绝了您的请求,因为它不是来自正确的浏览器。如果您查看 503 响应的内容,它会说:

要讨论对亚马逊数据的自动访问,请联系 api-services-support@amazon.com。 有关迁移到我们 API 的信息,请参阅我们的 Marketplace API,网址为 https://developer.amazonservices.com/ref=rm_5_sv, 或我们的产品广告 API https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html/ref=rm_5_ac 用于广告用例。

这是因为 Python 的 urllibUser-Agent 显然不是浏览器。你总是可以伪造User-Agent,但这不是很好(或道德)的做法。

作为旁注,正如另一个答案中提到的,requests 库非常适合 Python 中的 HTTP 访问。

【讨论】:

  • 我正在查看您关于使用 User-Agent 的声明,并想知道我是否需要为 urllib2 添加类似这样的标题:stackoverflow.com/questions/802134/…
  • 是的,这就是您更改用户代理的方式。同样,requestshere 在这方面要好得多。
  • 伪造用户代理(或任何其他私人数据)并没有什么不道德的!!!这些公司(或任何人)没有上帝赋予的权利来了解您使用的浏览器、您拥有的设备或访问的网站。人们对他们的数据撒谎的越多越好。他们可以并且将使用该信息来对付您。他们会毫不犹豫地获得对你的优势,所以你不应该!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
  • 2012-10-29
  • 1970-01-01
相关资源
最近更新 更多