Plaggerを使って、mixiニュース一覧から本文を抜き出しフィードを生成するplagger::CustomFeed::Scriptです。google-code-prettifyを使ってコード表示(見やすく)するようにする方法(jQueryで)を紹介しています。
perlの勉強で、実益も兼ねてPlaggerを使って勉強中です。まず、 CustomFeed::Scriptを作りました。mixiニュース一覧からリンクを辿って、本文をを抜き出しRSSフィードを生成するスクリプトです。
web::scrper www::mechanizeを使っています。
- mixiニュース一覧http://news.mixi.jp/list_news.pl
- アクセスランキング http://news.mixi.jp/show_ranking.pl?type=access
- 日記ランキング http://news.mixi.jp/show_ranking.pl?type=diary
- フォトランキング http://news.mixi.jp/show_ranking.pl?type=photo
上記4つのリスト一覧ページがあります。お好きなページのアドレスをスクリプトに追加することでRSS生成できます。
本文はHTMLを抜き出すようにしていますのでRSS生成後、Gmail送信でもOK。(mixiニュース一覧については80件程の記事となり、送信文字数オーバーなのか、すべての記事を送ることができません。)
mixinews_follow_check.pl
#!/usr/bin/perl
use strict;
use warnings;
use URI;
use YAML;
use utf8;
use File::Basename;
use WWW::Mechanize;
use Web::Scraper;
my $uri = URI->new( 'http://mixi.jp/' );
#my $url = 'http://news.mixi.jp/list_news.pl';
my $username = 'example@example.com';
my $password = "password";
my $mech = new WWW::Mechanize;
$mech->get($uri);
$mech->submit_form(
fields => {
email => $username,
password => $password,
}
);
my $filename = basename(__FILE__);
my $url = $ARGV[0]
or die "Usage: $filename url\n";
$mech->get($url);
my @links = $mech->find_all_links( url_regex => qr/view_news\.pl\?id\=\d{6}\&media_id\=\d{2}$/ );
my $s = scraper {
process '//div[@id="bodyMainArea"]',
'entries[]' => scraper {
process '//div[@class="newsArticle"]//h2',title => 'TEXT';
process '//p[@class="date"]', date => 'TEXT';
process '//div[@class="article"]', body => 'HTML';
process '//div[@id="viewNewsCategoryNews"]//h2', category => [ 'TEXT', sub { @_= /(.*?)\s.*?/gm;$1} ];
};
result qw( entries );
};
my $src = $s->scrape($mech->content, $mech->uri);
my $feed = {
title => 'mixi NEWS',
link => $url,
type => 'mixinews',
};
foreach my $links (@links){
$mech->get($links);
my $contents = $s->scrape($mech->content, $mech->uri);
foreach my $entry ( @{$contents} ) {
push @{$feed->{entries}}, {
title => $entry->{category}. "/" .$entry->{title},
link => $mech->uri,
summary => $entry->{date},
body => $entry->{body},
};
}
}
binmode STDOUT, ":utf8";
print Dump($feed);
※foreachのなかにforeachというのはありなんでしょうか?(変なのかも)
正規表現の部分も自信ありません。怪しい。($mech->find_all_linkの部分とscraperでのcategoryの文字抜き出し部分)
yaml(例:mixi ニュースアクセスランキング一覧)
global:
plugin_path:
- /usr/local/share/perl/5.10.0/Plagger/Plugin
assets_path:
- /usr/local/share/perl/5.10.0/Plagger/assets
timezone: Asia/Tokyo
log:
level: error
plugins:
- module: Subscription::Config
config:
feed:
- script:///path/to/mixinews_follow_check.pl http://news.mixi.jp/show_ranking.pl?type=access
- module: CustomFeed::Script
- module: Publish::Feed
config:
dir: /home/user/
filename: mixiNEWS.rss
format: RSS
感想
perl便利だと思いました。また、さまざまなスクリプトを記事にして情報発信している方が多く、perlユーザの方たちのコミュニティはすばらしいとも感じました。
web scraperでXpathでのエレメント探査は2階層まで3階層は無理みたいに感じましたがどうなんだろう?
web scraperを使ってplaggerでフィード生成しようと考えた場合、Config::PitとWeb::ScraperとPlaggerで24時間365日のゲーム監視体制で言われているように、
Plaggerにあわせて「ひとつのFeedに複数のEntry」という構造で項目名を決めることです
他に抜き出した要素構成を複雑にしないようにするといいこともわかりました。feed生成した後にentriesに要素を追加する過程でハッシュが複雑になりすぎて、コストがかかりすぎるといったかんじでしょうか。
プラグインのフローは基本的にFeedを生成し、そのFeedのなかのentry(基本: title author summary body)の中に要素を配置していくといったことになるのかな。
これをベースにして、mixiで特定のコミュニティだけの最新コンテンツを拾ってこれるものも作ろうと考えています。他にも特定キーワードの検索結果なども拾い出せれるようにできればいいかなーと。
こういったスクリプトがあれば、企画段階でターゲットの背景などさまざまな要素をリサーチしたりするのにとても使えると思いました。プログラムを走らせて取ってこれるものは取ってこさせる。そうした方が早いしいいですね。フローもスリムにできていい感じになるかと思います。
mixiなんかのコンテンツは無理だけど、さまざまなコンテンツの中から特定キーワードに関する記事を拾い出してきて、tumblr・はてなグループダイアリー(プライベートモード)なんかに投げて、リスト表示(並べて配置)させれば、京大式カードやKJ法なんかに似せた知的生産のためのスクラップコンテンツを作れたりするかも。ちょっと他にもよさげなものがないか考えてみます。
参考記事
- Config::PitとWeb::ScraperとPlaggerで24時間365日のゲーム監視体制
- 今度はConfig::Pitを実装してみます。
- Big Sky :: はてなニュースのRSSを出力するCustomFeedScript
- 助かりました。
- さくら水産の日替わり定食献立表を取得する - noboruhiの日記 - Plaggerグループ
- use WWW::Mechanize; - 今日のCPANモジュール
- use Web::Scraper; - 今日のCPANモジュール
- 配列のリファレンス, 配列への変換, 要素の参照 - Perl入門~サンプルコードによるPerl入門~
プロセス
このコードを作成するまでのプロセスです。mixiニュース一覧だけならはてなダイアリーのスクリプトを使ってもらえればOK。
- web::scraperでmixi news一覧を抜き出す - cool_ni_ikouの日記
- Web::Scraper,PlaggerでMixiニュースをGmailへ送信 CustomFeed::Script for MixiNews - cool_ni_ikouの日記
perlコード表示
syntaxhighlighterでperlコードは対応していないということで、今後のコード表示をgoogle-code-prettifyに変更。
jQueryを使って、ロードさせています。以下のコードをhead内に追加すればいいかと。
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1.3.0");</script>
<script type="text/javascript" src="<$MTBlogURL$>js/prettify.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('pre').addClass("prettyprint");
prettyPrint();
});
</script>
<link rel="stylesheet" type="text/css" href="<$MTBlogURL$>css/prettify.css" />
本文中に以下のパターンでコードを書き込めばきれいに表示されます。
<pre> code </pre>




process '//div[@id="bodyMainArea"]', 'entries[]' => scraper { process '//div[@class="newsArticle"]//h2',title => 'TEXT'; process '//p[@class="date"]', date => 'TEXT'; process '//div[@class="article"]', body => 'HTML'; process '//div[@id="viewNewsCategoryNews"]//h2', category => [ 'TEXT', sub { @_= /(.*?)\s.*?/gm;$1} ]; };はprocess 'div#bodyMainArea', 'entries[]' => scraper { process 'div.newsArticle h2',title => 'TEXT'; process 'p.date', date => 'TEXT'; process 'div.article', body => 'HTML'; process 'div#viewNewsCategoryNews h2', category => [ 'TEXT', sub { @_= /(.*?)\s.*?/gm;$1} ]; };とCSSセレクタでかくと読みやすくなるかも。>otsune
どうもありがとうございます。
そうやってもOKなんですね。助かりました。