【问题标题】:Python's `urllib2`: Why do I get error 403 when I `urlopen` a Wikipedia page?Python的`urllib2`:当我`urlopen`维基百科页面时,为什么会出现错误403?
【发布时间】:2019-12-26 21:51:49
【问题描述】:

我在尝试 urlopen 维基百科的某个页面时遇到了一个奇怪的错误。这是页面:

http://en.wikipedia.org/wiki/OpenCola_(drink)

这是 shell 会话:

>>> f = urllib2.urlopen('http://en.wikipedia.org/wiki/OpenCola_(drink)')
Traceback (most recent call last):
  File "C:\Program Files\Wing IDE 4.0\src\debug\tserver\_sandbox.py", line 1, in <module>
    # Used internally for debug sandbox under external interpreter
  File "c:\Python26\Lib\urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "c:\Python26\Lib\urllib2.py", line 397, in open
    response = meth(req, response)
  File "c:\Python26\Lib\urllib2.py", line 510, in http_response
    'http', request, response, code, msg, hdrs)
  File "c:\Python26\Lib\urllib2.py", line 435, in error
    return self._call_chain(*args)
  File "c:\Python26\Lib\urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "c:\Python26\Lib\urllib2.py", line 518, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden

这发生在不同大陆的两个不同系统上。有谁知道为什么会这样?

【问题讨论】:

  • 您可能希望对这些括号进行 URL 编码。不过,这并不是说它有助于对抗 403。
  • 您也可以使用来自维基媒体 api mediawiki.org/wiki/API:Main_page的链接

标签: python http urllib2


【解决方案1】:

Wikipedias stance is:

数据检索:不得使用机器人 检索批量内容以供任何使用 与已批准的没有直接关系 机器人任务。这包括动态 从另一个网站加载页面, 这可能会导致网站 列入黑名单并永久拒绝 使用权。如果你想下载 批量内容或镜像项目, 请通过下载或托管来完成 您自己的数据库副本。

这就是 Python 被阻止的原因。你应该download data dumps

无论如何,你可以在 Python 2 中阅读这样的页面:

req = urllib2.Request(url, headers={'User-Agent' : "Magic Browser"}) 
con = urllib2.urlopen( req )
print con.read()

或者在 Python 3 中:

import urllib
req = urllib.request.Request(url, headers={'User-Agent' : "Magic Browser"}) 
con = urllib.request.urlopen( req )
print(con.read())

【讨论】:

  • "这就是 Python 被阻止的原因。" 我不明白这句话是什么意思?但是,即使我列出了“User-Agent”并随机选择其中一个来构建 url,网站也会向我发送“urllib2.URLError: ”或者只是阻止我的 ip 访问他们的网站。你能给我更多的想法吗?非常感谢。
  • 他们还阻止 HEAD 请求是非常荒谬的,这很有用,例如验证用户发布的所有链接。
  • 这种方法也适用于我返回 403 的 HTTPS 页面。为什么它有效,而 urllib2.urlopen() 导致 403?
  • 另外,如果您在使用 api 时遇到错误 403,您应该使用上述解决方案
【解决方案2】:

要对此进行调试,您需要捕获该异常。

try:
    f = urllib2.urlopen('http://en.wikipedia.org/wiki/OpenCola_(drink)')
except urllib2.HTTPError, e:
    print e.fp.read()

当我打印结果消息时,它包括以下内容

"英文

我们的服务器目前正在经历 一个技术问题。这大概是 临时的,应该尽快修复。 请在几分钟后再试一次。 "

【讨论】:

  • 文件“”,第 3 行,除了 urllib2.HTTPError,e: ^ SyntaxError: invalid syntax
  • @KHANirfan 那是 python2 语法。 Python3 异常语法为“except Exception as e: print(e)”。
【解决方案3】:

网站通常会通过检查是否由公认的用户代理访问来过滤访问。维基百科只是将您的脚本视为机器人并拒绝它。尝试欺骗浏览器。以下链接将向您展示如何操作。

http://wolfprojects.altervista.org/changeua.php

【讨论】:

    【解决方案4】:

    某些网站会通过读取 urllib 发送的标头来阻止来自脚本的访问,以避免对其服务器的“不必要”使用。我不知道也无法想象为什么维基百科会/会这样做,但是您是否尝试过欺骗您的标题?

    【讨论】:

      【解决方案5】:

      正如 Jochen Ritzel 所说,维基百科屏蔽了机器人。

      但是,如果机器人使用 PHP api,它们不会被阻止。 获取标题为“love”的维基百科页面:

      http://en.wikipedia.org/w/api.php?format=json&action=query&titles=love&prop=revisions&rvprop=content

      【讨论】:

        【解决方案6】:

        我使用没有被我需要的站点阻止的 php 解决了这个问题。

        可以这样访问:

        path='http://phillippowers.com/redirects/get.php? 
        file=http://website_you_need_to_load.com'
        req = urllib2.Request(path)
        response = urllib2.urlopen(req)
        vdata = response.read()
        

        这会将html代码返回给您

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-06
          • 2010-12-26
          • 2022-01-10
          • 2013-11-13
          • 1970-01-01
          相关资源
          最近更新 更多