BeautifulSoup: удаляет указанные атрибуты, но сохраняет тег и его содержимое - PullRequest
6 голосов
/ 28 января 2012

Я пытаюсь «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])

Он работает без ошибок, но фактически не удаляет ни один из атрибутов.Когда я запускаю его без внешнего цикла, просто жестко кодирую отдельный атрибут (soup.findAll ('style' = True)), он работает.

Кто-нибудь знает, знает ли здесь проблему?- Мне также не очень нравятся вложенные циклы. Если кто-нибудь знает более функциональный стиль карты / фильтра, я бы с удовольствием посмотрел его.

Ответы [ 4 ]

7 голосов
/ 28 января 2012

Линия

for tag in soup.findAll(attribute=True):

не находит никаких tag с.Там может быть способ использовать 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())
4 голосов
/ 11 октября 2016

Я использую 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}
2 голосов
/ 13 июля 2018

Просто ftr: проблема здесь в том, что если вы передаете атрибуты HTML в качестве аргументов ключевого слова, ключевое слово будет name атрибута. Итак, ваш код ищет теги с атрибутом имени attribute, поскольку переменная не раскрывается.

Вот почему

  1. сработало жесткое кодирование имени вашего атрибута [0]
  2. код не дает сбоя. Поиск не соответствует ни одному тегу

Чтобы устранить проблему, передайте искомый атрибут как dict:

for attribute in REMOVE_ATTRIBUTES:
    for tag in soup.find_all(attrs={attribute: True}):
        del tag[attribute]

Hth кто-то в будущем, ДТК

[0]: хотя в вашем примере это должно быть find_all(style=True), без кавычек, потому что SyntaxError: keyword can't be an expression

0 голосов
/ 16 ноября 2018

Я использую это:

if "align" in div.attrs:
    del div.attrs["align"]

или

if "align" in div.attrs:
    div.attrs.pop("align")

Благодаря https://stackoverflow.com/a/22497855/1907997

...