Table of Contents
概要
- XML::Simple を使って XML を読む
- Amazon Web Services の BrowseNodeSearch の結果をXML::Simpleを使って解析し、子ノードを探索する。
- 親ノード/子ノードの表示だけ行いファイル保存はしないようにした。(2009/12/05)
- AssociateTagを指定するようにした。(2011/10/27)
- Web版
BrowseNodeSearch
- 下記URLにリクエストすることで、あるBrowseNodeの子ノード一覧を取得できる。
- XXXXは調べたいBrowseNode。
http://webservices.amazon.co.jp/onca/xml ?Service=AWSECommerceService &Operation=BrowseNodeLookup &ResponseGroup=BrowseNodeInfo &AssociateTag=xxxx-22 &BrowseNodeId=XXXX
- XXXXは調べたいBrowseNode。
スクリプト
-
BrowseNodes2.zip
#!/usr/local/bin/perl # # BrowseNodes2.pl # Amazon Web Services BrowseNodes 探索スクリプト # by TakeAsh # # http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/BrowseNodeIDs.html # # 2009.12.05 v2.00 親ノード/子ノードの表示だけ行いファイル保存はしないようにした。 # 2011.10.27 v2.01 AssociateTagを指定するようにした。 use strict; use warnings; use utf8; use Encode; use URI::Amazon::APA; use LWP::UserAgent; use XML::Simple; use YAML::Syck; $YAML::Syck::ImplicitUnicode = 1; my $charsetConsole = 'CP932'; #my $charsetInFile = 'UTF-8'; #my $charsetOutFile = 'UTF-8'; binmode( STDIN, ":encoding($charsetConsole)" ); binmode( STDOUT, ":encoding($charsetConsole)" ); binmode( STDERR, ":encoding($charsetConsole)" ); my $confyaml = './ID.yaml'; my $conf = YAML::Syck::LoadFile( $confyaml ) or die( "$confyaml: $!\n" ); my $nodelistbaseyaml = './BrowseNodeIDs-JP.yaml'; my $nodelistbase = YAML::Syck::LoadFile( $nodelistbaseyaml ) or die( "$nodelistbaseyaml: $!\n" ); unless ( @ARGV ){ print "BrowseNodeId\tCategory\n"; foreach my $nodeid ( sort by_number ( keys( %{$nodelistbase} ) ) ){ print "$nodeid\t$nodelistbase->{$nodeid}\n"; } die( "usage: $0 <browse_node_id> [ <browse_node_id> ...]\n" ); } my $browsenodeid = join( ",", @ARGV ) || '465610'; my $u = URI::Amazon::APA->new( 'http://ecs.amazonaws.jp/onca/xml' ); $u->query_form( Service => 'AWSECommerceService', Operation => 'BrowseNodeLookup', ResponseGroup => 'BrowseNodeInfo', AssociateTag => $conf->{'ASSOCIATE_TAG'}, BrowseNodeId => $browsenodeid, ); $u->sign( key => $conf->{'AWS_ACCESS_KEY_ID'}, secret => $conf->{'SECRET_ACCESS_KEY'}, ); my $ua = LWP::UserAgent->new; my $r = $ua->get($u); if ( $r->is_success ){ my $content = XMLin( $r->content, ForceArray => [ 'BrowseNode', 'Error' ], KeyAttr => { 'BrowseNode' => '+BrowseNodeId' } ); # die( YAML::Syck::Dump( $content ) ); if ( my $errors = $content->{'BrowseNodes'}->{'Request'}->{'Errors'} ){ die( YAML::Syck::Dump( $errors ) ); } my $nodelist = $content->{'BrowseNodes'}->{'BrowseNode'}; # die( YAML::Syck::Dump( $nodelist ) ); foreach my $nodeid ( sort by_number ( keys( %{$nodelist} ) ) ){ my $node = $nodelist->{$nodeid}; print "Node\t\t$node->{'BrowseNodeId'}\t$node->{'Name'}\n"; printAncestors( $node ); my $children = $node->{'Children'}->{'BrowseNode'}; foreach my $childid ( sort by_number ( keys( %{$children} ) ) ){ my $child = $children->{$childid}; print "Child\t\t$child->{'BrowseNodeId'}\t$child->{'Name'}\n"; } } } else { die( $r->status_line, "\n" ); } exit; sub by_number { $a <=> $b; } sub printAncestors { my( $browsenode ) = @_; if ( my $ancestors = $browsenode->{'Ancestors'}->{'BrowseNode'} ){ foreach my $nodeid ( keys( %{$ancestors} ) ){ my $node = $ancestors->{$nodeid}; print "Ancestor\t$node->{'BrowseNodeId'}\t$node->{'Name'}\n"; printAncestors( $node ); } } } # EOF
エラーメッセージ対応
- XML::Simple で下記エラーメッセージが表示される。
could not find ParserDetails.ini in D:/Perl64/site/lib/XML/SAX
次の行を追加する。
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
https 対応
- URI::Amazon::APA 0.05 は https に対応していない。
my $u = URI::Amazon::APA->new('https://webservices.amazon.co.jp');
エラーメッセージ
500 Can't connect to webservices.amazon.co.jp:80 (LWP::Protocol::https::Socket: SSL connect attempt failed error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol)
- https のエンドポイントを使用するにはポートまで指定する必要がある。
- testHttps.pl
#!/bin/perl # test https scheme for URI and URI::Amazon::APA use strict; use warnings; use utf8; use Encode; use URI::Amazon::APA; use YAML::Syck qw(Dump); use open ':std' => ':locale'; print "URI: ${URI::VERSION}\n"; print "URI::Amazon::APA: ${URI::Amazon::APA::VERSION}\n"; my @uris = qw( https://webservices.amazon.co.jp/onca/xml https://webservices.amazon.co.jp:443/onca/xml ); foreach my $uri (@uris) { print "\n# ${uri}\n"; print "URI:\n"; print Dump( getProperty( URI->new($uri) ) ) . "\n"; print "URI::Amazon::APA:\n"; print Dump( getProperty( URI::Amazon::APA->new($uri) ) ) . "\n"; } sub getProperty { my $u = shift; return { scheme => $u->scheme, secure => $u->secure, host => $u->host, port => $u->port, }; }
- テスト出力
URI: 1.74 URI::Amazon::APA: 0.05 # https://webservices.amazon.co.jp/onca/xml URI: --- host: webservices.amazon.co.jp port: 443 scheme: https secure: 1 URI::Amazon::APA: must be http at ./testHttps.pl line 25. --- host: webservices.amazon.co.jp port: 80 scheme: https secure: 0 # https://webservices.amazon.co.jp:443/onca/xml URI: --- host: webservices.amazon.co.jp port: 443 scheme: https secure: 1 URI::Amazon::APA: must be http at ./testHttps.pl line 25. --- host: webservices.amazon.co.jp port: 443 scheme: https secure: 0