Ошибка xml.dom.minidom.parse (), когда атрибут XML содержит Unicode - PullRequest
0 голосов
/ 07 мая 2011

Я запрашиваю веб-сервис, используя urllib2.request и получаю XML. Если я нарушу ограничение скорости веб-службы (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 является частью некоторого текста значения атрибута, который содержит ampersand-pound-x-9 (Stackoverflow скрывает мой юникод).

Должен ли xml.dom.minidom справиться с этим? Может ли быть другая проблема с XML помимо этого, которая вызывает сбой синтаксического анализа?

Кроме того, я открыт для других способов решения подобных ситуаций, если у сообщества есть такая.

Если это поможет, вот что возвращает веб-служба, когда я нарушил ограничение скорости:

<!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>

Ответы [ 2 ]

0 голосов
/ 08 мая 2011

Вы также можете проверить строку на HTML, прежде чем пытаться проанализировать результат:

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

Я также не смог заставить минидом взорвать атрибут, содержащий сущность табуляции. Возможно, это неправильно завершенная последовательность сущностей, например &#9 без конечной точки с запятой? Минидом кажется нормальным с правильно экранированными сущностями внутри атрибутов:

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>'
0 голосов
/ 07 мая 2011

Я думаю, что &#x9 это вкладка.Вам следует попробовать http://docs.python.org/library/htmllib.html#module-htmlentitydefs, чтобы преобразовать специальные html-сущности обратно в то, чем они являются.(Это может иметь проблему &lt; и т. Д.).Или вы можете выполнить подстановку строк, которые заменят &#x9 пробелом.

Просто как совет, когда вы разбираете вещи, и анализатор сталкивается с проблемой, такой как несоответствие вашего шаблона, вместо этогочтобы остановить операцию, вы должны позволить парсеру продолжить, но выложить предупреждение.Таким образом, вы можете увидеть, в чем проблема, и, возможно, исправить ее, или, по крайней мере, увидеть, что есть проблема.

Также, что касается вашей проблемы с ограничением скорости, почему бы не кэшировать запрошенный HTML один раз, чтобы вы могливыполнить обработку локально.

...