Perlの最近のブログ記事

コマンド1発で、ヤフーのトップページを取得する!

Perlを使うと、たった1行のコード(というかコマンド)でウェブページのHTMLを取得できます。

しかも、LinuxでもWIndowsでも全く同じコマンドで動作します。

Linux系の場合
$ perl -MLWP::Simple -e  " print get 'http://yahoo.co.jp' "


Windowsの場合(コマンドプロンプトで下記を入力)
> perl -MLWP::Simple -e  " print get 'http://yahoo.co.jp' "


実行結果
Wide character in print at -e line 1.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<meta name="description" content="日本最大級のポータルサイト。
検索、オークション、ニュース、メール、コミュニティ、ショッピング、など80以上のサービスを展開。
あなたの生活をより豊かにする「ライフ・エンジン」を目指していきます。">
<title>Yahoo! JAPAN</title>
<base href="http://www.yahoo.co.jp/_ylh=X3oDMTB2OHNyYWxqBF9TAzIwNzkxODE5OTkEdGlkA
zEzBHRtcGwDdGFibGU-/">
<style type="text/css">
(以下省略)

取得したHTMLをファイルとして保存したい場合は、下記のようにします。
こうすると、結果を画面に表示する代わりにファイルに保存できます。


perl -MLWP::Simple -e  " print get 'http://yahoo.co.jp'" > yahoo.html
ちなみに">"記号のことを「リダイレクト」といいます。

Perlって素晴らしい!!



【補足1】
LWP::Simpleモジュールが必要です。
上記のget関数は、Perlの標準関数ではなくてLWP::Simpleというモジュールが提供する関数です。
インストール方法は割愛しますが、よく使われるモジュールなのでレンタルサーバなどでは初めから入ってることが多いです。
(Xreaにはインストール済みでした。)

【補足2】
出力結果の1行目に警告が出ちゃってますが、多めに見てあげてください。。。
前回の記事で、XML::LibXMLのインストールが失敗してることまではわかりました。

cpan[1]> install XML::LibXML
CPAN: Storable loaded ok (v2.18)
Going to read '/root/.cpan/Metadata'
  Database was generated on Sat, 05 Jun 2010 04:27:23 GMT
CPAN: YAML loaded ok (v0.70)
Going to read 86 yaml files from /root/.cpan/build/
CPAN: Time::HiRes loaded ok (v1.9711)
DONE
Restored the state of none (in 2.0500 secs)
Running install for module 'XML::LibXML'
Running make for P/PA/PAJAS/XML-LibXML-1.70.tar.gz
  Has already been unwrapped into directory /root/.cpan/build/XML-LibXML-1.70-IIX0Tb
  No 'Makefile' created
, won't make
Running make test
  Make had some problems, won't test
Running make install
  Make had some problems, won't install

とりあえず解決できたので、以下にその方法を載せておきます。
原因や仕組みはよくわかりません。すいません。。


# su -        # rootになる
# cd /root/.cpan/build/XML-LibXML-1.70-IIX0Tb
# perl Makefile.PL      # Makefile.PLを実行 → エラーが出る
# apt-get install libxml2-dev       # ライブラリをインストール
# perl Makefile.PL       #  Makefile.PLを実行 → またエラーが出る
# apt-get install libxml-libxml-perl      # ライブラリをインストール
# perl Makefile.PL       # 成功!!
# make
# make test
# make install
# update-perl-sax-parsers       # 一応。
# cpan

cpan>  install XML::libXML       # 成功!
cpan>  install Web::Scraper      # 成功!

成功!!

動作確認は次回の記事で。
Ubuntu9.04にWeb::Scraperをインストールしたかったのですが、うまくいきません。

私はPerlが大好きなのですが、CPANモジュールのインストールができないときは何をどうしてよいのかわからず途方にくれてしまいます。

う~ん。。。モダンPerlへの道は険しい。。。

cpan > install Web::Scraper

