8

有没有办法从 HTML 文件中获取 CSS 类BeautifulSoup?示例片段:

<style type="text/css">

 p.c3 {text-align: justify}

 p.c2 {text-align: left}

 p.c1 {text-align: center}

</style>

完美的输出将是:

cssdict = {
    'p.c3': {'text-align': 'justify'},
    'p.c2': {'text-align': 'left'},
    'p.c1': {'text-align': 'center'}
}

虽然这样的事情会做:

L = [
    ('p.c3', {'text-align': 'justify'}),  
    ('p.c2', {'text-align': 'left'}),    
    ('p.c1', {'text-align': 'center'})
]
4

3 回答 3

11

BeautifulSoup 本身根本不解析 CSS 样式声明,但您可以提取这些部分,然后使用专用的 CSS 解析器解析它们。

根据您的需要,有几个可用于 python 的 CSS 解析器;我会选择cssutils(需要 python 2.5 或更高版本(包括 python 3)),它是支持最完整的,也支持内联样式。

其他选项是css-pytinycss

要获取和解析所有样式部分(以 cssutils 为例):

import cssutils
sheets = []
for styletag in tree.findAll('style', type='text/css')
    if not styletag.string: # probably an external sheet
        continue
    sheets.append(cssutils.parseStyle(styletag.string))

然后cssutil你可以组合这些,解析导入,甚至让它获取外部样式表。

于 2012-07-16T10:16:48.237 回答
5

BeautifulSoup 和 cssutils 组合可以很好地解决问题:

    from bs4 import BeautifulSoup as BSoup
    import cssutils
    selectors = {}
    with open(htmlfile) as webpage:
        html = webpage.read()
        soup = BSoup(html, 'html.parser')
    for styles in soup.select('style'):
        css = cssutils.parseString(styles.encode_contents())
        for rule in css:
            if rule.type == rule.STYLE_RULE:
                style = rule.selectorText
                selectors[style] = {}
                for item in rule.style:
                    propertyname = item.name
                    value = item.value
                    selectors[style][propertyname] = value

BeautifulSoup 解析 html 中的所有“样式”标签(头部和正文),.encode_contents() 将 BeautifulSoup 对象转换为 cssutils 可以读取的字节格式,然后 cssutils 将各个 CSS 样式一直解析到属性/值通过 rule.selectorText 和 rule.style 级别。

注意: “rule.STYLE_RULE”只过滤掉样式。cssutils 文档详细介绍了过滤媒体规则、评论和导入的选项。

如果你把它分解成函数会更干净,但你明白了要点......

于 2016-08-27T22:28:56.127 回答
0

tinycss 解析器用于在 python 中显式解析 CSS。BeautifulSoup 支持 HTML 标签,除非使用正则表达式,否则无法搜索特定的 css 类。这甚至支持一定数量的 CSS3。

http://packages.python.org/tinycss/

PS:但是,它只能从 python 2.6 开始工作。

于 2012-07-16T09:43:34.813 回答