2

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 にはスタイル属性の個々の部分を変更または抽出する方法がありません。それが私がやろうとしていることだと思います。

4

2 に答える 2

11

このような場合は、HTML パーサー (BeautifulSoup や lxml など) と専用の CSS パーサーを併用することをお勧めします。cssutils パッケージで成功しました。野生で見つけられる可能性のある 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 ファイルとしてフォーマットするように設計されていると思いますが、ここで行っていることのほとんどで十分に機能する柔軟性があります。

于 2012-05-09T13:44:23.983 に答える
2

車輪を再発明する代わりに、stoneage パッケージhttp://pypi.python.org/pypi/StoneageHTMLを使用します。

于 2012-05-16T09:21:02.870 に答える