首页 文章

BeautifulSoup:剥离指定的属性,但保留标记及其内容

提问于
浏览
6

我正在尝试'defrontpagify'MS FrontPage生成的网站的html,我正在写一个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),它就可以了 .

有人知道这里有问题吗?

PS - 我也不太喜欢嵌套循环 . 如果有人知道更具功能性的map / filter-ish风格,我很乐意看到它 .

4 回答

  • 0

    这条线

    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())
    
  • 6

    我正在使用带有python 2.7的BeautifulSoup 4,对我来说 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}
    
  • 0

    只是ftr:这里的问题是,如果将HTML属性作为关键字参数传递,则关键字是属性的名称 . 所以你的代码正在搜索名为 attribute 的属性的标签,因为变量没有扩展 .

    这就是为什么

    • 硬编码您的属性名称[0]

    • 代码没有失败 . 搜索只是与任何标签都不匹配

    要解决此问题,请将您要查找的属性作为 dict 传递:

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

    和某人在一起,dtk

    [0]:虽然在你的例子中需要 find_all(style=True) ,但没有引号,因为 SyntaxError: keyword can't be an expression

  • 4

    我用这个:

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

    要么

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

    感谢https://stackoverflow.com/a/22497855/1907997

相关问题