本文抽出の手法について探していたところ、CybouzLabsさんのサイトにWebページの本文抽出に関する記事とソースがアップされていましたので参考にさせていただきました。
オリジナルソースはRubyで書かれたものです。
筆者はRubyは全く知らないので、ソースを理解しつつPythonに移植していきます。
オリジナルソースは約220行ですが、メソッドごとに解釈と移植をしていきます。
デアゴスティーニ(DeAGOSTINI)のように何週間かかけて完成させます。(^^;
まずは一番簡単そうなタイトル抽出からです。
# Extracts title. def self.extract_title(st) if st =~ /<title[^>]*>\s*(.*?)\s*<\/title\s*>/i strip_tags($1) else "" end end
Rubyの正規表現は以下のマニュアルを参照してください。
http://docs.ruby-lang.org/ja/2.1.0/doc/spec=2fregexp.html
3行目 “=~”
まずは謎(?)の演算子のようなもの“=~”から調べます。
Rubyのマニュアルを見ると以下のように書かれています。
なるほど、正規表現と文字列をマッチさせるようです。ここは理解できました。
/xxx/ =~ yyy | 正規表現のメソッド =~ 。正規表現と文字列をマッチさせる。両辺を入れ替えても機能します。 |
/xxx/ !~ yyy | 正規表現のメソッド =~ の否定。マッチが失敗したらtrueを返します。 |
3行目 “/・・・・/i ”
まずは大まかな構造“/・・・・/i ”を理解します。
さっそくRubyのマニュアルを見てみましょう。
/pat/という正規表現の直後に以下のアルファベットを 置くことで、正規表現にオプションを指定することができます。 /pat/i 大文字小文字を無視する /pat/m メタ文字「.」が改行にマッチするようになる /pat/x コメント内の空白を無視する。コメントの仕様が変化する /pat/o パターン内の #{} の展開を1回限りしかしない。
“i”は大文字小文字を無視するということのようです。
htmlタグは大文字で書かれている場合と小文字で書かれている場合がありますから当然ですね。
3行目 “[^>]*”
角括弧 [ と ] で囲まれ、1個以上の文字を列挙した部分は、文字クラス(character class) とよばれます。
いずれかの1文字にマッチします。
文字クラスの [ の直後の文字がキャレット(^)の場合は、[と]で囲まれた部分に、列挙「されていない」 文字にマッチします。
つまり、このプログラムの場合は“>”以外にマッチします。
その後続のアスタリスク(*)は、0回以上の繰り返しにマッチします。
3行目 “\s*(.*?)\s*”
ここはtitleタグで挟まれたテキストを解析する部分になります。
\s | 空白文字。 [ \t\r\n\f]とイコールです。 |
. | 任意の1文字(改行を除く) |
*? | 0回以上 |
丸括弧 ( ) によって当該箇所をキャプチャ(記憶)することができます。
括弧に囲まれた部分正規表現にマッチした 文字列を後で参照することができます。
このプログラムでは4行目の“$1”が参照している箇所です。
4行目
この行で、さきほどキャプチャ(記憶)した文字列をstrip_tags()メソッドに渡します。
$1はキャプチャ(記憶)の1番目を参照する特殊変数です。
何とかタイトル抽出については理解できました。
続きはまた後日です。