― Web Technology and Life ―

Web::Scraperでhtmlのcontent-typeを一発で抜き出す方法

2011-04-04
近年、Webデータを使ったデータマイニングが活況を呈していますので、WebのスクレーピングをしてDBにためておきたいというニーズが少なからずあると思います。 Perl環境であれば、スクレーピングしたHTMLをDBに貯める前にutf8に変換しておきたいので、HTMLから文字コードを取り出したいと思います。そんなときに試行錯誤して調べた、PerlのWeb::Scraperを使った文字コードを抜き出す方法紹介します。なお、この記事はhachioji.pmにおける発表に基づいています。

不完全な方法

Web::Scraperを使って、簡単に一発で抜き出すには、パっと思いつくのは以下のような方法です。

use strict;
use warnings;
use Web::Scraper;
use Test::More;

my $html = '<meta HTTP-EQUIV="content-type" content="text/html; charset=euc-jp" />';

my $scrape_dt = scraper{
    process 'meta[http-equiv="content-type"]','content_type' => '@content',
};

my $content_type = $scrape_dt->scrape($html)->{content_type};

is $content_type,'text/html; charset=euc-jp';

done_testing;

このケースでは成功します。しかし、たくさんのhtmlにスクレーピングするにつれ、想定外のケースに出くわします。以下のようなケースもあるということです。

<meta http-equiv="Content-Type" content="text/html; charset=euc-jp" />
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=euc-jp" />

いまいちな成功方法

Web::Scraperでは、『using HTML and CSS Selectors or XPath expressions』ということになっていますが、いづれも正規表現の使い方はわからないので、調べた挙句以下のように書けることが判明しました。
参考サイト⇒『XPath の文字列比較で、小文字と大文字を区別しない方法』

my $scrape_dt = scraper{
    process '//meta[translate(@http-equiv,"CENOPTY","cenopty") = "content-type"]',
    'content_type' => '@content'
};

一応こんな感じで、取れています。

use strict;
use warnings;
use Web::Scraper;
use Test::More;

scraping_test('<meta http-equiv="Content-Type" content="text/html; charset=euc-jp" />');
scraping_test('<meta http-equiv="CONTENT-TYPE" content="text/html; charset=euc-jp" />');

sub scraping_test {
    my $html = shift;

    my $scrape_dt = scraper{
        process '//meta[translate(@http-equiv,"CENOPTY","cenopty") = "content-type"]',
        'content_type' => '@content'
    };

    my $content_type = $scrape_dt->scrape($html)->{content_type};

    is $content_type,'text/html; charset=euc-jp';
}

done_testing;

トミールさんに教えてもらった方法

「以上方法はなんだか長ったらしいので、見栄えも悪いしいまいちです。きれいに、正規表現を使う方法はないのでしょうか?」とhachioji.pmで聞いたら、 『CPANモジュールガイド』の宣伝に来ていたトミールさんが教えてくれました。

process 'meta[http-equiv =~ "(?i:content-type)"]','content_type' => '@content',

コンパイル済みの正規表現?でしたっけ?この(?オプション:パターン)という書き方でできるんですね。この正規表現の書き方は、Dumpで見ることはあっても覚えることはないと思っていましたが。。。 さすがトミールさんです。とりあえず、『CPANモジュールガイド』はアマゾンで予約しました。

hachioji.pmについて

hachioji.pmについてはこちらをご覧ください。多摩地域を中心としたシステム開発者の集いで、今回第四回目となっていました。 飲みながらライトニングトークのさらにライトな感じの発表を参加者ほぼ全員がするというのが特徴のラフな集いです。今のところ年始以来毎月実施するというかなりの挑戦をしており、 次回は2011/4/23(土)を予定しています。ちょっと予定がかぶっているけど、なんとか遅刻してでも行こうかと思っています。

Perl hachioji.pm update_at : 2011-04-04T03:54:58
hirobanex.netの更新情報の取得
 RSSリーダーで購読する   
blog comments powered by Disqus