python - 使用 Beautiful Soup 将 CSS 属性转换为单个 HTML 属性?

标签 python html css html-parsing beautifulsoup

我正在尝试编写一个程序,该程序将采用 HTML 文件并使它对电子邮件更友好。现在所有的转换都是手动完成的,因为没有一个在线转换器能完全满足我们的需要。

这听起来像是一个很好的机会,可以突破我的编程知识的极限,并实际编写一些有用的代码,所以我提出尝试在业余时间编写一个程序,以帮助提高流程的自动化程度。

我对 HTML 或 CSS 了解不多,所以我主要依靠我的兄弟(他知道 HTML 和 CSS)来描述这个程序需要做哪些改变,所以如果我问一个愚蠢的问题,请多多包涵问题。这对我来说是全新的领域。

大多数更改都非常基本——如果您看到标记/属性 X,则将其转换为标记/属性 Y。但是在处理包含样式属性的 HTML 标记时,我遇到了麻烦。例如:

<img src="http://example.com/file.jpg" style="width:150px;height:50px;float:right" />

只要有可能,我就想将样式属性转换为 HTML 属性(或将样式属性转换为对电子邮件更友好的属性)。所以在转换之后它应该是这样的:

<img src="http://example.com/file.jpg" width="150" height="50" align="right"/>

现在我意识到并非所有 CSS 样式属性都具有 HTML 等效项,所以现在我只想关注那些具有等效项的属性。我编写了一个 Python 脚本来执行此转换:

from bs4 import BeautifulSoup
import re

class Styler(object):

    img_attributes = {'float' : 'align'}

    def __init__(self, soup):
        self.soup = soup

    def format_factory(self):
        self.handle_image()

    def handle_image(self):
        tag = self.soup.find_all("img", style = re.compile('.'))
        print tag
        for i in xrange(len(tag)):
            old_attributes = tag[i]['style']
            tokens = [s for s in re.split(r'[:;]+|px', str(old_attributes)) if s]
            del tag[i]['style']
            print tokens

            for j in xrange(0, len(tokens), 2):
                if tokens[j] in Styler.img_attributes:
                    tokens[j] = Styler.img_attributes[tokens[j]]

                tag[i][tokens[j]] = tokens[j+1]

if __name__ == '__main__':
    html = """
    <body>hello</body>
    <img src="http://example.com/file.jpg" style="width:150px;height:50px;float:right" />
    <blockquote>my blockquote text</blockquote>
    <div style="padding-left:25px; padding-right:25px;">text here</div>
    <body>goodbye</body>
    """
    soup = BeautifulSoup(html)
    s = Styler(soup)
    s.format_factory()

现在这个脚本可以很好地处理我的特定示例,但它不是很健壮,而且我意识到当与现实世界的示例进行比较时,它很容易崩溃。我的问题是,我怎样才能使它更健壮?据我所知,Beautiful Soup 没有办法更改或提取样式属性的各个部分。我想这就是我想要做的。

最佳答案

对于这类事情,我建议将 HTML 解析器(如 BeautifulSoup 或 lxml)与专门的 CSS 解析器结合使用。我在 the cssutils package 上取得了成功.与试图想出正则表达式来匹配您可能在野外找到的任何可能的 CSS 相比,您会轻松得多。

例如:

>>> import cssutils
>>> css = 'width:150px;height:50px;float:right;'
>>> s = cssutils.parseStyle(css)
>>> s.width
u'150px'
>>> s.height
u'50px'
>>> s.keys()
[u'width', u'height', u'float']
>>> s.cssText
u'width: 150px;\nheight: 50px;\nfloat: right'
>>> del s['width']
>>> s.cssText
u'height: 50px;\nfloat: right'

因此,使用它您可以非常轻松地提取和操作您想要的 CSS 属性,并使用 BeautifulSoup 将它们直接插入 HTML。不过,请注意 cssText 属性中弹出的换行符。我认为 cssutils 更适合将事物格式化为独立的 CSS 文件,但它足够灵活,主要适用于您在这里所做的事情。

关于python - 使用 Beautiful Soup 将 CSS 属性转换为单个 HTML 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10401110/

相关文章:

html - iOS 设备中的 css 问题

html - 如何禁用 XSL 样式表上的按钮?

javascript - 如何在 Swiper slider 的边缘设置幻灯片样式

css - 自定义滚动条不会出现在 Internet Explorer 上

python - 为什么 9007199254740993 != 9007199254740993.0?

python - 了解分发卡住的 Python Tkinter 应用程序需要 TCL 中的哪些文件

Python Plotnine - 创建堆积条形图

html - 在 Font Awesome 图标之后设置明文样式

javascript - 针对 :first-letter of :after content pseudoelement

python - 嵌入 libPython 时重定向 stdout 和 stderr