Test Summary Report
-------------------
t/xml-simple.t        (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
Files=22, Tests=40,  9 wallclock secs ( 0.72 usr  0.18 sys +  6.39 cusr  1.73 csys =  9.02 CPU)
Result: FAIL
Failed 1/22 test programs. 0/40 subtests failed.
make: *** [test_dynamic] Error 2
  MIYAGAWA/Web-Scraper-0.32.tar.gz
  /usr/bin/make test -- NOT OK
//hint// to see the cpan-testers results for installing this module, try:

  reports MIYAGAWA/Web-Scraper-0.32.tar.gz
Running make install
  make test had returned bad status, won't install without force
Failed during this command:
 MIYAGAWA/HTML-TreeBuilder-LibXML-0.11.tar.gz : make_test NO
 MIYAGAWA/Web-Scraper-0.32.tar.gz             : make_test NO

HTML::TreeBuilder::LibXMLのインストールが失敗したのかな?

cpan > install HTML::TreeBuilder::LibXML

中略

t/HTML-TreeBuilder-XPath.t .. 1/19 Can't locate XML/LibXML.pm
 in @INC (@INC contains:
 /root/.cpan/build/HTML-TreeBuilder-LibXML-0.11-sa80fu/inc
 /root/.cpan/build/HTML-TreeBuilder-LibXML-0.11-sa80fu/blib/lib
 /root/.cpan/build/HTML-TreeBuilder-LibXML-0.11-sa80fu/blib/arch
 /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0
 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 
 /usr/local/lib/site_perl .) 
at /root/.cpan/build/HTML-TreeBuilder-LibXML-0.11-sa80fu/blib/lib/HTML/TreeBuilder/LibXML.pm line 7.

中略

Result: FAIL
Failed 7/7 test programs. 1/2 subtests failed.
make: *** [test_dynamic] Error 2
  MIYAGAWA/HTML-TreeBuilder-LibXML-0.11.tar.gz
  /usr/bin/make test -- NOT OK

XML::LibXMLのインストールが失敗してるのかな?

cpan[1]> install XML::LibXML
CPAN: Storable loaded ok (v2.18)
Going to read '/root/.cpan/Metadata'
  Database was generated on Sat, 05 Jun 2010 04:27:23 GMT
CPAN: YAML loaded ok (v0.70)
Going to read 86 yaml files from /root/.cpan/build/
CPAN: Time::HiRes loaded ok (v1.9711)
DONE
Restored the state of none (in 2.0500 secs)
Running install for module 'XML::LibXML'
Running make for P/PA/PAJAS/XML-LibXML-1.70.tar.gz
  Has already been unwrapped into directory /root/.cpan/build/XML-LibXML-1.70-IIX0Tb
  No 'Makefile' created
, won't make
Running make test
  Make had some problems, won't test
Running make install
  Make had some problems, won't install
うむむ。。。
まぁ失敗は成功の母ということで、何もしないよりは一歩前進した。

ググって調べてみます。

Net::Twitter::Liteを使うとこんなにカンタン!!

ほんとに5行のコードでつぶやけてしまいました。
#!/usr/bin/perl
use Net::Twitter::Lite;
use utf8;
my $nt = Net::Twitter::Lite->new(username => 'DQNEO', password => 'hoge');
my $result = eval { $nt->update('ついったー!!') };
warn "$@\n" if $@;
Net::Twitter::Lite バンザイ!!

13行のコードで、Yahoo!Japanのトピックス一覧を取得する!

PerlでHTML取得・解析したいときはLWP::UserAgentとHTML::TreeBuilderというのを使うと簡単にできます。
LWP::UserAgentを使うと、Webページの取得ができます。
HTML::TreeBuilderを使うと、HTMLのDOM解析ができます。

この2つのモジュールを使って、Yahoo!Japanのトピックス一覧を取得してみましょう。
コメント行と空行を除くとたったの13行です。

use strict;
use warnings;
use LWP::UserAgent;
use HTML::TreeBuilder;

# urlを指定する
my $url = 'http://www.yahoo.co.jp';

# IE8のフリをする
my $user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)";

# LWPを使ってサイトにアクセスし、HTMLの内容を取得する
my $ua = LWP::UserAgent->new('agent' => $user_agent);
my $res = $ua->get($url);
my $content = $res->content;

# HTML::TreeBuilderで解析する
my $tree = HTML::TreeBuilder->new;
$tree->parse($content);

# DOM操作してトピックの部分だけ抜き出す。
# <div id='topicsfb'><ul><li>....の部分を抽出する

