<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Love web applications &#187; Perl</title>
	<atom:link href="http://blog.hitsuji.me/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.hitsuji.me</link>
	<description>Webアプリつくるの楽しい！つくるネタ、使うネタ、あとは雑談です。</description>
	<lastBuildDate>Sun, 25 Jan 2015 12:49:45 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.41</generator>
	<item>
		<title>Perlで横浜市の区別年齢別人口データを自動入手する</title>
		<link>http://blog.hitsuji.me/get-stat-of-yokohama-city-population-automatically/</link>
		<comments>http://blog.hitsuji.me/get-stat-of-yokohama-city-population-automatically/#comments</comments>
		<pubDate>Wed, 09 Jul 2014 01:52:44 +0000</pubDate>
		<dc:creator><![CDATA[kapibarawebmaster1515]]></dc:creator>
				<category><![CDATA[データ収集]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[統計]]></category>

		<guid isPermaLink="false">http://blog.hitsuji.me/?p=114</guid>
		<description><![CDATA[こんにちは。今日もPerlを使った横浜市の人口データを収集を進めます♪ &#160; 前回の記事「Perlで横浜市統計webから人口データを入手する」で、個別のHTMLソースファイルから目的の人口デー・・・<a class="readon" href="http://blog.hitsuji.me/get-stat-of-yokohama-city-population-automatically/">続きを読む</a>]]></description>
				<content:encoded><![CDATA[<p>こんにちは。今日もPerlを使った横浜市の人口データを収集を進めます♪</p>
<p>&nbsp;</p>
<p>前回の記事「Perlで横浜市統計webから人口データを入手する」で、個別のHTMLソースファイルから目的の人口データを入手するスクリプトを作成しました。今回はこのスクリプトを拡張して、区別データを自動入手、ファイル書き出しまで行います。</p>
<p>&nbsp;</p>
<h3>横浜市の区別年齢別人口データを入手する</h3>
<p>横浜市の区別年齢別の人口データは、下記のサイトに掲載されています。</p>
<p><a title="横浜市統計ポータルサイト" href="http://www.city.yokohama.lg.jp/ex/stat/jinko/age/new/age-j.html" target="_blank">http://www.city.yokohama.lg.jp/ex/stat/jinko/age/new/age-j.html</a></p>
<p>&nbsp;</p>
<p>区名タブを押すと、区別の人口データが出て来ますよね。これらを手でコピペするのも大変なので、Perlで自動収集して、最後にJSONファイルで書き出すスクリプトを作成しました。</p>
<p>&nbsp;</p>
<h6>read_yokohama_stat.pl</h6>
<script src="https://gist.github.com/ad452791446e60ce538e.js"></script><noscript><pre><code class="language-perl perl">#! /opt/local/bin/perl
use strict;
use warnings;
use 5.012;
use Encode;
use HTML::TableExtract; 
use utf8;
use LWP::Simple;
use JSON qw( decode_json encode_json );

my $url_dir = &quot;http://www.city.yokohama.lg.jp/ex/stat/jinko/age/new/&quot;;
my @file_keys = qw(age tsurumi kanagawa nishi naka minami konan hodogaya asahi isogo kanazawa kohoku midori aoba tsuzuki totsuka sakae izumi seya);
my $browser = LWP::UserAgent-&gt;new(keep_alive=&gt;3, timeout=&gt;30);
my @stat;

foreach my $key (@file_keys) {
	# URLフレーズを作成する
	my $url = $url_dir . $key . &quot;-j.html&quot;;
	print $url, &quot;\n&quot;;
	
	# HTMLソースを入手する
	my $content = get_content_by_url($url);
	
	# HTMLソースから目的の人口データのみ入手する
	my $res = get_stat_from_html($content);
	
	# 結果を入れる配列にpush
	push(@stat, {'key' =&gt; $key, 'stat' =&gt; $res, });
	
	# Webサイトへのアクセスするタイミングを1sec開ける
	sleep(1);
	
}

my $json = encode_json(\@stat);
open(FILE, &quot;&gt;yokohama_stat.json&quot;) or die &quot;Cannot open json file.&quot;;
print FILE $json;
close(FILE);

sub get_content_by_url {
	my $url = shift;
	
	my $response = $browser-&gt;get( $url );
	# 正常に読み込みできたか確認する
	if ( $response-&gt;is_success ) {
		my $content = decode('Shift_JIS', $response-&gt;content) or die &quot;Decode html source code failed.&quot;;
		return $content;
	} else {
		die &quot;Get html form web failed.&quot;;
	}
}

sub get_stat_from_html {
	my $content = shift;
	
	my $te = new HTML::TableExtract(headers =&gt; [qw(年齢（歳） 総数)]);
	$te-&gt;parse($content) or die &quot;Parse file by htmlextract failed.&quot;;
	my $ts = ($te-&gt;tables)[0];
	my %nums;
	if(defined $ts and defined $ts-&gt;rows) {
		foreach my $row ($ts-&gt;rows) {
			print encode('utf-8', join(&quot;: &quot;,@$row)), &quot;\n&quot;;
			my $age;
			# 行見出しが0-5歳に該当する場合をそれぞれPickup（見出し数値は全角表記されている）
			if ($row-&gt;[0] eq '総数' ) {
				$age = &quot;TTL&quot;;
			} elsif ($row-&gt;[0] eq '０' ) {
				$age = 0;
			} elsif ( $row-&gt;[0] eq '１' ) {
				$age = 1;
			} elsif ( $row-&gt;[0] eq '２' ) {
				$age = 2;
			} elsif ( $row-&gt;[0] eq '３' ) {
				$age = 3;
			} elsif ( $row-&gt;[0] eq '４' ) {
				$age = 4;
			} elsif ( $row-&gt;[0] eq '５' ) {
				$age = 5;
			} else {
				next;
			}
			# 桁区切り文字を取り除いて、再度文字列として連結した後で数値に変換。Validationも兼ねて行う
			my $num = join('', split(/,/,$row-&gt;[1])) + 0 or die &quot;The population number invalid.&quot;;
			# 結果をhashに追加
			$nums{$age.&quot;&quot;} = $num;
		}
	}
	return \%nums;
}

</code></pre></noscript>
<p>&nbsp;</p>
<p>L40〜のget_content_by_urlで、WebサイトにアクセスしてHTMLソースを入手するsubルーチンが定義されています。</p>
<p>L54〜のget_stat_from_htmlは、前回記事で作成したスクリプトをほぼ流用しています。↑のHTMLソースコードから、０−５歳各年齢別人口と総計値を入手してhashテーブルにまとめるsubルーチンです。</p>
<p>&nbsp;</p>
<p>L16〜のforeachループで、上の２つのsubルーチンを呼び出して、行政区毎に処理を行うようにしてあります。</p>
<p>&nbsp;</p>
<p>・・・</p>
<p>JSONファイルが出来ました♪</p>
<p>&nbsp;</p>
<p>次はこのJSONファイルを元にD3.jsを使ってグラフでも描いてみようかと思います。</p>
<p>それでは、よい１日をお過ごしください♪</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hitsuji.me/get-stat-of-yokohama-city-population-automatically/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perlで横浜市統計webから人口データを入手する</title>
		<link>http://blog.hitsuji.me/get-population-of-babies-and-preschoolers/</link>
		<comments>http://blog.hitsuji.me/get-population-of-babies-and-preschoolers/#comments</comments>
		<pubDate>Mon, 07 Jul 2014 01:42:00 +0000</pubDate>
		<dc:creator><![CDATA[kapibarawebmaster1515]]></dc:creator>
				<category><![CDATA[データ収集]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[統計]]></category>

		<guid isPermaLink="false">http://blog.hitsuji.me/?p=107</guid>
		<description><![CDATA[こんにちは。今日は梅雨らしいジトジトしたお天気ですね。 雨ニモ負ケズ、元気に行こうと思います♥︎ &#160; さて、前回はようやく普通の横浜市地図を入手したところでした。その次に、地図を人口の大小で・・・<a class="readon" href="http://blog.hitsuji.me/get-population-of-babies-and-preschoolers/">続きを読む</a>]]></description>
				<content:encoded><![CDATA[<p>こんにちは。今日は梅雨らしいジトジトしたお天気ですね。</p>
<p>雨ニモ負ケズ、元気に行こうと思います♥︎</p>
<p>&nbsp;</p>
<p>さて、前回はようやく普通の横浜市地図を入手したところでした。その次に、地図を人口の大小で塗り分けたいので、今日は元となる人口データを調達したいと思います！</p>
<p>&nbsp;</p>
<h3>横浜市の人口データを入手する</h3>
<p>横浜市のページを開くと、おおっ、統計ポータルサイトがあります。</p>
<p>横浜市統計ポータルサイト <a title="横浜市統計ポータルサイト" href="http://www.city.yokohama.lg.jp/ex/stat/" target="_blank">http://www.city.yokohama.lg.jp/ex/stat/</a></p>
<p>&nbsp;</p>
<h4>ちょっと寄り道</h4>
<p>つい気になって、寄り道。「大都市推計人口」を見てみました。</p>
<p><a title="大都市推計人口" href="http://www.city.yokohama.lg.jp/ex/stat/jinko/city/new-j.html" target="_blank">http://www.city.yokohama.lg.jp/ex/stat/jinko/city/new-j.html</a></p>
<p><a href="http://www.city.yokohama.lg.jp/ex/stat/jinko/city/new-j.html"><img class="alignnone size-large_for_2x wp-image-108" src="http://blog.hitsuji.me/app/wp-content/uploads/2014/07/04a188429cc118bd4ccd534d3df1e96e-1200x635.png" alt="大都市推計人口" width="600" height="317" /></a></p>
<p><em>横浜市統計ポータルサイトより引用</em></p>
<p>&nbsp;</p>
<p>男女の性比が載っているのですが、地方都市は軒並み男性少ないじゃないですかー。東京に移動しているのかな・・・と見てみても、関東圏もほぼ男女比１：１みたいです。男性はどこへ行ったのでしょう・・・？女性の方が長生きするからでしょうか。もっと年代別の詳しいデータが無いと分からないですね。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h4>本題に戻ります</h4>
<p>先ほどの統計ポータルサイトに、年齢（各歳・５歳階級）別男女別人口が掲載されています。</p>
<p>こちら</p>
<p><a title="横浜市人口" href="http://www.city.yokohama.lg.jp/ex/stat/jinko/age/new/age-j.html">http://www.city.yokohama.lg.jp/ex/stat/jinko/age/new/age-j.html</a></p>
<p>&nbsp;</p>
<p>案の上、HTMLのテーブルデータとExcelですね・・・（正直メンドクサイ…；-；）。</p>
<p>行政区毎のデータが欲しいので、ちまちまコピペは嫌なので自動処理がしたい！</p>
<p>Web屋さんらしく、HTMLの方から目的のデータを入手するスクリプトを作ってみました。</p>
<p>&nbsp;</p>
<p>今日はPerlで実装します。TableExtractというモジュールが使えそうです。</p>
<p>日本語で使い方を書いてくれているサイト発見：</p>
<p><a title="TableExtract" href="http://www.geocities.co.jp/SiliconValley-Sunnyvale/6128/perl/tableextract.html" target="_blank">http://www.geocities.co.jp/SiliconValley-Sunnyvale/6128/perl/tableextract.html</a></p>
<p>&nbsp;</p>
<p>上のサイトを参考にして、早速小さいスクリプトを書いてみました。<br />
※目的のhtmlをtest.htmlとしてローカルに保存してあります。</p>
<h6>read_yokohama_population.pl</h6>
<script src="https://gist.github.com/088c1d13ba9bd6802119.js"></script><noscript><pre><code class="language-perl perl">#! /opt/local/bin/perl
use strict;
use warnings;
use 5.012;
use Encode;
use HTML::TableExtract; 
use utf8;

my $filepath = &quot;test.html&quot;;
open(FILE, $filepath) or die &quot;Open a html file failed.&quot;;
my $content = &quot;&quot;;
while (my $line = &lt;FILE&gt;) {
	$content .= decode('Shift_JIS', $line);;
}
close(FILE);

my $te = new HTML::TableExtract(headers =&gt; [qw(年齢（歳） 総数)]);
$te-&gt;parse($content) or die &quot;Parse file by htmlextract failed.&quot;;
my $ts = ($te-&gt;tables)[0];
my %nums;
if(defined $ts and defined $ts-&gt;rows) {
	foreach my $row ($ts-&gt;rows) {
		print encode('utf-8', join(&quot;: &quot;,@$row)), &quot;\n&quot;;
		my $age;
		# 行見出しが0-5歳に該当する場合をそれぞれPickup（見出し数値は全角表記されている）
		if ($row-&gt;[0] eq '０' ) {
			$age = 0;
		} elsif ( $row-&gt;[0] eq '１' ) {
			$age = 1;
		} elsif ( $row-&gt;[0] eq '２' ) {
			$age = 2;
		} elsif ( $row-&gt;[0] eq '３' ) {
			$age = 3;
		} elsif ( $row-&gt;[0] eq '４' ) {
			$age = 4;
		} elsif ( $row-&gt;[0] eq '５' ) {
			$age = 5;
		} else {
			next;
		}
		# 桁区切り文字を取り除いて、再度文字列として連結した後で数値に変換。Validationも兼ねて行う
		my $num = join('', split(/,/,$row-&gt;[1])) + 0 or die &quot;The population number invalid.&quot;;
		# 結果をhashに追加
		$nums{$age.&quot;&quot;} = $num;
	}
}

# 結果を出力してみる
print &quot;Age 0-5\n&quot;;
foreach my $age (keys(%nums)) {
	print $age, &quot; &quot;, $nums{$age}, &quot;\n&quot;;
}

1;</code></pre></noscript>
<p>&nbsp;</p>
<p>TableExtractモジュール、とっても便利ですね！カラムの見出し値を指定することで、抽出するテーブル＆カラムを限定することが出来るようです。</p>
<p>&nbsp;</p>
<p>他に注意点としては、</p>
<p>お役所のホームページなので、エンコードがShift_JISです。読み込んだHTMLソースは、Shift_jisでdecodeにてPerl内部リテラルに変換します。出力時は自分の標準出力環境がutf-8なので、utf-8でencodeします。</p>
<p>&nbsp;</p>
<p>行見出しが0-5の各年齢に合致する値を入手したいのですが、見出しの年齢が全角表記になっていますね。見出しが全角の0-5各年齢と一致する行を選択して、その後の処理のしやすさを考えて、半角数値に置き直しています。</p>
<p>&nbsp;</p>
<p>人口は３桁毎にカンマ（,）で区切られているので、カンマを除去、再度文字列連結してから、数値データに変換しています。数値データへの変換が上手くいくかどうかでvalidationの機能を持たせているつもりです。</p>
<p>&nbsp;</p>
<p>次回は、各行政区のデータを一気にWebから取得して、目的の人口データを入手してファイルに書き出す処理を実装したいと思います。</p>
<p>&nbsp;</p>
<p>それでは、よい一日をお過ごしください♥︎</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hitsuji.me/get-population-of-babies-and-preschoolers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
