【问题标题】:XML-RPC python client raising xml.parsers.expat.ExpatError exceptionXML-RPC python 客户端引发 xml.parsers.expat.ExpatError 异常
【发布时间】:2013-02-17 22:48:38
【问题描述】:

我正在尝试使用 xmlrpclib python 的 lib 执行 XMP-RPC,但我得到了

xml.parsers.expat.ExpatError: XML or text declaration not at start of entity: line 1, column 1

这是带参数的字典:

{'cliente_chave': 'hUi238sh328sjk37Hms8Kisjeg9',
     'cliente_codigo': 164,
     'imovel_bairro': u'Renascen\xe7a',
     'imovel_banheiros': u'5',
     'imovel_cidade': u'S\xe3o Lu\xeds - MA',
     'imovel_codigo_imobiliaria': u'757',
     'imovel_descricao': u'\n\t\t\t\n\t\t\tCasa em otima localiza\xe7\xe3o ideal tanto para empresas quanto para moradia tendo:\r\nTerra\xe7o\r\nSala Ampla para 03 ambientes\r\nLavabo\r\nHall\r\n03 su\xedtes\r\nEscritorio\r\nCozinha\r\nQuintaL\r\n\xc1rea de Servi\xe7o\r\nDCE\r\nGaragem coberta para 02 carros\r\nPort\xe3o eletronico\r\nCisterna\r\nNascente',
     'imovel_estado': 'MA',
     'imovel_negociacao': 'venda',
     'imovel_novo': False,
     'imovel_quartos': u'3',
     'imovel_subtipo': u'padr\xe3o',
     'imovel_suites': u'3',
     'imovel_tipo': u'casa',
     'imovel_vagas': u'2',
     'imovel_valor': u' 480.000,00',
     'url': 'http://www.estiloma.com.br/imoveis/para-venda/em-sao-luis/no-bairro-renascenca/casa-padrao/id-774.html'}

这里是异常的追溯:

Traceback (most recent call last):
      File "/Library/Python/2.7/site-packages/Twisted-12.2.0-py2.7-macosx-10.8-intel.egg/twisted/internet/defer.py", line 551, in _runCallbacks
        current.result = callback(current.result, *args, **kw)
      File "/Users/bslima/Documents/Aptana Studio 3 Workspace/aqueleimovel/aqueleimovel/pipelines.py", line 31, in process_item
        result = server.salvar_imovel(dict(item))
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1224, in __call__
        return self.__send(self.__name, args)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1575, in __request
        verbose=self.__verbose
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1264, in request
        return self.single_request(host, handler, request_body, verbose)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1297, in single_request
        return self.parse_response(response)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1467, in parse_response
        p.feed(data)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 557, in feed
        self._parser.Parse(data, 0)
    xml.parsers.expat.ExpatError: XML or text declaration not at start of entity: line 1, column 1

我只对字符串使用 UTF-8,如果运气不好,我会尝试将其编码或解码为 UTF-8。 我也尝试用谷歌搜索,但没有成功。有人看过吗?

哦,这是客户端代码:

server = ServerProxy(uri=settings.RPC_SERVER, verbose=True)
server.salvar_imovel(item)

提前感谢您的帮助。

正如我所评论的,ExpatError 在响应对象中。谢谢

【问题讨论】:

  • 我在回溯中注意到,问题出在响应中,而不是在请求中。我将调查响应以了解发生了什么。谢谢@danodonovan

标签: python xml xml-rpc rpc xmlrpclib


【解决方案1】:

[已解决] 响应的开头带有空格。 我不得不从 xmlrpc 扩展 Transport 类并简单地剥离响应。

from xmlrpc.client import SafeTransport, Transport
from xmlrpc.client import GzipDecodedResponse

is_https = False
if is_https:
    BaseTransport = SafeTransport
else:
    BaseTransport = Transport

class CustomTransport(BaseTransport):
    def parse_response(self, response):
        # read response data from httpresponse, and parse it

        # Check for new http response object, else it is a file object
        if hasattr(response,'getheader'):
            if response.getheader("Content-Encoding", "") == "gzip":
                stream = GzipDecodedResponse(response)
            else:
                stream = response
        else:
            stream = response

        p, u = self.getparser()

        while 1:
            data = stream.read(1024)
            data = data.strip()
            if not data:
                break
            if self.verbose:
                print "body:", repr(data)
            p.feed(data)

        if stream is not response:
            stream.close()
        p.close()

        return u.close()

【讨论】:

  • 小备注:要在 HTTPS 服务器上调用方法,我必须传递 SafeTransport 而不是 Transport,否则调用的是 http:// URL,而不是 https://。要使用它,不要忘记从 xmlrpclib 导入 Transport(或 SafeTransport)和 GzipDecodedResponse。在我的例子中,这允许我在 Drupal XML-RPC 响应的开头去除额外的“\n”。
【解决方案2】:

您似乎正在将 dict 对象传递给期望 XML 的对象 - 这一行

server.salvar_imovel(dict(item))

如果你真的必须传入dict,你可以先尝试序列化dict。有一些示例代码here

【讨论】:

  • 我在回溯中注意到,问题出在响应中,而不是在请求中。我将调查响应以了解发生了什么。谢谢@danodonovan
猜你喜欢
  • 2020-07-31
  • 2016-09-15
  • 2016-10-13
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多