【问题标题】:How to get round the HTTP Error 403: Forbidden with urllib.request using Python 3如何绕过 HTTP 错误 403: Forbidden with urllib.request using Python 3
【发布时间】:2017-08-09 08:22:12
【问题描述】:

您好,不是每次,但有时在尝试访问 LSE 代码时,我会遇到每个烦人的 HTTP 错误 403:禁止消息。

任何人都知道我如何仅使用标准 python 模块来解决这个问题(遗憾的是没有漂亮的汤)。

import urllib.request

url = "http://www.londonstockexchange.com/exchange/prices-and-markets/stocks/indices/ftse-indices.html"
infile = urllib.request.urlopen(url) # Open the URL
data = infile.read().decode('ISO-8859-1') # Read the content as string decoded with ISO-8859-1

print(data) # Print the data to the screen

然而,这就是我经常看到的错误:

Traceback (most recent call last):
  File "/home/ubuntu/workspace/programming_practice/Assessment/Summative/removingThe403Error.py", line 5, in <module>
    webpage = urlopen(req).read().decode('ISO-8859-1')
  File "/usr/lib/python3.4/urllib/request.py", line 161, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.4/urllib/request.py", line 469, in open
    response = meth(req, response)
  File "/usr/lib/python3.4/urllib/request.py", line 579, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.4/urllib/request.py", line 507, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.4/urllib/request.py", line 441, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.4/urllib/request.py", line 587, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden


Process exited with code: 1

链接到所有可用模块的列表:https://docs.python.org/3.4/py-modindex.html

非常感谢。

【问题讨论】:

标签: python python-3.x urllib http-status-code-403 urllib3


【解决方案1】:

这可能是由于 mod_security。您需要通过以浏览器而不是 python urllib 的方式打开 URL 来进行欺骗。

在这里,我更正了您的代码:

import urllib.request

url = "http://www.londonstockexchange.com/exchange/prices-and-markets/stocks/indices/ftse-indices.html"

# Open the URL as Browser, not as python urllib
page=urllib.request.Request(url,headers={'User-Agent': 'Mozilla/5.0'}) 
infile=urllib.request.urlopen(page).read()
data = infile.decode('ISO-8859-1') # Read the content as string decoded with ISO-8859-1

print(data) # Print the data to the screen

接下来,您可以使用BeautifulSoup 抓取 HTML。

【讨论】:

    【解决方案2】:

    您似乎受到了速率限制。尝试进入睡眠状态并重试。例如:

    import urllib
    import urllib.request
    from time import sleep
    
    LSE_URL = "http://www.londonstockexchange.com/exchange/prices-and-markets/stocks/indices/ftse-indices.html"
    WAIT_PERIOD = 15
    
    def stock_data_reader():
        stock_data = get_stock_data()
        while True:
            if not stock_data:
                sleep(WAIT_PERIOD) # sleep for a while until next retry
                stock_data = get_stock_data()                
            else:
                break
    
        print(stock_data) # do something with stock data
    
    
    
    def get_stock_data():
        try:
            infile = urllib.request.urlopen(LSE_URL) # Open the URL
        except urllib.error.HTTPError as http_err:
            print("Error: %s" % http_err)
            return None
        else:
            data = infile.read().decode('ISO-8859-1') # Read the content as string decoded with ISO-8859-1
            return data
    
    
    stock_data_reader()
    

    【讨论】:

    • 非常感谢!尽管有什么方法可以在不使用异常的情况下做到这一点?我不是 100% 我大声使用它。
    • Nope 确认没有大声使用 exepts - 抱歉,还有其他方法吗?
    • 你能用 requests 库 (docs.python-requests.org/en/master) 代替 urllib 吗?我在使用它时没有遇到 403 错误。
    • 感谢您的评论,但我们可以大声使用的唯一模块是 docs.python.org/3.4/py-modindex.html,请求库不是其中的一部分:/
    • 不幸的是,我没有想法。你可以调用像 curl 这样的 cli 工具吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 2017-05-04
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多