AWSをはじめよう! で詰まったところ
「AWSをはじめよう」を電子書籍の配信日にゲットするも、前作の「DNSをはじめよう」みてからがオススメ!という文中のアドバイスに従い、DNS本を購入して読み終わり、そのままAWS本読むのを忘れてたというね。 pic.twitter.com/hTas3UQvE8
— sironekotoro (@sironekotoro) September 14, 2019
ってことで、2019年09月最初の連休はAWSに入門しております。
この本は2018年10月08日に技術書典5で頒布されたものですが、約1年後のこの連休に試してみたところ、ちょっと詰まったところがあったので残しておきます。
技術書、特にITがらみはサービスの進化も早く、頻繁にデザインが変わるので、出た瞬間からすごい勢いで古くなってしまうという宿命があります。つらい。
この本はAWSの管理画面の画像も多くわかりやすいのですが、一部は既にAWS側のデザインや名称が異なっています。
とはいえ、ある程度は推測ができるものでそれほど迷うことはありませんでした。
詰まったところ 「6.3 画像をS3に保存する」
この第6章ではAWSのEC2上にWordPressを立てます。
本の通りに立てたところ、以下の構成になりました。
3節では画像の保存先をAmazon S3にするということで、プラグインを使う方法が書かれていました。プラグインは2つです。
この2番目のプラグイン、プラグインの検索で引っかからなくなっています。色々ググってみたんですが、うちのググり力なくて、解決まで時間がかかりました。
ということで、最終的には
ということで落ち着きました。
WP Offload Media Lite
名前の通りWP Offload S3 Liteプラグインの機能拡張版です。S3以外のクラウドストレージへの保存にも対応しています。
このWP Offload Media LiteプラグインはS3に保存する際のアクセスキーIDとシークレットアクセスキーIDを独自に保存が可能です。このため、このプラグインでS3に保存するだけであればAmazon Web Serviceプラグインを削除しても画像のアップロードは可能でした。
WordPressの管理画面で
WP Offload Media Lite
を検索し、「今すぐインストール」ボタンでインストールするインストールが完了したら、「有効化」ボタンを押す
プラグイン一覧の画面で有効化し、「Settings」のリンクをクリックする
以下のような画面が出てくるので、Access Key IDとSecret Access Keyを入力する
もし、以下のような画面が出た場合には、既に設定があるということなので、Back のリンクから Offload Media Liteの設定ページに移動する
移動した先のページの AmazonS3 の右にある Change のリンクをクリックすると 4. の画面に移動する
バケットの指定をしていない場合には以下の画面が出るので、バケット名を入力する
・・・ただし、ここでAmazon S3の制限に気をつける必要がある
つまり、本にある通り東京リージョンでは
start-aws-wordpress-bucket
という名称のバケットを作ることができない。うちは後ろに-sironekotoro
ってつけて回避。httpsにする
ここは本と同じ
これで、WordPressにあげた画像をS3に保存することができました。めでたしめでたし。
おまけ
PHP触るの初めてかもなー、ってことで、ググりながら書いた初めてのPHP。
<?php header("Content-type: text/plain"); for ( $i = 1; $i <= 100; $i++){ if ($i % 15 == 0){ echo "fizzbuzz\n"; }elseif ($i % 3 == 0){ echo "fizz\n"; }elseif($i % 5 == 0){ echo "buzz\n"; }else{ echo "$i\n"; } } ?>
Perl入学式 in 東京 第5回 ピザ会でのお題「WebアプリからLINEに定型メッセージ送信」
Perl入学式 in 東京では各回の講義終了後にピザ会(ピザ&ジュース代は参加者負担)を開催しており、そこで受講者さんと雑談などをしております。
その中で、id:xtetsuji さんが課題が出し、志願者がコードを書いてその場で発表、という試みを行っています。
今回のお題:WebアプリからLINEに定型メッセージ送信
- Mojolicious::Lite でボタンが並んでいるページを作る
- そのボタンには「帰宅」「横になる」「寝る」などの状態が書かれている
- そのボタンを押すと、IFTTT の WebHookを経由してLINEに「帰宅」「横になる」「寝る」などのメッセージが投稿される
- ボタンを押した後は「送信しました」というページが表示される
- LINEの家族チャットなどに送信できると便利なのではないか?
というものでした。
しかし
当方、LINE使っていないでござる・・・
ということで、当日は作りかけだったTwitterのアプリからAPIKeyを流用してでっち上げ。
ボタンを押すと、メッセージがtwitter APIを利用してtwitterに投稿される、というものです。
Perl入学式 第5回の講義資料の最後に掲載した「落ち穂拾い」にあるGETとPOSTを分けたコードになっています。
ボタンを押すと、TwitterAPI経由で定型メッセージをtweetする君
クリックするとコードが出てきます
ぶぶー!レギュレーション違反です!!
LINEじゃなくてtwitterだし、IFTTTじゃなくてtwitterのAPIだけど、ボタンを押すとメッセージが飛ぶという結果自体は同じだし・・・
しかし、やっぱりレギュレーション満たしたコード書いてみたいですよね!
というわけで、LINEに登録。
IFTTT
まずはIFTTTについて情報あつめ。
うんうん、大体わかった(フラグ
Continue with Google or Facebook からGoogleでログイン。
ログイン後、右上のユーザーのアイコンをクリックして Create を選択
IF + THEN THIS THAT の + をクリック
たくさんのアイコンが出てくるので、検索窓に web と入力。出てきた Web Hook をクリック
Connect Webhooks 画面のConnect ボタンをクリック
Receive a web request をクリック
Event Name は適当に・・・send_message とかにしとこう。ほんで、 Create trigger ボタンをクリック
おぉ、+ のところが Web Hook のマークになった。では次の + のマークのところをクリック。
検索窓に今度は LINE と入力して、出てきた LINEの緑のアイコンをクリック
Connectボタンを押すと、LINEのメアドとパスワード入力画面が出るのでそれを入力
同意して連携する、をクリック
Send message という緑のボタンが出てくるのでそれをクリック
Recipient という画面が出てくる・・・とりあえず、何も変更せずに Create action をクリック
確認画面が出てくるので Finish をクリック
次に出てきた画面で、Web Hook のアイコンをクリック
画面右上にある Documentationをクリック
画面下部にある
curl -X POST https://maker.ifttt.com/trigger//with/key/YOUR_KEY
をターミナルから実行LINE Notify にメッセージが届く
届いたメッセージは
[IFTTT] Value 1: Value 2: Value 3:
ふむ。とりあえず、URLにアクセスすると、LINEに何か通知が届く、というところまではできた。
IFTTTのAPI調整
このDocumentationのページ、薄い四角のところは実は文字が入力可能だったりする。
{event}
に 6. で決めたEvebt Name である send_message
を入力、Value1 , 2, 3 にそれぞれ対応する何か適当な文字を入れて、画面下部にあるTest it!を使うと・・・おぉ、ちゃんと文字が入ったメッセージが届いた!
あ、画像からはKEYは消してます。
ということで、このURLをPerlで組み立て、そしてMojolicious::Liteのボタンを押した時にURLに送信するようにすれば、レギュレーションは満たせそう。
ちなみに、このDocumentationページから入力が可能ってのがわからなくて、2時間くらい試行錯誤したよ!
というわけで、出来上がったコードがこれです。第5回はサブルーチンもやったので、IFTTTにリクエスト投げるところはサブルーチンにしてみました。
ボタンを押すと、IFTTT API経由で定型メッセージをLINEに流す君
クリックするとコードが出てきます
gist.github.com
注意
このコードをインターネットに置いた場合、誰彼構わずボタンが押しまくられるだろうことは想像に難くないです。
ただ、自分の手元のパソコンで利用するだけであれば十分でしょう。
IFTTTと連携したレシピをPerlから制御することができる、というのは日々の暮らしがちょっと楽になる素晴らしい技術だと思います。
また、IFTTT経由ではなく、直接LINEのAPIを使ってみるのも良いかもしれません。
ぜひ、試行錯誤して日々の煩わしい業務や暮らしを楽にしてください!
試行錯誤の後
苦労した跡が見てとれる pic.twitter.com/eaNCGcpJ7r
— sironekotoro (@sironekotoro) 2019年9月2日
Perl入学式 2019 in東京 第5回 お疲れ様でした
受講された方、サポーターの方、気温と湿度の高い中、お疲れ様でした。 講師をやったジャージの人です。
Perl入学式第5回です。Webアプリに関するスライドも大改修を施しました。その影響でいくつか表記の抜けや不整合があり、お手数とご迷惑をおかけしました。すみません。
スライドの修正は完了しており、近々反映予定です。スライドの修正が完了しました。
コードの追加や削除、編集をGitHubのdiffを使うことで、わかりやすく提示できたと考えています。
講義に利用したスライドはMarkdown形式で公開しています。復習に使ってください。スライドの最後の方に「落ち穂拾い」として追加のコンテンツもあります。チャレンジしてみてください。
スライド中にある練習問題の解答例を掲載しています。TMTOWTDI(There's More Than One Way To Do It.(やり方は何通りもある))の一つとして、参考にしてください。
問題の意味がわからない、とか、このような解答例はどうだろう?という方はSlackのPerl入学式チャンネル(招待フォーム)やtwitterでハッシュタグ #Perl入学式 をつけて聞いてみてください。 応答速度、監視頻度などの面からSlackの方をお勧めします。
Perl入学式を終えた方へ
一昨年、同じようなエントリ書いていたんで、リンク貼っておきます。
以下、講義中に言及したオススメ。
また、これまでの第5回 Webアプリ編 の自分のエントリを並べておきます。
2019年後半のPerl入学式
従来、Perl入学式 in東京 は年に2回、同じ内容を繰り返す受講スケジュールでやってきました。
が、今年後半の構成はちょっと変わる可能性があります。
(変わらない可能性もある)
connpassやTwitter、Slackでの告知があると思いますので、興味のある方は続報をお待ちください。
YAPC::Japan ?????
海外からの情報なんですが、来年の3月末くらいにPerlのお祭り YAPC::Japanが開催されるようです。公式発表を楽しみに待ちましょう。
YAPCはPerlの話はもちろん、様々なシステムやサービスの構成、ベストプラクティスや新しい知見を得られる場です。参加を強くお勧めします。受講した方とお会いできるのを楽しみにしてます。
(動画の18分あたり)
懇親会などで出た話の元ネタやリンクなど
今回の懇親会のお題については別エントリで。
謎のカタツムリ
講師の @sironekotoro さん「謎のカタツムリみたいなやつに引数が入っていると思って下さい」。これから @_ を見たらカタツムリに見えてしまう。 #Perl入学式
— OGATA Tetsuji (@xtetsuji) 2019年8月31日
my @hoge = @_;
PerlからGoogleの感情分析を使ってみる
お盆明けから妙に気分が沈んだり、なんかおかしいなーって感じですが、みなさんお元気でしょうか。うちはダメです。
で、ほぼ毎日twitterでつぶやいているツイ廃としては、過去に呟いた内容をもとに、いつからおかしくなったのか?ってのを調べてみようと思ったのです。
と思って、twitterの履歴から感情分析とかしたら面白そう・・・ってことで日本語で感情分析できるGoogleのAPI使えないかなーってやってみてた。とりあえず、APIKEYベタ書きならリクエスト投げて戻ってくるところまでいけた。整理してblogに書けるかなー / https://t.co/hm4YO9GqiA
— sironekotoro (@sironekotoro) 2019年8月25日
今回はGoogleの感情分析APIを使ってみるところまでやってみました。暗く沈んでる時期の自分のtweet漁るのは怖さがある・・・
しかし、いつもの通りPerl用のライブラリやSDK(Software Development Kit)は提供されていない・・・けど、WebAPIであればリクエストを投げて受け取るだけなので安心(安心?
JSONでPOSTして、JSONで受け取る、ということなのでSDKなくてもなんとかなりそうですね。
ただ、APIを利用するためにGoogle CloudのAPI_KEYの取得とクレジットカード登録の必要があり、そこはハードルが高いかもしれません。
うちの場合、昔、BigQuery試してみた時にクレカを登録していました。
参考にしたところ
Google Cloud Natural Language API 公式サイト
GoogleのAPI使うための認証情報の扱いとか。特に環境変数の設定のあたり
公式サイトのほか、こちらのページが大変参考になりました。実装はPHPですが、curl をつかってリクエストを投げてくれるところがあって、Perlで書くにあたって大変助かりました。
macOS用のパッケージ管理ソフト brew cask をつかってgoogle-cloud-sdkを入れる際に参考にしました。
動かすまで
google-cloud-sdk
をインストール$ brew cask install google-cloud-sdk
$ brew cask info google-cloud-sdk
秘密鍵のファイルをローカルにおいて、パスを通したりする
早く動かしたいので、コマンドラインでAPI_KEYを表示させて、それをスプリプトに直接入れることにする
$ gcloud auth application-default print-access-token
PerlのWebクライアントでAPIを叩いて、 返ってくるエラーを見ながらGCPの権限をつけたり、コードを直したりする
Furl
ではうまく動いたので、標準に寄せるべくHTTP::Tiny
で書き直してたらハマった・・・ハマった原因は、
headers
と書くところをheader
と書いていたからなのでした
うごいたー!
こんな感じです。あー、参考にならない書き方ー
あと、やはり環境構築が鬼門だなぁという感じ。
コード
でも、コードがあればなんとかなりそうなので、コードを置いておきますね。
PerlでWebから情報を持ってくるときのツール
まず注意
昨今のWebではhttps化が進んでいます。https の s はSecureの s です。安全な通信をするためにデータを暗号化/復号するのですが、そのためのモジュールが別途必要です。
運が良ければ、すでにインストールされているかも・・・
Perl入学式で構築した手元のMsys32(Windows7上に構築)だと
のちに出てくる
HTTP::Tiny
のサンプルスクリプトを試したところ、httpのサイト(例:http://www.hatena.ne.jp/)はアクセスできるが、httpsのサイト(例:https://www.yahoo.co.jp)にPerlのスクリプトからアクセスできず。エラーメッセージによると、
Net::SSLeay
が無いとのこと。cpanm Net::SSLeay
- インストール失敗
- エラーメッセージによると、MSYS側にSSL環境がなさそう
pacman -Syu
- MSYS側の更新がなくなるまで複数回実行&再起動
- エラー変わらず
pacman -S openssl
- MSYSのopensslのインストールはできたが、
cpanm Net::SSLeay
は失敗
pacman -S perl-Net-SSLeay
cpanm IO::Socket::SSL
- 大文字小文字を厳密に見てくるので注意
- こっちはなんか時間切れとか出てくる。きー!
pacman -S perl-IO-Socket-SSL
- インストールできた
- うごいた!
こんな感じでした。ここまでが長い。でも、動いてしまえば「許そう、全てを・・・」って気分になりませんか。うちはなります。
HTTPクライアント編
HTTPクライアントというのは、Chromeとか、Firefoxとかそういったブラウザです。HTTPサーバーにアクセスし、情報を得るものです。
プログラムからもHTTPサーバにアクセスして情報を得ることができます。
以下はPerlでのHTTPクライアントの紹介です。
HTML::Tiny
Perl 5.13.9以降であればコアモジュールとしてPerl本体と一緒にインストールされるモジュール。なので、普通にPerlをインストールすれば大概の環境では使えるはず。
$ corelist HTTP::Tiny Data for 2018-11-29 HTTP::Tiny was first released with perl v5.13.9
HTTP::Tiny のページにあるサンプルをPerl入学式にある範囲で書き直したものです。あと、対象を日本のYahoo Japanに変えています。
$response->{content}
とか、リファレンス回をやった人だと見覚えがあるのではないでしょうか。ハッシュリファレンスですね。
use strict; use warnings; use HTTP::Tiny; # Yahooのurlを変数に入れる my $yahoo_url = 'http://www.yahoo.co.jp'; # HTTP::TinyでYahooにアクセスして、getでデータを持ってくる my $response = HTTP::Tiny->new->get($yahoo_url); # データを持ってくるのに成功したかどうかを判別 if ( $response->{success} ) { # 成功してたら、HTTPのステータスコードを表示。200ならok print "$response->{status} $response->{reason}\n"; } # 失敗してたら、プログラム終了 else { print "Failed!\n"; exit(); } print $response->{content}; # ヤフーのHTMLが表示される
LWP::Simple
ここからは cpanm でのインストールが必要なモジュール。LWP というのは ibwww-perl の略称で、PerlをつかってWebにアクセスするときの基本的なモジュールです。その機能最小版です。
use strict; use warnings; use LWP::Simple; # Yahooのurlを変数に入れる my $yahoo_url = 'http://www.yahoo.co.jp'; # getでデータを持ってくる my $content = get($yahoo_url); # データ持ってくるのに成功したら表示する if ($content) { print $content; # ヤフーのHTMLが表示される }
HTTP::Tinyと大体同じですね。うちのコメントも早くも簡素になってきました。
LWP
上記 LWP::Simple の大元である、HTTPアクセスに必要なことの全てが詰まったフルセット版です。 ユーザーエージェントの変更やPOSTでのデータ送信など、HTTP通信を使った機能が詰まっています。
use strict; use warnings; use LWP::UserAgent; # Yahooのurlを変数に入れる my $yahoo_url = 'http://www.yahoo.co.jp'; # LWP::UserAgentのインスタンスを生成する my $ua = LWP::UserAgent->new(); # HTTP::Requestのインスタンスを生成するついでに、GETでアクセスしに行くページも設定する my $req = HTTP::Request->new( GET => $yahoo_url ); # uaがGETでyahooにデータを取りに行く my $res = $ua->request($req); # ページの取得に成功してたら内容を表示する if ( $res->is_success ) { print $res->content; # ヤフーのHTMLが表示される }
Furl
tokuhiromさん作成の「早い」ライブラリ。
Furlはもう一つのHTTPクライアントライブラリです。LWPはPerl5のデファクトスタンダードな HTTPクライアントですが、クリティカルなジョブでは遅すぎますし、週末のハッキングには 複雑過ぎます。Furlはこれらの問題を解決します。楽しんで下さい!
use strict; use warnings; use Furl; # Yahooのurlを変数に入れる my $yahoo_url = 'http://www.yahoo.co.jp'; # Furlのインスタンスを生成するついでに、GETでアクセスしに行くページも設定する my $res = Furl->new->get($yahoo_url); # ページの取得に成功してたら内容を表示する if ( $res->is_success ) { print $res->content; }
Webスクレイピング
ここまで紹介したものは、Webサーバーにアクセスして、そこから情報を取得するものでした。しかし、ほとんどの用途では、Webの情報が全て必要なわけではなく、ごく一部のみ必要だったりします。
そういった情報を都度、正規表現などを使って取り出してもいいですが、もっと楽はできないものでしょうか?そんなプログラマの三大美徳「怠惰」を実現させるツール、ありそうですよね。
Webサーバから返ってきたデータのうち、必要な部分だけ取り出す、こそげとる、それがスクレイピングと言われるツールです。
ここからはPerlのスクレイピングモジュールを使ってYahooニュースからトピック一覧だけ取り出してみます。
Web::Scraper
うちはこのツールをPerl CPANモジュールガイド という本で知って、ほぼこれをメインに使っています。要素の指定にXPathとCSSセレクタを利用することができます。
この本には他にもPerlのモジュールがたくさん載っているので、やや古いとはいえオススメです。
use strict; use warnings; # 日本語をターミナルで表示(出力)するときに警告が出ないよう書いておく binmode STDOUT, ':encoding(UTF-8)'; use Web::Scraper; use URI; my $yahoo_news_url = 'https://news.yahoo.co.jp/topics'; my $uri = URI->new($yahoo_news_url); # どの要素を取得するかを設定する変数 my $scraper = scraper { # タイトルを取得するスクレイパー # Xpath形式で指定 process '/html/head/title', 'page_title' => 'TEXT'; # ニュースタイトル一覧を取得するスクレイパー # CSSセレクタ形式で指定 process 'li.topicsListItem > a ', 'news_titles[]' => 'TEXT'; }; # ここでスクレイピングが実行される my $res = $scraper->scrape($uri); # ここから結果表示 print $res->{page_title} . "\n"; # タイトルの表示 for my $title ( @{ $res->{news_titles} } ) { print $title . "\n"; # ニュースのタイトルの表示 }
Web::Query
Web::Query is a yet another scraping framework, have a jQuery like interface.
Javascriptのライブラリ、JQueryに似た方法で要素を指定してスクレイピンすることができるモジュールです。実はJQuery使ったことないので、わからない・・・
でも、直感的に要素を指定できる感じで良いですね。
use strict; use warnings; # 日本語をターミナルで表示(出力)するときに警告が出ないよう書いておく binmode STDOUT, ':encoding(UTF-8)'; use Web::Query; my $yahoo_news_url = 'https://news.yahoo.co.jp/topics'; # topicsListItem 属性をもつ li タグの下にある a タグを持ってきて、 # a タグのテキスト要素を表示する wq($yahoo_news_url)->find('li.topicsListItem > a')->each( sub { print $_->text . "\n"; } );
HTML::TreeBuilder
スクレイピングツールのくくりに入れましたが、HTML::TreeBuilderはHTMLをパース(解析)するためのツールです。
正確なHTMLは<html>
の中に<head>
と<body>
タグがあり、その中にさらに複数のタグが配置されています。
これを、<html>
という太い幹から<head>
と<body>
という枝が生え、さらにその枝から別の枝が生え・・・という木構造で解析していきます。
本来は「特定の枝の先にだけ、何らかの処理を行う」ということをしたかったのですが、ちょっと今の自分ではわかりませんでしたわ・・・
use strict; use warnings; # 日本語をターミナルで表示(出力)するときに警告が出ないよう書いておく binmode STDOUT, ':encoding(UTF-8)'; use HTML::TreeBuilder; my $yahoo_url = 'https://news.yahoo.co.jp/topics'; # new_from_urlメソッドは裏でLWP::UserAgent使っているので、 # LWP入れてないと動かない my $tree = HTML::TreeBuilder->new_from_url($yahoo_url); $tree->eof(); foreach $a ( $tree->find("a") ) { # news の a タグには data-ual-gotocontent って属性が付与されてた # ところで、ual って何だろう・・・urlならわかるんだけど my $data_ual_gotocontent = $a->attr('data-ual-gotocontent') || next; if ( $data_ual_gotocontent eq 'true' ) { print $a->as_text . "\n"; } }
閑話休題
WWW::Mechanize
一部の人には刺さるかもしれません。私も刺さった人です。
今まで紹介したものは、Webサーバから情報を持ってくるものと、Webページから特定のデータを抜き出す(スクレイピングする)ものでした。
ここで紹介する WWW::Mechanize
、通称Mech は、Webサーバからデータを受け取り、そのあとにリンクをたどったり、入力欄に文字を入れてボタンを押す、なんてことができます。
以下は、Yahooの検索ページの入力欄に「Perl入学式」という文字を入力して、その検索結果を得るスクリプトです。
use strict; use warnings; use utf8; # 日本語をターミナルで表示(出力)するときに警告が出ないよう書いておく binmode STDOUT, ':encoding(UTF-8)'; use WWW::Mechanize; # Yahooの検索ページのURL my $yahoo_search_url = 'https://search.yahoo.co.jp/'; # WWW::Mechanizeのインスタンスを生成する my $mech = WWW::Mechanize->new(); # Yahooの検索ページのHTMLをGETで取得する $mech->get($yahoo_search_url); # 取得したHTMLを解析し、フォームの入力欄に文字を入れて、 # そのフォームのボタン(検索ボタン)を押す $mech->submit_form( # 最初のフォーム form_number => 0, # name属性が p の入力欄に 検索対象の文字を入れる fields => { p => 'Perl入学式' }, ); # 結果を表示する print $mech->{content};
どうでしょう、ずらっとHTMLが表示されて、その中にかすかに検索結果らしきものが見えますね・・・これを整形したい・・・と思いませんか?
うちは思います。
ということで、ここで、先に登場したスクレイピングツールを使います。WWW::MechanizeでYahoo検索した結果から、タイトルとリンクをWeb::Scraperで取り出してみます。
use strict; use warnings; use utf8; # 日本語をターミナルで表示(出力)するときに警告が出ないよう書いておく binmode STDOUT, ':encoding(UTF-8)'; use WWW::Mechanize; my $yahoo_search_url = 'https://search.yahoo.co.jp/'; my $mech = WWW::Mechanize->new(); $mech->get($yahoo_search_url); $mech->submit_form( form_number => 0, fields => { p => 'Perl入学式' }, ); my $mech_result = $mech->{content}; # -----ここまでが WWW::Mechanize の部分 # -----ここからは Web::Scraper の部分 use Web::Scraper; my $scraper = scraper { # 検索結果を取得するスクレイパーを用意しているところ # Xpath形式で指定 //と書くことで前方の要素を省略する # ここでは、 # id が web 要素のdivタグを撮ってきて、その下(直下とは限らない)にある liタグを持ってくる # という内容 process '//div[@id="web"]//li', 'search_result[]' => scraper { # さらに、その取得条件からタイトルとリンクを分けて取得し、 # ハッシュで格納する process '//a', 'title' => 'TEXT'; process '//a', 'url' => '@href'; }; }; # ここでスクレイピングが実行される # スクレイプ対象にはmechで検索した後のページを入れる my $res = $scraper->scrape( $mech_result ); # ここから結果表示 for my $result ( @{ $res->{search_result} } ) { print '-------' . "\n"; print $result->{title} . "\n"; print $result->{url} . "\n"; print '-------' . "\n"; }
Web API
さっきので終わらせようと思ったんだけど、ふと、昨今のWebからのデータ取得をいうならWeb APIは外せないのでは?と思い至りました。遅い。
Web APIは簡単にいうと、プログラムが使いやすいように整形されたデータのやり取り、というところでしょうか。詳細はググったり調べたりでお願いします。
もちろん、上記のHTTP::TinyとJSON::PPモジュールを利用することでWeb APIで提供されているデータの取得と利用が容易になります。どちらもPerlのコアモジュールです(5.13.9 以降)。
ここでは、無料で利用できるAPIとして、Livedoorの天気予報APIを利用します。
地域は東京地方、今日(2019年8月4日)の最高気温を調べてみます。
HTTP::Tiny + JSON::PP
use strict; use warnings; use HTTP::Tiny; # Livedoor天気APIのURLを変数に入れる my $livedoor_weather_url = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=130010'; # HTTP::TinyでAPIにアクセスして、getでデータを持ってくる my $response = HTTP::Tiny->new->get($livedoor_weather_url); # データを持ってくるのに成功したかどうかを判別 if ( $response->{success} ) { # 成功してたら、HTTPのステータスコードを表示。200ならok print "$response->{status} $response->{reason}\n"; } # 失敗してたら、プログラム終了 else { print "Failed!\n"; exit(); } # 取得したデータはJSON形式なので、Perlで操作しやすいように変換する。 use JSON::PP; my $decoded_response = decode_json($response->{content}); # どんなデータ構造になっているかわからなくなったら、Data::Dumperを使おう! # use Data::Dumper; # print Dumper $decoded_response; # 最高気温 print $decoded_response->{forecasts}->[0]->{temperature}->{max}->{celsius}; # 34
34度!ヤダもう・・・
ところで、my $livedoor_weather_url = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=130010';
の末尾の数字を 270000
に変えることで、大阪の最高気温を出したりすることができます。
ここを変数にすると、他の地域の気温を見たいときに楽ですね。
さらに、その数字を標準入力から入れられると楽かも。
さらにさらに、Webアプリから地域を選べるようにすれば・・・となります。
そんな、Webアプリからの入出力を学べる Perl入学式 2019 第5回 in東京 お待ちしております!
perl-entrance-tokyo.connpass.com
ojo
Perl入学式 in沖縄の id:AnaTofuZ さんから教えてもらったのがこのツール。
cpanm ojo
でインストールして、コマンドラインから1行、ワンライナーです。
$ perl -Mojo -E'my $content = j g("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010")->{content}->{asset}->{content};say $content->{forecasts}->[0]->{temperature}->{max}->{celsius}'
ということで
PerlでWebにアクセスしてデータ集める方法でした。
Perl入学式 in 東京第4回でピザ会でのお題「双六」
Perl入学式 in 東京第4回でピザ会でのお題「双六」
今回の id:xtetsuji さんからのお題は双六で「あがり」までの平均何回サイコロを振れば良いか?を計算するものでした。 問題のレギュレーションは既にサポーターの id:nishiru3 さんが書いてくれております。 @nishiru3++
うちはこんな感じで解いてみました。平均6.3回振ればゴールにたどり着けそう、って感じですかね・・・
#!/usr/bin/env perl use strict; use warnings; my $number_of_trials = 1000000; # 試行回数。 # 100回とか10万回とか変えられるよう、変数に入れておく。 my $number_of_dice_rolled = 0; # サイコロを振った合計回数を格納する変数。 for ( 1 .. $number_of_trials ) { # 試行回数分繰り返す my $sum = 0; # 1試行あたりのサイコロの目の合計を初期化 while ( $sum < 10 ) { # 目の合計(双六のマスの位置)が10以下の時は繰り返す $number_of_dice_rolled++; # サイコロを振った回数 +1 する $sum += int( rand(6) + 1 ); # サイコロを振る(1〜6の目が出る) # サイコロの目の合計(双六のマスの位置)が3の倍数、かつ、 # サイコロの目の合計が10未満の時は「振り出しに戻る」 if ( $sum % 3 == 0 && $sum < 10 ) { $sum = 0; } } } print $number_of_dice_rolled / $number_of_trials;
今回のピザ会は盛況だった
他にも
- ライフゲーム
- Imger
- 並列処理
とネタが多くて、一通り書いてからブログ公開だとしばらくかかりそうだなーってことで、先にかいた双六から公開しまする。
Perl入学式 2019 in東京 第4回 お疲れ様でした
受講された方、サポーターの方、大変湿度の高い中、お疲れ様でした。
講師をやったジャージの人です。
Perl入学式第4回です。カリキュラム改定に伴い、Perl初学者には難しい(しかし避けては通れない)「リファレンス」で1回丸々使う回となりました。
講義に利用したスライドはMarkdown形式で公開しています。復習に使ってください。
また、講義中に数回言及しましたが、練習問題も骨のあるものになっています。ぜひチャレンジしてみてください!
問題の意味がわからない、とか、このような解答例はどうだろう?という方はSlackのPerl入学式チャンネル(招待フォーム)やtwitterでハッシュタグ #Perl入学式 をつけて聞いてみてください。
応答速度、監視頻度などの面からSlackの方をお勧めします。
リファレンス!
過去のエントリで大体語り尽くしてる感があるので、そちらで・・・
講義の最後にもオススメしましたが、Perlのリファレンスに関しては、完全な自信をもって深沢千尋さんの「すぐわかる オブジェクト指向 Perl」をお勧めします。
ピザ会
今日はネタが多くてちょっと後日にまとめて書く予定です。
いつもの id:xtetsuji さん出題、サイコロゲームの試行回数
Perlでお絵かき Imger
Webサイトの死活監視を並列で処理したい!AnyEvent
解決したいコード、困っているコードをプロジェクターに映し出して、いろいろとみていくの、楽しかったですね。モブプログラミングってあんな感じなのかな。
次回予告
次回は8月の後半での開催を予定しています。やるのはWebフレームワーク、Mojoliciousです。PerlとMojoliciousを通して、Webアプリケーションの骨組みとデータの流れを学習していきます。