BeautifulSoup: удалите указанные атрибуты, но сохраните тег и его содержимое
Я пытаюсь "defrontpagify" html веб-сайта, созданного MS FrontPage, и я пишу сценарий BeautifulSoup для этого.
однако я застрял на той части, где я пытаюсь удалить определенный атрибут (или атрибуты списка) из каждого тега в документе, который их содержит. Фрагмент кода:
REMOVE_ATTRIBUTES = ['lang','language','onmouseover','onmouseout','script','style','font',
'dir','face','size','color','style','class','width','height','hspace',
'border','valign','align','background','bgcolor','text','link','vlink',
'alink','cellpadding','cellspacing']
# remove all attributes in REMOVE_ATTRIBUTES from all tags,
# but preserve the tag and its content.
for attribute in REMOVE_ATTRIBUTES:
for tag in soup.findAll(attribute=True):
del(tag[attribute])
он выполняется без ошибок, но на самом деле не все атрибуты. Когда я запускаю его без внешнего цикла, просто жестко кодирую один атрибут (суп.findAll ('style' =True), он работает.
кто-нибудь видит здесь проблему?
PS-мне тоже не очень нравятся вложенные циклы. Если кто-нибудь знает более функциональный стиль карты/фильтра, я бы хотел его увидеть.
3 ответов
строку
for tag in soup.findAll(attribute=True):
не нашел ни tag
s. Возможно, есть способ использовать findAll
, Я не уверен. Однако, это работает:
import BeautifulSoup
REMOVE_ATTRIBUTES = [
'lang','language','onmouseover','onmouseout','script','style','font',
'dir','face','size','color','style','class','width','height','hspace',
'border','valign','align','background','bgcolor','text','link','vlink',
'alink','cellpadding','cellspacing']
doc = '''<html><head><title>Page title</title></head><body><p id="firstpara" align="center">This is <i>paragraph</i> <a onmouseout="">one</a>.<p id="secondpara" align="blah">This is <i>paragraph</i> <b>two</b>.</html>'''
soup = BeautifulSoup.BeautifulSoup(doc)
for tag in soup.recursiveChildGenerator():
try:
tag.attrs = [(key,value) for key,value in tag.attrs
if key not in REMOVE_ATTRIBUTES]
except AttributeError:
# 'NavigableString' object has no attribute 'attrs'
pass
print(soup.prettify())
Я использую BeautifulSoup 4 С python 2.7 и для меня tag.attrs
- это словарь, а не список. Поэтому мне пришлось изменить этот код:
for tag in soup.recursiveChildGenerator():
if hasattr(tag, 'attrs'):
tag.attrs = {key:value for key,value in tag.attrs.iteritems()
if key not in REMOVE_ATTRIBUTES}
просто ftr: проблема здесь в том, что если вы передаете атрибуты HTML в качестве аргументов ключевого слова, ключевое слово -имя атрибута. Таким образом, ваш код ищет теги с атрибутом name attribute
, поскольку переменная не расширяется.
вот почему
- жесткое кодирование вашего имени атрибута работало[0]
- код не удастся. Поиск просто не соответствует никаким тегам
чтобы устранить проблему, передайте атрибут, который вы ищете как dict
:
for attribute in REMOVE_ATTRIBUTES:
for tag in soup.find_all(attrs={attribute: True}):
del tag[attribute]
Hth кто-то в будущем, dtk
[0]: хотя это должно быть find_all(style=True)
в вашем примере, без кавычек, потому что SyntaxError: keyword can't be an expression