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

Kur*_*sis 7 python beautifulsoup frontpage scraper web-scraping

我正在尝试'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])
Run Code Online (Sandbox Code Playgroud)

它运行没有错误,但实际上并没有删除任何属性.当我在没有外部循环的情况下运行它时,只需对单个属性进行硬编码(soup.findAll('style'= True),它就可以了.

有人知道这里有问题吗?

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

unu*_*tbu 8

这条线

for tag in soup.findAll(attribute=True):
Run Code Online (Sandbox Code Playgroud)

找不到任何tags.可能有一种使用方法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())
Run Code Online (Sandbox Code Playgroud)


小智 6

我正在将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}
Run Code Online (Sandbox Code Playgroud)


dtk*_*dtk 6

只是 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]
Run Code Online (Sandbox Code Playgroud)

未来的某个人,dtk

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