在Python中解析CSS

时间:2014-08-13 23:00:19

标签: python regex

我正在合并100个HTML页面,所有HTML页面都包含嵌入式样式元素。使用BeautifulSoup来提取样式的内容,但现在留下了将字符串解析为dict {selector_str:properties_str}的任务。看着tinycss,它让我成为选择者' .c0'很容易,但不是属性字符串' {...}'。

这是一个示例字符串

'.c0 { padding: 1px 0px 0px; font-size: 11px } .c1 { margin: 0px; font-size: 11px } .c2 { font-size: 11px } .c3 { font-size: 11px; font-style: italic; font-weight: bold } '

连连呢?一个正则表达式黑客欢迎。这是CSS的范围。每页和每页上的类选择器.c0到.c100(s)遵循相同的模式。

2 个答案:

答案 0 :(得分:1)

这样的东西?

from collections import defaultdict

properties = defaultdict(str)

for item in example_str.split("}"):
    item_split = item.split("{")
    properties[item_split[0]] = "{" + item_split[1] + "}"

答案 1 :(得分:0)

这是我降落的地方。使用BadKarma的分裂破解字符串的策略。

from bs4 import BeautifulSoup
import re

class RichText(BeautifulSoup):
    """
    subclass BeautifulSoup
    add behavior for generating selectors and declaration_blocks from <style>
    """

    def __init__(self, html_page):
        super().__init__(html_page)

    @property
    def rules_as_str(self):
        return str(self.style.string)

    def rules(self):
        split_rules = re.split('(\.c[0-9]*)', self.rules_as_str)
        # side effect of split, first element is null
        assert(split_rules[0] == '')
        # enforce that it MUST be null, then pass over it
        for i in range(1, len(split_rules), 2):
            yield (split_rules[i].strip(), split_rules[i+1].strip())


if __name__ == '__main__':

    with open('rich-text.html', 'r') as f:
        html_file = f.read()

    rich_text = RichText(html_file)
    for selector, declaration_block in rich_text.rules():
        print(selector)
        print(declaration_block)

>>> with open("test.py") as f:
...     code = compile(f.read(), "test.py", 'exec')
...     exec(code)
... 
.c0
{ padding: 1px 0px 0px; font-size: 11px }
.c1
{ margin: 0px; font-size: 11px }
.c2
{ font-size: 11px }
.c3
{ font-size: 11px; font-style: italic; font-weight: bold }
>>>