AWS各サービスの価格情報をスクレイピングするワンライナー
昔のURLは非推奨になってしまった
AWSの価格一覧を取得したいときに以前まで使っていたURLが非推奨になってしまっていました。そこで、新しいURLを使って同じようなことをしてみたいと思います。
以前の方法。
https://aws.amazon.com/jp/ec2/pricing/json/linux-od.json
301転送される
https://a0.awsstatic.com/pricing/1/deprecated/ec2/linux-od.json
新しいURLはAWSの各サービスのHTMLソースを見れば分かります。新しいURLはJSONではなくJSONPのコールバックになっています。これはブラウザアプリから呼び出し易くなりましたが、スクレイピングするには面倒です。そこで、JSONに変換するワンライナーを入れます。
新しいURL
http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js
callback部分を外す
$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \ | sed -n 's/.*callback(//p' \ | sed -e 's/);$//g'
JSONとして認識させるために名前を"でくくる
$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \ | sed -n 's/.*callback(//p' \ | sed -e 's/);$//g' \ | sed 's/\([0-9a-zA-Z]*\):/\"\1\":/g'
jqで形を整える
$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \ | sed -n 's/.*callback(//p' \ | sed -e 's/);$//g' \ | sed 's/\([0-9a-zA-Z]*\):/\"\1\":/g' \ | jq .
結果
・・・ "regions": [ { "region": "us-east-1", "instanceTypes": [ { "type": "generalCurrentGen", "sizes": [ { "size": "t2.micro", "vCPU": "1", "ECU": "variable", "memoryGiB": "1", "storageGB": "ebsonly", "valueColumns": [ { "name": "linux", "prices": { "USD": "0.013" } } ] ・・・
jqを使ってもっとピンポイントに情報を収集する
基本的な方法が分かりましたので必要な情報だけを取り出してみましょう
対応しているリージョン一覧
$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \ | sed -n 's/.*callback(//p' \ | sed -e 's/);$//g' \ | sed 's/\([0-9a-zA-Z]*\):/\"\1\":/g' \ | jq .config.regions[].region
結果
"us-east-1" "us-west-2" "us-west-1" "eu-west-1" "eu-central-1" "ap-southeast-1" "ap-northeast-1" "ap-southeast-2" "sa-east-1" "us-gov-west-1
東京リージョンの情報だけ取得
$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \ | sed -n 's/.*callback(//p' \ | sed -e 's/);$//g' \ | sed 's/\([0-9a-zA-Z]*\):/\"\1\":/g' \ | jq .config.regions[] \ | jq 'select(.region=="ap-northeast-1")'
結果
{ "region": "ap-northeast-1", "instanceTypes": [ { "type": "generalCurrentGen", "sizes": [ { "size": "t2.micro", "vCPU": "1", "ECU": "variable", "memoryGiB": "1", "storageGB": "ebsonly", "valueColumns": [ { "name": "linux", "prices": { "USD": "0.020" } } ] }, ・・・
Spotインスタンスの情報
Spotインスタンスの情報が入っているjsは、静的テキストではなく動的生成しているようで、他とフォーマットが異なるのでコマンドも少々違います。
$ curl http://spot-price.s3.amazonaws.com/spot.js \ | sed -e 's/.*callback(//g' \ | sed -e 's/)$//g' \ | jq .config.regions[] \ | jq 'select(.region=="apac-tokyo")'
結果
{ "region": "apac-tokyo", "footnotes": { "*": "clusterOnlyInUSEast" }, "instanceTypes": [ { "type": "generalCurrentGen", "sizes": [ { "size": "m3.medium", "valueColumns": [ { "name": "linux", "prices": { "USD": "0.0122" } }, { "name": "mswin", "prices": { "USD": "0.0731" } } ] }, ・・・
他サービスの価格情報
EC2
- Linux : http://a0.awsstatic.com/pricing/1/ec2/ri-v2/linux-unix-shared.min.js
- RHEL : http://a0.awsstatic.com/pricing/1/ec2/ri-v2/red-hat-enterprise-linux-shared.min.js
- SUSE : http://a0.awsstatic.com/pricing/1/ec2/ri-v2/suse-linux-shared.min.js
- Windows : http://a0.awsstatic.com/pricing/1/ec2/ri-v2/windows-shared.min.js
- Windows with SQL Server : http://a0.awsstatic.com/pricing/1/ec2/ri-v2/windows-with-sql-server-standard-shared.min.js
- Windows with SQL Server Web Shared : http://a0.awsstatic.com/pricing/1/ec2/ri-v2/windows-with-sql-server-web-shared.min.js
- Spot Instance(直近5分) : http://spot-price.s3.amazonaws.com/spot.js
- データ通信 : http://a0.awsstatic.com/pricing/1/ec2/pricing-data-transfer-with-regions.min.js
- EBS Optimized : http://a0.awsstatic.com/pricing/1/ec2/pricing-ebs-optimized-instances.min.js
- EBS : http://a0.awsstatic.com/pricing/1/ebs/pricing-ebs.min.js
- EIP : http://a0.awsstatic.com/pricing/1/ec2/pricing-elastic-ips.min.js
- CloudWatch : http://a0.awsstatic.com/pricing/1/cloudwatch/pricing-cloudwatch.min.js
- ELB : http://a0.awsstatic.com/pricing/1/ec2/pricing-elb.min.js
RDS
- MySQL : http://a0.awsstatic.com/pricing/1/rds/mysql/pricing-standard-deployments.min.js
- MySQL MultiAZ : http://a0.awsstatic.com/pricing/1/rds/mysql/pricing-multiAZ-deployments.min.js
- Oracle SE : http://a0.awsstatic.com/pricing/1/rds/oracle/pricing-li-standard-deployments.min.js
- Oracle MultiAZ : http://a0.awsstatic.com/pricing/1/rds/oracle/pricing-li-multiAZ-deployments.min.js
- SQL Server SE : http://a0.awsstatic.com/pricing/1/rds/sqlserver/sqlserver-li-se-ondemand.min.js
- SQL Server SE MultiAZ : http://a0.awsstatic.com/pricing/1/rds/sqlserver/sqlserver-li-se-ondemand-maz.min.js
- PostgreSQL : http://a0.awsstatic.com/pricing/1/rds/postgresql/pricing-standard-deployments.min.js
- PostgreSQL MultiAZ : http://a0.awsstatic.com/pricing/1/rds/postgresql/pricing-multiAZ-deployments.min.js
- データ通信 : http://a0.awsstatic.com/pricing/1/rds/postgresql/pricing-data-transfer.min.js
S3
- データ保存 : http://a0.awsstatic.com/pricing/1/s3/pricing-storage-s3.min.js
- リクエスト : http://a0.awsstatic.com/pricing/1/s3/pricing-requests-s3.min.js
- データ転送 : http://a0.awsstatic.com/pricing/1/s3/pricing-data-transfer-s3.min.js
Redshift
- Redshift Ondemand : http://a0.awsstatic.com/pricing/1/redshift/pricing-on-demand-redshift-instances.min.js
ElastiCache
- ElastiCache Ondemand : http://a0.awsstatic.com/pricing/1/elasticache/pricing-standard-deployments-elasticache.min.js
まとめ
ある程度メジャーなサービスは価格表をjs経由で取得出来る事が分かりました。jqで加工できますので煮るなり焼くなりしてDBなどに入れておいても良いかもしれませんね。