読者です 読者をやめる 読者になる 読者になる

pythontでHTMLを解析したり、文字列置換などしてみる。

python

こんな感じのHTMLを読んで、tdタグ内のデータを出力するときに、もし文字列が{}で囲まれてたら置換して表示するようなことをやってます。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Testcase001</title>
</head>

<body>

<table border=1>
  <tr bgcolor="#00FFFF">
    <td>Testcase</td>
    <td>Test step</td>
  </tr>
  <tr>
    <td>User should input login id and password</td>
    <td>Input {LOGIN_ID} and {PASSWORD}<br>
      Enter the {BUTTON}</td>
  </tr>
</table>
</body>
</html>

Pythonのコードはこれです。

#!/usr/bin/env python                                                                                                                     
from __future__ import with_statement
from htmllib import HTMLParser
from formatter import NullFormatter
import re

class ScriptWriterHtmlParser(HTMLParser):

    def __init__(self):
        HTMLParser.__init__(self, NullFormatter())
        self.dic = {}

        self.dic["{LOGIN_ID}"] = "foo"
        self.dic["{PASSWORD}"] = "bar"
        self.dic["{BUTTON}"] = "OK"

    def start_td(self, attributes):
        self.save_bgn()

    def end_td(self):
        tmp = self.save_end()

        for k in self.dic.iterkeys():
            p = re.compile(k)
            tmp = p.sub(self.dic[k], tmp)
        print tmp

if __name__ == "__main__":
    testcase = ""
    with open("./testcase001.html") as f:
        testcase = f.read()

    parser = ScriptWriterHtmlParser()
    parser.feed(testcase)
    parser.close()

HTMLの解析には、以下の2つのモジュールをインポートします。

from htmllib import HTMLParser
from formatter import NullFormatter

tdタグが見つけて処理をするので、見つかった時の処理が必要ですが、それを実行しているのはstart_td()とend_td()です。
この2個の関数はHTMLParserには含まれていませんが、ちゃんと呼び出されます。
その仕組みですが、SGMLParserというHTMLParserのさらに上位クラスにあるstart_tag(attributes)、とend_tag()関数が絡んでます。多分・・・
今回はtdを処理したかったのでstart_td()とend_td()を定義しました。
データの取得はsave_bgn()->save_end()という流れです。save_end()の戻り値にtdタグではさまれたデータが返ってきます。
文字列の置換してる部分はここで、実際に文字列の置換をしているのはsub()です。
1番目の引数は置換対象、2番目は検索対象の文字列を渡して、結果を受け取ってます。

            p = re.compile(k)
            tmp = p.sub(self.dic[k], tmp)

そうすると、このような感じになります。

[masami@moonlight:~/experiment]% ./script_writer.py
Testcase
Test step
User should input login id and password
Input foo and bar Enter the OK