1

我正在使用 urllib2.request 查询 Web 服务并接收 XML。如果我违反了 Web 服务的速率限制(1 次调用/秒),我会收到 HTML 回复说我违反了速率限制。

尽管每次通话后我可以 time.sleep() 2-3 秒,但无论出于何种原因,我仍然违反了速率限制。

为了测试我的响应是 XML 还是 HTML,我使用 xml.dom.minidom() 然后测试是否存在 html 元素

try:
    dom = xml.dom.minidom.parseString(response_text)
  except xml.parsers.expat.ExpatError:
    return False

  if len(dom.getElementsByTagName('html')) == 0:
    return True
  else:
    return False

这样就完成了工作,但我遇到了一个 XML 属性包含 XML 的情况。在这种情况下, parseString() 命令失败并显示

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/python/default-2.6/lib/python2.6/xml/dom/minidom.py", line 1918, in     parse
    return expatbuilder.parse(file)
  File "/opt/python/default-2.6/lib/python2.6/xml/dom/expatbuilder.py", line 924, in parse
    result = builder.parseFile(fp)
  File "/opt/python/default-2.6/lib/python2.6/xml/dom/expatbuilder.py", line 207, in parseFile
    parser.Parse(buffer, 0)
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 3125

在这种情况下,第 3125 列是某些属性值文本的一部分,其中包含 &-pound-x-9(Stackoverflow 正在隐藏我的 unicode)。

xml.dom.minidom 应该能够处理这个吗?除了这个导致解析失败的 XML 是否还有其他问题?

此外,如果社区有其他处理此类情况的方法,我愿意接受。

如果有帮助,以下是当我违反其速率限制时 Web 服务返回的内容:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="eng">
    <head>
        <title>Service Temporarily Unavailable - Rate Limited</title>
    </head> 
    <body style="text-align:center;background-color:white;"> 
        <h1>Service Temporarily Unavailable</h1>
        <hr />
        <div>
            You have used this service too often in a short time.  Please wait before using this service again.
            <br/><br/>
            Please visit the <a href="http://wiki.xxxx.com/index.php?title=API_Usage">wiki</a> for more details.
        </div> 
    </body> 
</html>
4

2 回答 2

0

您还可以在尝试解析结果之前测试 HTML 字符串:

if response_text.lstrip().startswith('<!DOCTYPE html'):
    # we received an html response, sleep again
...

我也无法让 minidom 炸毁包含选项卡实体的属性。也许它是一个不正确终止的实体序列,比如&#9没有结束分号?Minidom 对于属性内正确转义的实体似乎没问题:

text = '<root><a href="&#9;foo&lt;">link</a></root>'
tree = minidom.parseString(text)
print tree.toxml()

u'<?xml version="1.0" ?>\n<root><a href="\tfoo&lt;">link</a></root>'
于 2011-05-08T14:39:46.873 回答
0

我认为那&#x9是一个标签。您应该尝试http://docs.python.org/library/htmllib.html#module-htmlentitydefs将特殊的 html 实体转换回它们本来的样子。(这可能有&lt;等问题)。或者你可以做一个用空格替换的字符串替换&#x9

就像一个建议一样,当您解析内容时,解析器遇到问题,例如不适合您的模式,而不是停止操作,您应该允许解析器继续,但会发出警告。通过这种方式,您可以看到问题所在,并可能纠正它,或者至少可以看到存在问题。

另外关于您的速率限制问题,为什么不将请求的 HTML 缓存一次,以便您可以在本地执行处理。

于 2011-05-07T16:23:51.833 回答