[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
https://github.com/Shunshun94/ytsheet_sw2.5/blob/57e6656c554678ea2accbcd27e69601c0520381e/_core/lib/sw2/client-ytsheet_one_mons.pl
書いた。このコードからだと perl client-ytsheet_one_mons.pl https://yutorize.2-d.jp/ms_sw2/s/data/1579365932.htmlとすれば動く。でも、これを本体に取り込んでもらうのはちょっとむずかしい気がしてはいる。ここからどう改修したものかねぇ。
HTML::Parser について使い方がなかなか分からなかったので書いておく。
parser を提議させ、その parser の parse 関数を実行すると parse 関数に渡した html を解析してくれる。
一気に解析して木を作ってくれるわけではない。HTML を上から順番に見ていき、開始タグ、終了タグ、なんでもない文章、コメントといったものを1つ1つ見つけるごとに関数を実行する、という挙動をする。そのため、parser を定義するときは「〇〇を見つけたらこの関数を実行してね」という話をする。
上述の 開始タグ、終了タグ、なんでもない文章、コメントといったもの
を event と呼んでいる(一覧)。この各イベントに対して見つかった際に実行する関数(handler)を定義することで parser を定義するのである。後述の例は イベント名_h というのがやたら出てくるが「〇〇というイベントに対応する handler」を定義しているのである。例えば開始タグのイベントに対しては when_open_tag_found という関数を handler として割り当てている([\&when_open_tag_found, "self, tagname, attr"])。
色々渡せる(一覧)。後述の例では start には tag 名称とその要素に当てられた属性を handler に渡している([\&when_open_tag_found, "self, tagname, attr"])
use HTML::Parser ();
use LWP::UserAgent;
print "start\n";
my $browser = LWP::UserAgent->new;
my $response = $browser->get("http://shunshun94.example.com/index.html");
my $parser = HTML::Parser->new(
api_version => 3,
start_h => [\&when_open_tag_found, "self, tagname, attr"],
end_h => [\&when_close_tag_found, "self, tagname"],
text_h => [\&when_text_found, "self, text"],
comment_h => [\&when_comment_found, "self, text"]
);
$parser->parse($response->content);
print "finish!\n";
sub when_open_tag_found {
my ($self, $tagname, $attr) = @_;
print "OPEN $tagname\n";
}
sub when_close_tag_found {
my ($self, $tagname) = @_;
print "CLOSE $tagname\n";
}
sub when_text_found {
my ($self, $text) = @_;
print "TEXT $text\n";
}
sub when_comment_found {
my ($self, $text) = @_;
print "COMMENT $text";
}
もっとモジュール使えば楽、特に HTML のパースはそうなんだろうけど、さくらインターネットのレンタルサーバ ライトプランで動くことを前提に書いている。
#!/usr/bin/perl
use HTML::Parser ();
use LWP::UserAgent;
use JSON::PP;
use CGI;
use Encode;
my $cgi = CGI::new();
my $browser = LWP::UserAgent->new;
my $enc = "utf8";
print "Status: 200 OK\n";
print "Content-Type: application/json; charset=UTF-8\n\n";
my $url = $cgi->url_param('url');
my %ogps = (result => "OK");
sub when_open_tag_found {
my ($self, $tagname, $attr) = @_;
if($tagname eq 'meta' and $attr->{'property'} and $attr->{'content'} ){
$ogps{$attr->{'property'}} = Encode::decode($enc, $attr->{'content'});
}
if($tagname eq 'meta' and $attr->{'name'} and $attr->{'content'} ){
$ogps{$attr->{'name'}} = Encode::decode($enc, $attr->{'content'});
}
}
if($url) {
eval {
my $response = $browser->get($url);
$ogps{'url'} = $url;
my $parser = HTML::Parser->new(
api_version => 3,
start_h => [\&when_open_tag_found, "self, tagname, attr"]);
$parser->parse($response->content);
my $json = JSON::PP->new->utf8->space_after->encode(\%ogps);
print $json;
};
if (my $error = $@) {
$json = JSON::PP->new->utf8->space_after->encode({
result => "NG",
message => $error
});
print $json;
}
} else {
print '{"result": "NG", "message":"No URL is found in parameter"}'
}
exit;
use strict;
use LWP::UserAgent;
use JSON::PP;
my $browser = LWP::UserAgent->new;
my $json = JSON::PP->new;
sub getAccessToken {
my $code = $_[0];
my $redirect_url = $_[1];
my $oauth_scope = $_[2];
my $oauth_client_id = $_[3];
my $oauth_secret_id = $_[4];
my $token_url = "https://accounts.google.com/o/oauth2/token";
my $token_request = HTTP::Request->new(POST => $token_url);
$token_request->content_type('application/x-www-form-urlencoded');
my $body = "redirect_uri=$oauth_redirect_url&scope=$oauth_scope&client_id=$oauth_client_id&client_secret=$oauth_secret_id&grant_type=authorization_code&code=$code";
$token_request->content($body);
my $token_response = $browser->request($token_request);
my @rawResult = decode_json $token_response->content;
my $token = $rawResult[0]->{'access_token'};
return $token;
}
print getAccessToken(
"nankanankaNankaRondomeNaCodeCode9877",
"http%3A%2F%2Fsheeprogramming.iku4.com%2F",
"https://www.googleapis.com/auth/userinfo.profile%20email",
"5348789543906-o86eefe6g7clf855htsefii06cin.apps.googleusercontent.com",
"ran51Random25"
);
こんな感じでアクセストークンが取得できた。今後なんか使いそうなのでメモ。
以下で取得そのものは上手くいった。このままえいっとさくらインターネットのレンタルサーバに CGI として置いても動く。なお、チャネルの ID は 111111111111111111、取得の為に使う Bot のトークンは BOTTOKENBOTTOKENBOTTOKENBOTTOKENBOTTOKENBOTTOKEN とする。
下のコードは恐らくチャンネル ID、Bot トークン、UserAgent のサービス URL を換えれば動く。
#!/usr/bin/perl use LWP::UserAgent; my $browser = LWP::UserAgent->new; my $response = $browser->get( "https://discordapp.com/api/channels/111111111111111111/messages", "Authorization" => "Bot BOTTOKENBOTTOKENBOTTOKENBOTTOKENBOTTOKENBOTTOKEN", "User-Agent" => "DiscordBot (YOUR_SERVICE_URL, 6)" ); print "Status: 200 OK\n"; print "Content-Type: text/json\n\n"; print $response->decoded_content; exit;
いくつか見落としやすい点。まず、Authorization は Token の前に Bot という文字列が必要。詳しくは公式ドキュメント。
また、User-Agent の設定も必要。これも詳しくは公式ドキュメント。