my @items =  $tree->look_down('id', 'topicsfb')->find('li');
print $_->as_text."\n" for @items;                          

実行結果↓↓

$ perl get_parse.pl

岡田氏ら11閣僚の再任内定
都知事「菅新内閣は極左」
主力級の種牛5頭 感染シロ
鳥獣駆除の2人 撃たれて死亡写真
イスラエル 新たに支援船だ捕写真NEW
はやぶさ地球へ 異例の人気写真
エトオ「日本が最も危険」
看護師アイドル「採血が快感」写真
今日の話題(40件)
一覧
をを!超かんたん!!

解説

主にHTML::TreeBuilderを解説します。

parse
my $tree = HTML::TreeBuilder->new;
$tree->parse($content);
$contentには、HTMLを文字列として格納したものが入ります。
必ずしもLWPを使う必要はなく、ローカルファイルを読み込んだものでもOKです。
ここまではお約束なので覚えてしまいましょう。


find, look_down, as_text
my @items =  $tree->look_down('id', 'topicsfb')->find('li');
print $_->as_text."\n" for @items;
↑をわかりやすく書くとこう↓です。
my $elm  = $tree->look_down('id', 'topicsfb');
my  @list =  $elm->find('li');
for my $li (@list) {
    print $li->as_text."\n"
} 

$tree->look_down('id', 'topicsfb') 
「HTML文書中で、id属性がtopicsfbである要素を取得せよ」です。
JavaScriptのdocument.getElementByID('topicsfb') とほぼ同じものです。

$elm>find('li');
「その要素の中のli要素のリストを取得せよ」です。
JavaSciptのelement.getElementsByTagName('li')とほぼ同じものです。

$li->as_text 
「その要素に含まれるテキスト文字列を取得せよ」です。
JavaSciptのelement.innerTextとほぼ同じものです。


このlook_down, find, as_textという3つのメソッドだけ覚えればたいていのことはできます。
(実はHTML::Elementというオブジェクトのメソッドです)
公式ドキュメントを見ると他にもごちゃごちゃといっぱいメソッドがありますが、最初は覚える必要ありません(キッパリ)

メッソドチェーン (jQuery的なアレ)
look_down,find, as_textは任意のHTML要素に対して実行できます。
また、戻り値はHTML要素を返します。
つまり、jQueryのようにメソッドチェーンをつなげてDOM要素を探索していくことができるのです。

print $tree->look_down('id', 'spotlight_mainfb')->find('ul')->find('li')->as_text;

# 結果
「女編集者、松方弘子28歳独身」
・・・働きマン?

レンタルサーバでも動く

Web::Scraperというモダンなモジュールもあるようですが、HTML::TreeBuilderの方がインストールが簡単です。
(私が使っているXreaレンタルサーバではデフォルトで入っていました。)

参考になった記事

補足1

Webページを取得するだけなら1行でできます!
簡単!たった1行のコードでWebページを取得するPerlスクリプト - DQNEO起業日記

補足2

いろんな方が補足記事を書いてくださったので、ご紹介いたします。
ツッコミありがとうございます!

HTML::TreeBuilder のメソッドを覚えるには人生はみじかすぎる件について

Tatsuhiko Miyagawa の HTML::Selector::XPath をつかえば、 use HTML::Selector::XPath 'selector_to_xpath'; print selector_to_xpath('#topicsfb li'), "\n"; # => //*[@id='topicsfb']//li のように、簡単に CSS Selector から XPath を生成することができる。

知りませんでした!ありがとうございます。

[PHP]簡単!たった6行のコードで HTML取得&解析をするPHPスクリプト
PHPだと6行ですか!すごい!

[perl] たった*行のコードでHTML取得&解析をしたい場合はWeb::Scraperが便利
コードが短い!
ありがとうございます。
ただ、Web::Scraperは私のようなPerl初心者にはインストールが難しかったです。。

補足3

いろいろ試行錯誤してWeb::Scraperをインストールできたので記事を書いてみました。
誰かのお役に立てば幸いです。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちPerlカテゴリに属しているものが含まれています。

前のカテゴリはMySQLです。

次のカテゴリはPerl再入門です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

OpenID対応しています OpenIDについて
Powered by Movable Type 5.02