1

urllib2.request を使用して Web サービスにクエリを実行し、XML を受信して​​います。Web サービスのレート制限 (1 呼び出し/秒) に違反すると、レート制限に違反したことを示す HTML が返されます。

各呼び出しの後に 2 ~ 3 秒間 time.sleep() を実行できますが、何らかの理由でレート制限に違反しています。

応答が 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 属性の 1 つに 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 は ampersand-pound-x-9 を含む属性値テキストの一部です (Stackoverflow はユニコードを隠しています)。

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 に答える