BeautifulSoup4 извлекает все типы условных комментариев

Что я пытаюсь сделать:

Удаляйте подозрительные комментарии из писем в формате html с помощью bs4. Теперь я столкнулся с проблемой с так называемым conditional comments типа downlevel-revealed.

См.: https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/compatibility/ms537512(v=vs.85)#syntax-of-условныекомментарии

import bs4

html = 'A<!--[if expression]>a<![endif]-->' \
       'B<![if expression]>b<![endif]>'


soup = bs4.BeautifulSoup(html, 'html5lib')

for comment in soup.find_all(text=lambda text: isinstance(text, bs4.Comment)):
    comment.extract()

Перед извлечением комментариев:

'A',
'[if expression]>a<![endif]',
'B',
'[if expression]',
'b',
'[endif]',

После извлечения комментариев:

'A',
'B',
'b',

Проблема:

Маленькая буква b также должна быть удалена. Проблема в том, что bs4 определяет первый комментарий как один объект комментария, а второй — как 3 объекта. Комментарий(если), NavigableString(b) и Комментарий(endif). Извлечение просто удаляет оба типа комментариев. NavigableString с содержимым «b» остается в DOM.

Есть ли какое-нибудь решение?


person tzanke    schedule 23.10.2018    source источник


Ответы (1)


После некоторого времени чтения об условных комментариях я могу понять, почему это происходит именно так.

скрытый на нижнем уровне

downlevel-hidden в основном пишутся как обычный комментарий <!-- ... -->. Это определяется как условный блок комментариев в современных браузерах. Поэтому BeautifulSoup полностью удаляет его, если я хочу удалить условные комментарии.

раскрытый на нижнем уровне

downlevel-revealed записываются как <!...>b<!...>, современные браузеры определяют два тега как недействительные и игнорируют их в DOM, поэтому только b остается действительным. Итак, BeautifulSoup удаляет только теги, а не контент.

Заключение

BeautifulSoup обрабатывает условные комментарии так же, как и современные браузеры. Это совершенно нормально для моих обстоятельств.

person tzanke    schedule 14.11.2018