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

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

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

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

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


person Divya    schedule 07.09.2011    source источник
comment
Может ли это помочь? stackoverflow.com/questions/780334/   -  person Louis    schedule 07.09.2011


Ответы (1)


Вы не можете. 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()

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

person Devin Jeanpierre    schedule 07.09.2011
comment
Большое спасибо за ответ. Да, после стольких исследований я тоже обнаружил, что не могу использовать ElementTree для завершения своей работы. - person Divya; 07.09.2011
comment
Не могли бы вы объяснить, как вы использовали sgmllib для получения текста между тегами в html файле. Пожалуйста, exaplin с некоторым кодом, чтобы я мог понять. Я новичок в этой библиотеке, поэтому, пожалуйста, помогите мне. - person Divya; 07.09.2011
comment
Привет, спасибо тебе большое за это. Еще один вопрос. У меня есть html файл. Я хочу предоставить это как входной файл и проанализировать его, а затем записать обратно в этот файл. Как мне это сделать? Любой пример кода, который работает с указанным выше кодом, пожалуйста. - person Divya; 07.09.2011