Ваша строка содержит HTML-сущности (будь то XML или HTML) и должна быть экранирована. ‘
и ’
соотносятся с ‘
и ’
соответственно.
Если вы используете html.unescape
, вы увидите очищенный текст:
>>> import html
>>> html.unescape('<tag>Sample ‘cp 99-3a’</tag>')
'<tag>Sample ‘cp 99-3a’</tag>'
Редактировать : @mzjn указал, что вы также можете исправить строку, добавив пропущенную точку с запятой во 2-й объект:
>>> import xml.etree.ElementTree as ET
>>> tag = ET.fromstring('<tag>Sample ‘cp 99-3a’</tag>')
>>> tag.text
'Sample \x91cp 99-3a\x92'
Но выубедитесь, что все еще есть символы \x91
и \x92
(и требует, чтобы вы могли контролировать содержимое строки). Это кодировки MS CP1252 для одинарных кавычек слева и справа. Использование метода html.unescape
, описанного выше, все равно даст вам очищенный текст.
Последующая обработка комментариев
В своем комментарии вы добавили дополнительную складку вашей строкисодержит другие допустимые escape-последовательности XML (такие как &
), которые html.unescape
будут удачно очищены. К сожалению, как вы видели, это в конечном итоге возвращает вас на круги своя, так как у вас теперь есть &
, что должно быть экранированным, но это не так (ElementTree
вырвется из него дляyou).
>>> import html
>>> import xml.etree.ElementTree as ET
>>> cleaned = html.unescape('<tag>&Sample ‘cp 99-3a’</tag>')
>>> print(cleaned)
<tag>&Sample ‘cp 99-3a’</tag>
>>> ET.fromstring(cleaned)
Traceback (most recent call last):
...
ParseError: not well-formed (invalid token): line 1, column 12
Некоторые другие варианты, которые у вас есть, попробуйте использовать soupparser
из lxml.html
, что намного лучше при работе с проблемным HTML / XML:
>>> from lxml.html import soupparser
>>> soupparser.fromstring('<tag>&Sample ‘cp 99-3 a’</tag>').text_content()
'&Sample ‘cp 99-3 a’'
Или, в зависимости от ваших потребностей, вам может быть лучше заменить строку / регулярное выражение перед анализом, чтобы удалить раздражающие символы cp1252:
>>> import re
# Matches "‘" or "’", with or without trailing semicolon
>>> node = ET.fromstring(re.sub(r'	[1-2];?', "'", '<tag>&Sample ‘cp 99-3 a’</tag>'))
>>> node.text
"&Sample 'cp 99-3 a'"