使用urllib时Python3:HTTP错误302

时间:2017-09-26 10:06:32

标签: python python-3.x web urllib

我想从网站上阅读不同股票的价值。因此,我编写了这个小脚本,它读取页面源,然后解析出值:

stock_reader.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from re import search
from urllib import request


def main():
    links = [
        [
            'CSG',
            'UBS',
        ],
        [
            'http://www.tradegate.de/orderbuch.php?isin=CH0012138530',
            'http://www.tradegate.de/orderbuch.php?isin=CH0244767585',
        ],
    ]

    for i in in range(len(links[0])):
        url = links[1][i]
        htmltext = request.urlopen(url).read().decode('utf-8')
        source = htmltext.splitlines()
        for line in source:
            if 'id="bid"' in line:
                m = search('\d+.\d+', line)
                print('{}'.format(m.string[m.start():m.end()]))


if __name__ == '__main__':
    main()

有时可行但有时会出现此错误:

错误消息

Traceback (most recent call last):
  File "./aktien_reader.py", line 39, in <module>
    main()
  File "./aktien_reader.py", line 30, in main
    htmltext = request.urlopen(url).read().decode('utf-8')
  File "/usr/lib/python3.3/urllib/request.py", line 160, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.3/urllib/request.py", line 479, in open
    response = meth(req, response)
  File "/usr/lib/python3.3/urllib/request.py", line 591, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.3/urllib/request.py", line 511, in error
    result = self._call_chain(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 451, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 696, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python3.3/urllib/request.py", line 479, in open
    response = meth(req, response)
  File "/usr/lib/python3.3/urllib/request.py", line 591, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.3/urllib/request.py", line 511, in error
    result = self._call_chain(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 451, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 696, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python3.3/urllib/request.py", line 479, in open
    response = meth(req, response)
  File "/usr/lib/python3.3/urllib/request.py", line 591, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.3/urllib/request.py", line 511, in error
    result = self._call_chain(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 451, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 696, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python3.3/urllib/request.py", line 479, in open
    response = meth(req, response)
  File "/usr/lib/python3.3/urllib/request.py", line 591, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.3/urllib/request.py", line 511, in error
    result = self._call_chain(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 451, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 696, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python3.3/urllib/request.py", line 479, in open
    response = meth(req, response)
  File "/usr/lib/python3.3/urllib/request.py", line 591, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.3/urllib/request.py", line 511, in error
    result = self._call_chain(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 451, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 686, in http_error_302
    self.inf_msg + msg, headers, fp)
urllib.error.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop.
The last 30x error message was:
Found

我的问题是:为什么会发生这种情况,我该如何避免呢?

3 个答案:

答案 0 :(得分:2)

这可能是因为目标网站使用Cookie并在您不发送Cookie时重定向您。

你可以使用的是这样的东西:

from http.cookiejar import CookieJar

url = "http://www.tradegate.de/orderbuch.php?isin=CH0012138530"

req = urllib.request.Request(url, None, {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3','Accept-Encoding': 'gzip, deflate, sdch','Accept-Language': 'en-US,en;q=0.8','Connection': 'keep-alive'})

cj = CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
response = opener.open(req)
response.read()

这样,您支持Cookies,网站将允许您获取页面: - )

另一种方法是使用最简单的requests package。在你的情况下,它会导致:

import requests

url = "http://www.tradegate.de/orderbuch.php?isin=CH0012138530"
r = requests.get(url, headers={'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'}, timeout=15)
print(r.content)

答案 1 :(得分:0)

此答案是CédricJ的答案的简化。您确实不需要导入CookieJar 或设置各种Accept标头,如果您不想要的话至。不过,通常您应该设置超时。已使用Python 3.7进行了测试。通常,我会记住要为Cookie使用的每个随机URL使用新的开启程序

from urllib.request import build_opener, HTTPCookieProcessor, Request
url = 'https://www.cell.com/cell-metabolism/fulltext/S1550-4131(18)30630-2'
opener = build_opener(HTTPCookieProcessor())

没有Request对象:

response = opener.open(url, timeout=30)
content = response.read()

带有Request对象:

request = Request(url)
response = opener.open(request, timeout=30)
content = response.read()

答案 2 :(得分:-1)

HTTP状态代码302它是一种重定向,它将有一个带有新URL的标题以供访问(不需要工作的URL ..)

地点:http://www.example.com/x/y/

这常常被用来阻止那些在很短的时间内做出很多请求的机器人。所以不是编码问题。