suds SOAP库的HTTP认证异常行为

6 投票
1 回答
7387 浏览
提问于 2025-04-16 13:02

我有一个能正常工作的Python程序,它通过SOAP协议使用suds库获取大量数据。这个网络服务有一个分页功能,这样我每次可以抓取nnn行数据,然后在后续的调用中再抓取下一批nnn行数据。如果我用下面的代码来进行HTTP服务器的身份验证,

client = suds.client.Client(url=url, location=location, username=username, password=password, timeout=timeout)

一切都运行得很好。不过,如果我使用下面的代码,

t = suds.transport.https.HttpAuthenticated(username=username, password=password)
t.handler = urllib2.HTTPBasicAuthHandler(t.pm)
t.urlopener = urllib2.build_opener(t.handler)
client = suds.client.Client(url=url, location=location, timeout=timeout, transport=t) 

它只会在前6次调用中正常工作。也就是说,如果我每次请求限制为10行数据,我总共会收到60行数据。但是在第七次请求时,我收到的却是

  File "build/bdist.linux-i686/egg/suds/client.py", line 542, in __call__
  File "build/bdist.linux-i686/egg/suds/client.py", line 602, in invoke
  File "build/bdist.linux-i686/egg/suds/client.py", line 649, in send
  File "build/bdist.linux-i686/egg/suds/client.py", line 698, in failed
AttributeError: 'NoneType' object has no attribute 'read'

有没有人能给点建议,看看这可能是什么原因造成的?肯定是这个变化导致了问题。我可以在两种身份验证方式之间切换,而且每次都能重现这个问题。

我使用的是Python 2.6.6和suds 0.4。

谢谢

1 个回答

10

问题似乎是因为在更低层次上抛出了一个 urllib2.HTTPError 错误,而它的 fp 属性是 None:

suds.transport.http 的第81行:

except u2.HTTPError, e:
    if e.code in (202,204):
        result = None
    else:
        raise TransportError(e.msg, e.code, e.fp)

这个异常最终传递到 suds.client 的第698行,在那里 error.fp.read() 这一行出错了:

def failed(self, binding, error):
    status, reason = (error.httpcode, tostr(error))
    reply = error.fp.read()

我建议你对 suds.SoapClient 类进行一些修改,以获取 HTTP 错误代码和消息。在你创建 suds.Client 之前,添加这些代码行,然后运行它,看看第七次请求抛出了什么 HTTP 错误:

class TestClient(suds.client.SoapClient):
    def failed(self, binding, error):
        print error.httpcode, error.args

suds.client.SoapClient = TestClient

撰写回答