функция записи Python ElementTree - PullRequest
       6

функция записи Python ElementTree

3 голосов
/ 07 сентября 2011

Я использую Python ElementTree для чтения и изменения содержимого моих html-файлов. Когда я закончу с изменениями и использую функцию ElementTree.write,

1) он добавляет дополнительный html: infront из всех тегов. Как мне этого избежать?

2) Это также добавляет и где у меня есть специальные символы. Как мне этого избежать?

Спасибо, Дивья.

1 Ответ

1 голос
/ 07 сентября 2011

Вы не можете. ElementTree работает, загружая XML, анализируя его и сохраняя только абстрактное представление. Он записывает это в строку путем обхода абстрактного представления, но не помнит такие вещи, как то, какие символы были экранированы как сущности, или был ли элемент сохранен как <foo/> или <foo></foo> (HTML: <foo> или <foo></foo>)

Теперь, поскольку ElementTree работает только с XML (не HTML), я предполагаю, что вы работаете с lxml.html - в этом случае он фактически автоматически исправляет определенные формы ошибочного HTML потому что в противном случае он не сможет правильно его хранить.

Правильный способ обработки HTML-кода, данные которого вы хотите, чтобы полностью сохранился, за исключением того, как вы его изменили, - это захватить его в токены, которые запоминают их исходное представление. Я сделал это, используя sgmllib , но это несовершенно - например, есть метод get_starttag_text для получения точного содержимого начального тега, но нет соответствующего метода для конечных тегов. Это может быть достаточно хорошо в любом случае.

Например, чтобы выписать HTML, в котором удалены все абзацы, можно написать такую ​​функцию:

from cStringIO import StringIO

class SGMLModifier(sgmllib.SGMLParser):
    def __init__(self, *args, **kwargs):
        sgmllib.SGMLParser.__init__(self, *args, **kwargs)
        self._file = StringIO()

    def getvalue(self):
        return self._file.getvalue()

    def start_b(self, attributes):
        # skip it
        pass

    def end_b(self):
        # skip it
        pass

    def unknown_starttag(self, tag, attributes):
        self._file.write(self.get_starttag_text())

    def unknown_endtag(self, tag):
        # we can't get this verbatim.
        self._file.write('</%s>' % tag)

    def handle_comment(self, comment):
        # no verbatim here either.
        self._file.write('<!-- %s -->' % comment)

    def handle_data(self, data):
        self._file.write(data)

    def convert_entityref(self, ref):
        return '&' + ref + ';'

def remove_bold(html):
    parser = SGMLModifier()
    parser.feed(html)
    return parser.getvalue()

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

...