tag:crieit.net,2005:https://crieit.net/tags/API/feed 「API」の記事 - Crieit Crieitでタグ「API」に投稿された最近の記事 2021-09-30T09:25:05+09:00 https://crieit.net/tags/API/feed tag:crieit.net,2005:PublicArticle/17693 2021-09-30T07:19:35+09:00 2021-09-30T09:25:05+09:00 https://crieit.net/posts/ProductHunt 海外進出を目指して、ProductHuntへ個人開発サービスを投稿するまでにやったこと&やった結果を全面的にシェアする <h1 id="初めて作った個人開発サービスで海外進出しようという無謀な挑戦"><a href="#%E5%88%9D%E3%82%81%E3%81%A6%E4%BD%9C%E3%81%A3%E3%81%9F%E5%80%8B%E4%BA%BA%E9%96%8B%E7%99%BA%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%A7%E6%B5%B7%E5%A4%96%E9%80%B2%E5%87%BA%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%84%E3%81%86%E7%84%A1%E8%AC%80%E3%81%AA%E6%8C%91%E6%88%A6">初めて作った個人開発サービスで海外進出しようという無謀な挑戦</a></h1> <p>以下の記事の通り、9月頭に2goというサービスを作って公開しました。サービスの詳細は以下のURLから見てもらえればと思いますが、いくつかの理由から世界での公開を元から視野に入れていました。<br /> <a href="https://crieit.net/posts/Github-Issues-2go">https://crieit.net/posts/Github-Issues-2go</a></p> <p><a href="https://crieit.now.sh/upload_images/2ccd9128457814ab80f6aa50fae47a4b615488e83f814.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/2ccd9128457814ab80f6aa50fae47a4b615488e83f814.png?mw=700" alt="スクリーンショット 2021-09-26 16.27.05.png" /></a></p> <ol> <li>英語圏のユーザーも含めたほうがサービスの規模感が大きくなる</li> <li>サービス内容が日本だけに留まらない共通の需要があると思った</li> <li>どこかで挑戦しなくてはならないのなら、ここで挑戦しようと思った(無謀)</li> </ol> <p>こういった背景があり、全てのインターフェースは英語で作ってきました。そして、MVPが9月に完成したので、日本でのアナウンスをしました。海外を意識していたので、日本での進め方はあくまでフィードバックを貰えればくらいに思っていましたが、今思えばここからが既に問題なんだなと考えられます。<br /> <a href="https://crieit.now.sh/upload_images/f1969ee50f2c22b287264f3cd5afceb8615488f2e271d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f1969ee50f2c22b287264f3cd5afceb8615488f2e271d.png?mw=700" alt="スクリーンショット 2021-09-07 3.13.35.png" /></a></p> <p>私の経験をまとめましたので、自分への戒めと今後トライされる方の参考になれば。</p> <h1 id="日本でやったことと、その結果"><a href="#%E6%97%A5%E6%9C%AC%E3%81%A7%E3%82%84%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8%E3%81%A8%E3%80%81%E3%81%9D%E3%81%AE%E7%B5%90%E6%9E%9C">日本でやったことと、その結果</a></h1> <p>日本でリリースしたときにやったことを書いていきます。</p> <h2 id="Twitterでの開発進捗の共有による露出"><a href="#Twitter%E3%81%A7%E3%81%AE%E9%96%8B%E7%99%BA%E9%80%B2%E6%8D%97%E3%81%AE%E5%85%B1%E6%9C%89%E3%81%AB%E3%82%88%E3%82%8B%E9%9C%B2%E5%87%BA">Twitterでの開発進捗の共有による露出</a></h2> <p>私のTwitterアカウントはコチラですが、元々は現在働いている会社のAwarenessを上げるために、自分自身の考えやnoteなどの記事を共有するために使っていたものでした。そのため、インフラやクラウドなどのトピックが中心のため、100強のフォロワーもそういった傾向がありました。ただし、インフラやクラウドもこれからはアプリケーションレイヤーがわかっていないと語れないなと思い、個人開発をすることで開発者の気持ちを理解していこうとしている途中でした。<br /> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/jnakajima1982">https://twitter.com/jnakajima1982</a></p> <h3 id="Twitterでの取り組み内容"><a href="#Twitter%E3%81%A7%E3%81%AE%E5%8F%96%E3%82%8A%E7%B5%84%E3%81%BF%E5%86%85%E5%AE%B9">Twitterでの取り組み内容</a></h3> <p>そのため、絶対数としてこういったアプリレイヤーに興味がある人が少ないということもあり、開発進捗を共有したとしても反応がほぼもらえないという状況が続きました。そこで、私は以下を取り組みました。<br /> 1. 「#個人開発」や「#今日の積み上げ」といったハッシュタグを使った投稿を増やした<br /> 2. 上記ハッシュタグにまつわる個人開発者を中心にフォローを増やした<br /> 3. 自分自身で話題を作るより、フォローしている人のTweetに引用RTするようにした<br />  </p> <h3 id="結果と考察"><a href="#%E7%B5%90%E6%9E%9C%E3%81%A8%E8%80%83%E5%AF%9F">結果と考察</a></h3> <p>「#個人開発」に関しては普段よりはインプレッションが増えましたが、反応が劇的に増えた感じはしませんでした。これには2つの原因があると考えています。「どんなサービスかわかりにくかった(プロフィールもわかりにくかった)」のと、「作っているサービスが英語」だったため、ハードルが高かったのだと思っています。それでも少しずつフォロワーは増え、最終的には今回の取り組みで50フォロワーくらい増えたので、コツコツやっていくことが重要で、指数関数的に上がることになるのではないかなと思っていますので、継続が必要です。</p> <p>ただし、私のアカウントが公共分野(デジタル庁など)のインフラ・クラウドと、個人開発が混ざっているので、アカウントを分けるべきか非常に迷っています。フォロワー0から作り直すリスクと、複数アカウントを運用することの大変さに応えられるのかに解がないため、一旦は1つのアカウントとしています。</p> <p><a href="https://crieit.now.sh/upload_images/89697e0fc27d4936e961e842ff9c0e1861548905416a3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/89697e0fc27d4936e961e842ff9c0e1861548905416a3.png?mw=700" alt="twitter (1).png" /></a></p> <p>また、 「#今日の積み上げ」は、インプレッションが非常に増え、リアクションも同時に増えるのですが、フォロワーが増えません。これは個人開発に留まらないユーザーが大量に流入しているせいだと思いますが、どちらかと言うとお互いに励まし合おうというハッシュタグの位置づけになっていると思われるので、このような結果になっているのだと思います。自分自身の精神安定の観点で、たまに投稿して安心するくらいが丁度いいと思っています。</p> <p>3については、私自身が有益なことをTweetすることができればいいのですが、いざTwitterの画面を開いてなにか書こうと思ったときに、思いつくことには限界があったんですよね。特に、何がウケるのかみたいなことを考えだしたのもいけなかったんだと思います。なので、フォローしている人は私が興味があってフォローしているわけで、その人が話題にしていることに対して引用RTすることにして、自分の意見を言っていこうと考えました。</p> <p>これは意外と効果があります。Twitter上での表示のされ方も、元Tweetが強ければ同時に表示されることもあります。また、何より引用RTした相手からのコメントを頂ける確率も高く、それがインプレッションの増加に繋がる結果が多かったと思います。</p> <h3 id="反省と今後"><a href="#%E5%8F%8D%E7%9C%81%E3%81%A8%E4%BB%8A%E5%BE%8C">反省と今後</a></h3> <p>いずれにしても、Twitterでの認知度向上は一朝一夕ではいきませんので継続した活動が必要ということが身に沁みました。後ほど触れますが、ProductHuntなどは、このようなフォロワーの数が少ない開発者を掘り出して世に出すためのサービスという大前提があるのですが、現実問題として規模の戦いは存在すると実感しましたので、Twitter等のSNSでコミュニティを形成する必要を感じさせられました。</p> <p>特に英語圏での情報発信を考えると、英語用Twitterアカウントを作ったのですが、日本語用Twitterアカウントだけでも苦労しているのに、英語で書いて運用していくというのはとても大変なことです。そのため、英語用Twitterアカウントはほとんど活動ができていません。</p> <h2 id="運営者ギルドへの参加"><a href="#%E9%81%8B%E5%96%B6%E8%80%85%E3%82%AE%E3%83%AB%E3%83%89%E3%81%B8%E3%81%AE%E5%8F%82%E5%8A%A0">運営者ギルドへの参加</a></h2> <p>Twitterを徘徊していると、運営者ギルドという存在を知りました。まさに私が陥っているような状況が冒頭に書かれていました。<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/organizations/admin-guild">https://qiita.com/organizations/admin-guild</a></p> <blockquote> <p>作ったWebサービス、全然使われない……<br /> どうやってマネタイズしよう<br /> どこまで作り込んでからリリースすればいいんだろう<br /> デザイン難しすぎ<br /> 利用規約はどうすれば?<br /> この先どうやってサービスを伸ばしていけばいいのか……<br /> Slackでの運営形態になっており、中の活動が全く見えなかったので、入れていただくかを非常に悩んだのですが、何事もチャレンジだと思ったので、連絡させて頂き、無事入らせて頂きました。</p> </blockquote> <p><a href="https://crieit.now.sh/upload_images/9a13068ab299538fc8dcc14cfa4026f4615489143c8f5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9a13068ab299538fc8dcc14cfa4026f4615489143c8f5.png?mw=700" alt="image (28).png" /></a></p> <h3 id="結果と考察"><a href="#%E7%B5%90%E6%9E%9C%E3%81%A8%E8%80%83%E5%AF%9F">結果と考察</a></h3> <p>結果から言うと、個人開発をしている人は入ったほうが良いです。下手な質問をしたら、ぶっ飛ばされるのではないかとビクビクしていましたが、そんな事は全くありませんでした。唯一あるとするならば、自分自身で発信したことには多くの意見がもらえてモチベーションに繋がりますが、自分自身で発信しない方はここで何をしていいかわからなくなってしまうと思います。</p> <p>私は、実運用ではどのようにしているかなどは、こういった限定されたユーザーだけが参加するコミュニティだからこそ聞ける生の声が本当に貴重だと思いました。また、今回のProductHuntのチャレンジなどを好意的に捉えてくださるだけでなく、普段の自分自身の開発の進捗にコメントいただける方もいらっしゃり、個人開発の課題となりがちなモチベーション維持にもなりました。</p> <p>だからこそ、私自身がコミュニティの一部として、他の方が同様な状況にいる場合には、積極的に自分の経験を還元する必要があると思い、いろいろな方のチャンネルに入るようにしました。</p> <h2 id="技術コミュニティメディアへのサービス開発記事の投稿"><a href="#%E6%8A%80%E8%A1%93%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%83%86%E3%82%A3%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2%E3%81%B8%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E9%96%8B%E7%99%BA%E8%A8%98%E4%BA%8B%E3%81%AE%E6%8A%95%E7%A8%BF">技術コミュニティメディアへのサービス開発記事の投稿</a></h2> <p>Twitterや運営者ギルド以外では、とにかくサービスを知ってもらえるチャネルを増やそうとしていました。そこで以下の技術コミュニティメディアに記事を投稿してみました。<br /> - Zenn:https://zenn.dev/nice2have/articles/aa15eccd13a23c<br /> - Qiita:https://qiita.com/nice2have/items/28449ae4ef45fef2c671<br /> - Crieit: https://crieit.net/posts/Github-Issues-2go<br /> - ツクログ:https://creators.eightbit.jp/service/item4309.html</p> <p>以下にそれぞれのメディアの現時点での結果をまとめます(Google Analytics調べ)。Zennは正直きちんと取れているのかわかりません。ツクログは投稿して間もないのと、どこからデータが取れるのかわからずなので、外しています。<br /> <div class="table-responsive"><table> <thead> <tr> <th>メディア</th> <th>記事閲覧数</th> <th>サービス流入数</th> <th>LGTM</th> </tr> </thead> <tbody> <tr> <td>Zenn</td> <td>34</td> <td>10</td> <td>4</td> </tr> <tr> <td>Qiita</td> <td>1468</td> <td>261</td> <td>7</td> </tr> <tr> <td>Crieit</td> <td>1198</td> <td>66</td> <td>1</td> </tr> </tbody> </table></div></p> <h3 id="結果と考察"><a href="#%E7%B5%90%E6%9E%9C%E3%81%A8%E8%80%83%E5%AF%9F">結果と考察</a></h3> <p>いずれにせよ、どのメディアにも投稿することは確実に認知度とサービス流入に繋がっていると言えますので、サービスローンチのタイミングだけでなく、書く内容がある限り、投稿し続けると良いと思います、、、が、やっぱり書くのって大変なんですよね。さらに、メディアによってトレンドがあるから、書く内容を変えたほうがよいというのを見たのですが、全く同じ記事を上げているのが現状です。まずは続けることが大事なので、しばらくはそれを継続しようと思っています。</p> <h3 id="ダイレクトアプローチ"><a href="#%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88%E3%82%A2%E3%83%97%E3%83%AD%E3%83%BC%E3%83%81">ダイレクトアプローチ</a></h3> <p><a href="https://crieit.now.sh/upload_images/d3971adefd981bac418520bb891203cb61548925cc9ef.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d3971adefd981bac418520bb891203cb61548925cc9ef.png?mw=700" alt="lp_issues.png" /></a><br /> 追加でした作業についても記録しておきます。2goというサービスの特性上、Github Issueを利用している/利用見込みのユーザーがターゲットになります。そのため、メディア上にGithub Issueについて記事を書いている人へ直接連絡して実際に利用していただくことで、フィードバックを受けて改善に生かしていこうと思いました。</p> <p>Google検索からたどり着いた5件にコメントをしてコミュニケーションを図ってみたのですが、どこからも未だ返事がない状況です。Twitter上でキーワード検索してアプローチしたこともありましたが、ちょっと利用用途が異なったようで、試してもらうまでに至りませんでした。</p> <p>以上のアプローチで、面白いですとか、良いサービスですねなど言われるものの、今思えば、やはり利用されるだけの魅力やユースケースが見出してもらえなかったのだと思いました。</p> <h2 id="まとめ:日本での取り組み"><a href="#%E3%81%BE%E3%81%A8%E3%82%81%EF%BC%9A%E6%97%A5%E6%9C%AC%E3%81%A7%E3%81%AE%E5%8F%96%E3%82%8A%E7%B5%84%E3%81%BF">まとめ:日本での取り組み</a></h2> <p>海外進出を前提に置いていたため、以下の2点の理由で、Githubアカウントでログインしてまで試してくれた人は、2桁にすら行きませんでした。<br /> - 日本での取り組みを正直本気で取り組んだとは言えない<br /> - 英語のインターフェースのため、伝わりづらかった</p> <p>そこで、Githubアカウントでログインすることのハードルが高いと思い、ログイン不要で誰にでも触れるサンプルを追加開発して提供してみたのですが、こちらも時たま試す人が現れるくらいで、試すことすらしてもらえないのかと打ちひしがれましたorz</p> <p>ほとんどのユーザーアクティビティ(サービス登録/ログイン/公開設定)が発生すると、Slackに通知が飛んでくるようにしていたのですが、たまにしか飛んでこず、こちらも現時点では自分のログイン動作だけが通知される閑古鳥が鳴いている状態です。</p> <h1 id="海外編:Product Hunt"><a href="#%E6%B5%B7%E5%A4%96%E7%B7%A8%EF%BC%9AProduct+Hunt">海外編:Product Hunt</a></h1> <p>つらつらと書いてきましたが、これからが本編です。当時、海外進出しか見えていなかった私は、海外での認知度を上げるための方策を調査していました。調べていくと以下の2つのサービスがマッチすると思いました。</p> <ol> <li>Product Hunt : https://www.producthunt.com/</li> <li>Indie Hackers : https://www.indiehackers.com/</li> </ol> <p>これらのサービスでは、個人開発者やスタートアップが自分の作ったプロダクトを投稿して、認知度を上げることが毎日のように行われています。ただ、Indie Hackersの方は招待制でしか入れず、Redditなどを徘徊してもInvitation Codeを求める人はいるものの、なかなか何もない状態でそれがもらえる人は見られなかったので、一旦Product Huntにフォーカスすることに決めました。</p> <h2 id="Product Huntへの投稿を決心"><a href="#Product+Hunt%E3%81%B8%E3%81%AE%E6%8A%95%E7%A8%BF%E3%82%92%E6%B1%BA%E5%BF%83">Product Huntへの投稿を決心</a></h2> <p>まずは経験者のまとめを読み漁りました。具体的には以下の記事を読みました。この中でも、本当に有効だったこと、今では有効ではないこと、役に立たないことがあるので、それを自分なりに整理していきました。とにかくやれることはやりきらないと、次につながらないと思い計画していきました。</p> <p><a href="https://crieit.net/posts/7">https://crieit.net/posts/7</a><br /> <a target="_blank" rel="nofollow noopener" href="https://jp.taishikato.com/posts/i-want-to-prove-that-japanese-can-compete-in-english-speaking-countries">https://jp.taishikato.com/posts/i-want-to-prove-that-japanese-can-compete-in-english-speaking-countries</a><br /> <a target="_blank" rel="nofollow noopener" href="https://blog.notsobad.jp/entry/2019/12/23/232807">https://blog.notsobad.jp/entry/2019/12/23/232807</a><br /> <a target="_blank" rel="nofollow noopener" href="https://blog.notsobad.jp/entry/bungo-search-product-hunt">https://blog.notsobad.jp/entry/bungo-search-product-hunt</a></p> <h3 id="Product Hunt攻略計画"><a href="#Product+Hunt%E6%94%BB%E7%95%A5%E8%A8%88%E7%94%BB">Product Hunt攻略計画</a></h3> <p>先述の記事を読んで私が立てた当日の計画は以下のとおりです。<br /> 1. 太平洋時間 0:01(日本時間 16:01)からその日のランキングレース開始。<br /> 2. 1時間くらい様子をみて、Google や Facebook からのプロダクトなどのビッグサービスが投稿されていないのを確認してから投稿。<br /> 3. Twitter で Product Hunt への投稿を英語でアナウンス。 @ProductHuntをメンションする。<br /> 4. Product Hunt 上の紹介ページ URL が取得できるので、それを基に Product Hunt Card 作成(Medium の場合は URL を貼り付けるだけで OK)し、Medium 投稿。<br /> 5. ProductHunt の URL を使って Landing Page に反映し、導線を作る。<br /> 6. Medium の記事を、Product Hunt 上のプロダクト紹介ページに関連記事として貼り付け。<br /> 7. Medium の記事を、Hacker News に投稿(Show HN:をタイトルにつけて投稿)<br /> 8. Reddit に投稿<br /> 9. コメントが入ったらそれに返信していく。</p> <p>また、投稿当日までの計画は以下のとおりです。<br /> 1. 投稿用のランディングページを作る<br /> 2. 投稿用の動画(英語)を作る<br /> 3. Medium/HackersNews/Redditの記事を準備する<br /> 4. Product Huntのupcoming Productに登録する<br /> 5. Product Hunt投稿内容の準備をする<br /> 6. 最低限必要な機能の整備(退会機能・規約)<br /> 7. 著名なProduct HuntersにReview Requestをして、認知してもらう</p> <p>簡単に言ってしまうと、以下の2点に集約されます。すごくシンプルです。<br /> - ProductHuntの投稿を魅力的なものにする<br /> - ProductHuntのupvoteを得るための導線をできるだけ多く作る</p> <h4 id="投稿当日までの準備と結果"><a href="#%E6%8A%95%E7%A8%BF%E5%BD%93%E6%97%A5%E3%81%BE%E3%81%A7%E3%81%AE%E6%BA%96%E5%82%99%E3%81%A8%E7%B5%90%E6%9E%9C">投稿当日までの準備と結果</a></h4> <p>順番は前後しますが、投稿当日までの計画について共有します。</p> <h5 id="ランディングページ"><a href="#%E3%83%A9%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%9A%E3%83%BC%E3%82%B8">ランディングページ</a></h5> <p>ランディングページはたいして手間もかからなかったのですが、当日投稿しなければ、貼るURLがわからないため、ボタンだけ作ってVueの機能で表示しない状態で準備しておきました。実際のトップページの見えるところにボタンを置いた程度でした。はっきり言ってダサいですね。<br /> <a href="https://crieit.now.sh/upload_images/a66b3274000d3cb3eea1c45bdc3c27aa6154893919d2d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a66b3274000d3cb3eea1c45bdc3c27aa6154893919d2d.png?mw=700" alt="image (27).png" /></a></p> <p>改めて投稿後にいろいろ研究してみましたが、以下のような形で誘導するのはとても有効だと感じました。後にわかりますが、こんなレベルの問題ではないことがわかります。<br /> <a href="https://crieit.now.sh/upload_images/55b3b19e99f9362c582a1295c888addd61548947627a7.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/55b3b19e99f9362c582a1295c888addd61548947627a7.png?mw=700" alt="image (26).png" /></a></p> <hr /> <h5 id="投稿用の動画"><a href="#%E6%8A%95%E7%A8%BF%E7%94%A8%E3%81%AE%E5%8B%95%E7%94%BB">投稿用の動画</a></h5> <p>ProductHuntの投稿にYoutube動画を付けると、Product紹介の一番最初に表示され、自動的に再生される仕組みになっています。そのため、インパクトがあると思ったのと、これをやらねばやらなかったときの効果が今後わからなくなると思い、動画制作に手を付け始めました。しかしながら、以下の問題にぶつかります。</p> <ul> <li>動画編集に知見がない</li> <li>動画ナレーションは英語の必要性がある</li> </ul> <p>動画編集に知見がないので、いろいろ調べたところ、ダビンチリゾルブという動画編集ソフトが良さそうで試してみたところ、操作が全くわからず、説明記事をウロウロしていたのですが、わからなすぎて挫折しそうになっていました。ところが、原点に戻って動画のことは動画で、と思ってYoutubeの解説動画を探しました。</p> <p>そして以下の動画を10分で見たら、一気に進み、こんな私でも動画編集ができるようになりました。基本操作と、動画編集に最低限必要そうな動画を紹介しておきます。</p> <p><a target="_blank" rel="nofollow noopener" href="https://youtu.be/duxtN8ixpLo">https://youtu.be/duxtN8ixpLo</a><br /> <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=0J7lqAnP_64&t=194s">https://www.youtube.com/watch?v=0J7lqAnP_64&t=194s</a></p> <p>ただ、計画もなしに動画編集するとうまく行かなったので、Figmaで整理してみました。ただし、これで一旦動画を作ったのですが、文字だらけでなかなか理解しにくいものになってしまいました。<br /> <a href="https://crieit.now.sh/upload_images/7ef5b8ff4b8585d89aea6aae136e0560615488982a3bd.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7ef5b8ff4b8585d89aea6aae136e0560615488982a3bd.png?mw=700" alt="image (25).png" /></a></p> <p>ここあら紆余曲折があって、ようやく完成した最終版はコチラです。<br /> <a target="_blank" rel="nofollow noopener" href="https://youtu.be/YvcyiAccCBo">https://youtu.be/YvcyiAccCBo</a></p> <p>先にナレーションの英文を考えて、Google Text to Speechに喋らせて、それに合わせて映像を作成するという手順を踏みました。しかしながら、結果的に動画以前の問題であることも発覚します。<br /> <a href="https://crieit.now.sh/upload_images/1854cd2cbe6840ac117d5ae95762703d615488842c9e4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1854cd2cbe6840ac117d5ae95762703d615488842c9e4.png?mw=700" alt="image (24).png" /></a></p> <h5 id="Medium/HackersNews/Redditの記事を準備する"><a href="#Medium%2FHackersNews%2FReddit%E3%81%AE%E8%A8%98%E4%BA%8B%E3%82%92%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B">Medium/HackersNews/Redditの記事を準備する</a></h5> <p>ここから導線となる記事の準備についてお話しいたします。</p> <p><strong>Medium</strong><br /> <a target="_blank" rel="nofollow noopener" href="https://medium.com/@nice2have/2go-road-to-my-first-webservice-5b38666a7dd8">https://medium.com/@nice2have/2go-road-to-my-first-webservice-5b38666a7dd8</a><br /> <a href="https://crieit.now.sh/upload_images/c76742bc401d73b46336fe6b13cfa4c161548878085d9.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c76742bc401d73b46336fe6b13cfa4c161548878085d9.png?mw=700" alt="image (23).png" /></a><br /> - 特に制限もないので、自由に書きましたが、タグについては迷いましたね。サービスの特性上、割り当てるべき適切なタグかどれか未だにわかっていません。<br /> - しかしながら現時点でもView数は2です。そのため、こちらもMediumのフォロワーを増やしておくか、単なるプロダクト説明の置き場と割り切るかのどちらかが今後の戦略となりそうです。<br /> <a href="https://crieit.now.sh/upload_images/36006e156388e53b6d55afc31fa83f0a6154883e1dcc6.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/36006e156388e53b6d55afc31fa83f0a6154883e1dcc6.png?mw=700" alt="image (22).png" /></a></p> <hr /> <p><strong>HackersNews</strong><br /> <a href="https://crieit.now.sh/upload_images/1be5ea94b6dfb0a28f3b04305009befe6154880ca815b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1be5ea94b6dfb0a28f3b04305009befe6154880ca815b.png?mw=700" alt="image (21).png" /></a><br /> - Show HNを付けるというルールを守って投稿<br /> - 付けるURLはMediumのページか、サービス自体のURLかは迷いましたが、サービスにProductHuntへの誘導を用意していたので、後者を選択しました。<br /> - しかし残念ながら、GoogleAnalytics上は、HackersNewsからの流入は0でしたので、もう少し工夫が必要か、流れるのが早すぎて流入が期待できないかもしれません。</p> <hr /> <p><strong>Reddit</strong><br /> <a target="_blank" rel="nofollow noopener" href="https://www.reddit.com/r/ProductHunters/comments/px15lq/i_created_my_first_web_site_2go_2go_can_generate/">https://www.reddit.com/r/ProductHunters/comments/px15lq/i_created_my_first_web_site_2go_2go_can_generate/</a><br /> <a href="https://crieit.now.sh/upload_images/210f64e0ce8b159071e2738e1bd35776615487f13bade.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/210f64e0ce8b159071e2738e1bd35776615487f13bade.png?mw=700" alt="image (20).png" /></a><br /> - Karmaというポイントがないと記事が投稿できないという話を見たので、事前に記事投稿やコメントで参加してみました。特にGithub Issueの必要性などを投稿したりして、反応を窺うなどもトライしましたが、慣れていないせいもあって反応も薄かったです。<br /> - どのSubredditに投稿するかは検討しました。ProductHunt / Github / webdev / SaaS / startups / indieHackers / indieDevelopers等、色々調査しました。ProductHuntのSubredditが最も適切かと思いましたが、あまり活況がないのが心配でした。ただ、それ以外のところでは厳しい反応も予想されたので、シンプルにProductHuntのSubredditを投稿先と決定しました。<br /> - その他細かいことですが、RedditのProfileなどもきちんと整備しました。<br /> - しかしながら、RedditのSpamFilterに引っかかって削除されてしまったみたいです…</p> <hr /> <h5 id="Product Huntのupcoming Product"><a href="#Product+Hunt%E3%81%AEupcoming+Product">Product Huntのupcoming Product</a></h5> <p>あまり認知されていませんが、以下のようにサービスローンチ前にユーザーとコミュニケーションができるPre-Postサイトを作ることが出来ます。ただここからSubsriberは1人も登録されませんでした。おそらくProductHuntの著名なユーザーが、次期サービスを立ち上げる前にユーザーとコミュニケーションするためのプラットフォームだと感じましたので、私には当分必要ないと思いました。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.producthunt.com/upcoming/2go">https://www.producthunt.com/upcoming/2go</a></p> <hr /> <h6 id="Product Hunt投稿内容の準備をする"><a href="#Product+Hunt%E6%8A%95%E7%A8%BF%E5%86%85%E5%AE%B9%E3%81%AE%E6%BA%96%E5%82%99%E3%82%92%E3%81%99%E3%82%8B">Product Hunt投稿内容の準備をする</a></h6> <p><a href="https://crieit.now.sh/upload_images/76ebfc15ab748145d665f1c4a4986b7e615487ca134e3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/76ebfc15ab748145d665f1c4a4986b7e615487ca134e3.png?mw=700" alt="image (19).png" /></a><br /> Product Huntの投稿ページは入力したものが記録されるようになっているので、Submitボタンの直前までを入力しておいて事前に準備しておくことが可能です。今回の画像は、動画作成時に作っていたFigmaデータを画像データに変換して利用することとしました。特に動画は視覚的に、画像は落ち着いて読むように文字を入れるようにしました。</p> <p><a href="https://crieit.now.sh/upload_images/7c82e16b607550ccb13639965cdedb976154879728e68.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7c82e16b607550ccb13639965cdedb976154879728e68.png?mw=700" alt="スクリーンショット 2021-09-26 16.20.56.png" /></a><br /> <a href="https://crieit.now.sh/upload_images/51240628b6d64bac3d7d4b51f2ba477e615487a283dfe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/51240628b6d64bac3d7d4b51f2ba477e615487a283dfe.png?mw=700" alt="スクリーンショット 2021-09-26 16.03.43.png" /></a><br /> <a href="https://crieit.now.sh/upload_images/4cb7adb70db8bd9afc4ec8e3c63bc1ed615487a8a64c5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/4cb7adb70db8bd9afc4ec8e3c63bc1ed615487a8a64c5.png?mw=700" alt="スクリーンショット 2021-09-26 16.04.35.png" /></a><br /> <a href="https://crieit.now.sh/upload_images/4937eca85eebe0d18e1ce6a5b2637f91615487ae2d3bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/4937eca85eebe0d18e1ce6a5b2637f91615487ae2d3bc.png?mw=700" alt="スクリーンショット 2021-09-26 16.04.11.png" /></a><br /> ここで用意しにくいのは、投稿ロゴとして利用できるGIFファイルだと思います。動画や画像イメージは比較的簡単に用意できますが、GIFファイルはどんなものにするところから微妙に悩ましい位置づけです。私は今回動画ファイルを作って出力した後、MovファイルからGIFに変換して利用しました。<br /> <a href="https://crieit.now.sh/upload_images/07acf05940475d852b84873e9766827461548726e8258.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/07acf05940475d852b84873e9766827461548726e8258.gif?mw=700" alt="titleGIF.gif" /></a><br /> 目立たせるために、アニメーションというよりは、全体の色が大きく変わることで目につくように意識して作りました。</p> <hr /> <h5 id="著名なProduct HuntersにReview Request"><a href="#%E8%91%97%E5%90%8D%E3%81%AAProduct+Hunters%E3%81%ABReview+Request">著名なProduct HuntersにReview Request</a></h5> <p>先程の記事の中には著名なProductHunterにお願いして、彼らに周知してProductHuntで彼らをフォローしているユーザーに通知されるようにしたほうが良いという記述がありました。一方で、その機能はなくなったのでやる必要ないよというのも見受けられました。ということは、やってみるしかありません。まずは以下のサイトからTop Huntersを探しました。</p> <p><a target="_blank" rel="nofollow noopener" href="https://yvoschaap.com/producthunt/">https://yvoschaap.com/producthunt/</a></p> <p>それぞれがどういった方なのかまで抑えられなかったので、上から順番にTwitterを見て、直接DMを送れる人にていねいな英文を書いて送りました。…が、結果的に1人からも返信は返ってきませんでした。おそらく、こういった依頼が定常的に来るので、そもそもDMを開いていない可能性が高いです。既読にすらなりませんでしたので。</p> <p>では、このアプローチは不要なんでしょうか。その答えは、私のProductHuntの通知ページにありました。以下のようにフォローしているHunterがUpvoteすると、その通知がフォロワーには届きます。つまり、TopHuntersにUpvoteされると知られる確率が高くなるという理解をしています。ただ、彼らからUpvoteされるためにどうしたらよいかは未だにわかりません。Twitterでフォローされるわけもないので、ProductHuntでDiscussionに参加するなどして自分自身の露出が必要なのかもしれません。</p> <p><a href="https://crieit.now.sh/upload_images/93dd81709da263bd35dc9bdcde62bc5b615486ed95e33.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/93dd81709da263bd35dc9bdcde62bc5b615486ed95e33.png?mw=700" alt="tophunters.png" /></a></p> <p>その他に可能性があるとすると、以下は検討してみてもよいかと思いました。開発者のクローズドなコミュニティがあり、そこで繋がりが作れるかもしれません。なぜなら、$2,000/yearの有料会員制だからです。だからこそ、人数が爆発的に多いわけでもないですし、コミュニケーションが活発なのかもしれません。ただし、個人開発者がここに投資するのは、英語とお金が必要なので、ハードルが高いとは思います。</p> <p><a target="_blank" rel="nofollow noopener" href="https://megamaker.co/club/">https://megamaker.co/club/</a></p> <hr /> <h4 id="投稿当日の結果"><a href="#%E6%8A%95%E7%A8%BF%E5%BD%93%E6%97%A5%E3%81%AE%E7%B5%90%E6%9E%9C">投稿当日の結果</a></h4> <p>改めて、投稿当日の計画を振り返る前に、投稿曜日を検討していました。最初は準備ができた翌日に投稿しようかと思っていましたが、ちょうど週末でした。週末がどう影響するかがわからず、Active User数が減少するのではないかと推測して候補から外しました。また、週明けの月曜日も同様の理由で除外し、現地時間火曜日0時に投稿することとしました。</p> <ol> <li>太平洋時間 0:01(日本時間 16:01)からその日のランキングレース開始。</li> <li>1時間くらい様子をみて、Google や Facebook からのプロダクトなどのビッグサービスが投稿されていないのを確認してから投稿。</li> <li>Twitter で Product Hunt への投稿を英語でアナウンス。 @ProductHuntをメンションする。</li> <li>Product Hunt 上の紹介ページ URL が取得できるので、それを基に Product Hunt Card 作成(Medium の場合は URL を貼り付けるだけで OK)し、Medium 投稿。</li> <li>ProductHunt の URL を使って Landing Page に反映し、導線を作る。</li> <li>Medium の記事を、Product Hunt 上のプロダクト紹介ページに関連記事として貼り付け。</li> <li>Medium の記事を、Hacker News に投稿(Show HN:をタイトルにつけて投稿)</li> <li>Reddit に投稿</li> <li>コメントが入ったらそれに返信していく</li> </ol> <p>まず、予約投稿機能があるので、試してみましたが、正常に動作しませんでした。もしかすると私の現地時間の入力時間が間違っているかもしれませんが、念の為日本時間16時にはPCの前にいたほうがいいかもしれません。</p> <hr /> <h5 id="投稿後の動きの感想"><a href="#%E6%8A%95%E7%A8%BF%E5%BE%8C%E3%81%AE%E5%8B%95%E3%81%8D%E3%81%AE%E6%84%9F%E6%83%B3">投稿後の動きの感想</a></h5> <ul> <li>現地時間0時のタイミングでは、少しでもUpvoteを稼いだProductが上位に行きやすいです。そのため、初速を確保する知り合いやコミュニティへの事前声掛けは重要だと思いました(ただし、Upvoteを直接的に促してはいけません)</li> <li>必要初速Upvoteは10くらいだと思います。トップページに表示できるProductにも限りがあり、そこに載れなければ閲覧数も獲得できないです。</li> <li>必ずUpvote順にソートされるわけではありませんでした。コメントなどの他の要素も見ていると思われます。コメントはUpvote同様に初速に影響する可能性があるので、できれば事前に確保しておきたいところです。ただし、日本人のコミュニティにおいて、Upvoteはしてくれても、コメントまでしてくれる人を確保するのは至難の業だと思います。</li> <li>コメントがないと盛り上がりに欠けるのか、追加のコメントが得られにくいと思います。私はただの1つもコメントを最後まで得られませんでした。他のProductは、共同開発者などがコメントし合うことで盛り上がりを演出している印象を受けました。</li> <li>コメントが来たら返信しながら、投稿スレッドを盛り上げる準備をして待っていましたが、杞憂に終わってしまいました。</li> </ul> <hr /> <h5 id="結果と感想"><a href="#%E7%B5%90%E6%9E%9C%E3%81%A8%E6%84%9F%E6%83%B3">結果と感想</a></h5> <p><a href="https://crieit.now.sh/upload_images/74934dd4ad26684204b3a8d132c39ae6615486b229512.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/74934dd4ad26684204b3a8d132c39ae6615486b229512.png?mw=700" alt="スクリーンショット 2021-09-29 17.18.24.png" /></a></p> <p>最終的な結果はUpvote x15となりました。結果をまとめていきます。<br /> - Upvote x15(しかし、運営者ギルドから半数くらいはUpvoteしてくれた方がいたと思います)<br /> - 流入トラフィック x5(ほとんど流入が見込めませんでした)<br /> - 新規登録ユーザー数 x0(残念ながら一人も使ってくれませんでした)<br /> - サンプルを試したユーザー数 x2(流入トラフィックの割に確率が高かった)</p> <p>重要なのは…</p> <ul> <li>とにかく初速Upvoteを増やして、トップページに載らないと何も始まらない</li> <li>流入さえしてくれれば試してもらえる率はそこそこある</li> <li>投稿内容(文章・動画・画像)の良し悪しが影響するのかはわからなかった</li> <li>導線はほとんど影響しなかった(影響するように仕立て上げるには継続的な活動が必要)</li> <li>TopHuntersに認知される方法があれば、Upvoteを得るための近道になるかも。</li> </ul> <h2 id="ProductHuntへの挑戦は惨敗"><a href="#ProductHunt%E3%81%B8%E3%81%AE%E6%8C%91%E6%88%A6%E3%81%AF%E6%83%A8%E6%95%97">ProductHuntへの挑戦は惨敗</a></h2> <p>多くの方にご協力を頂きましたが、残念ながら私の個人開発サービスのProductHunt挑戦は惨敗に終わったと言って良いでしょう。ただし、考えうる限りのことはやり切ったので、次に繋がる敗戦だと考えています。</p> <p>海外進出のサービスの難しさを以下の点で痛感しています。<br /> - 海外でウケるサービスとかユースケースが、真の意味で理解できない可能性<br /> - 海外で求められるデザインやマーケティング・言い回しが適切かどうかわからない<br /> - 海外でのコミュニティ参加は更に負荷がかかるため、労力に見合うかが不安<br /> - 番外編)ユーザーに提供する規約の英文精査が難しい</p> <p>英語で開発すれば、非常に多くのユーザーに対する市場へのアプローチが可能ですが、このような深刻な悩みがついてまわることになります。いくつかの記事にもありましたが、英語圏の感覚を持つ人にヘルプしてもらわないと難しいかもしれません。</p> <h1 id="最後に…"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB%E2%80%A6">最後に…</a></h1> <p>想像してよりもずっとずっと個人開発は難しいです。プログラミングの世界だけでなく、デザイン・マーケティングまで1人で取り組まなければならず、かつアイデアの捻出とその中からの選定も全部自分の責任です。だからこそ楽しみがあるわけですが、大変さも同時に存在しています。</p> <p>企業よりも個人開発が気楽な分、企業よりもマーケティングや作業分担にお金がかけられません。特に個人開発はサービスが知られることがなければ、提供するユースケースが知られていないから失敗しているのか、知られていても失敗しているのか判断が難しくなります。</p> <p>そこでやはり重要となってくるのが、コミュニティだと思います。自分の作るプロダクトに意見を言ってくれる、試してみてくれる、拡散して届けてくれる人たちとともに歩まねば成功はあり得ません。そしてそれは継続的な努力によってのみ得られるものだと感じました。</p> <p>私にとって今回の開発は本当に作りたいものに対する準備の意味合いも兼ねていますが、コミュニティとともにモチベーションを維持し、成功の模索をしていきたいと思います。</p> <p>ということで、ぜひ気になる方はTwitterのフォローと、2goの利用をしてみて、フィードバックをいただければと思いますので、最後にリンクを貼って終わりにさせていただきます。</p> <p><a target="_blank" rel="nofollow noopener" href="https://twitter.com/jnakajima1982">https://twitter.com/jnakajima1982</a><br /> <a target="_blank" rel="nofollow noopener" href="https://2go.plus/">https://2go.plus/</a></p> <p>ありがとうございました!</p> jnakajima1982 tag:crieit.net,2005:PublicArticle/17538 2021-07-25T00:48:24+09:00 2021-07-26T11:27:01+09:00 https://crieit.net/posts/RESTful-API RESTful APIとは <h1 id="RESTful APIとは何?"><a href="#RESTful+API%E3%81%A8%E3%81%AF%E4%BD%95%EF%BC%9F">RESTful APIとは何?</a></h1> <p>RESTというだけあって、休みまくりのAPI。かと思ってたら全然違いました(汗)</p> <p>RESTは、<strong>REpresentational State Transfer</strong>の略。<br /> 分散型システムを設計するための構造</p> <p>APIなので、複数のアプリケーションを連携できる。twitterなど。</p> <h2 id="RESTの特徴"><a href="#REST%E3%81%AE%E7%89%B9%E5%BE%B4">RESTの特徴</a></h2> <h3 id="ステートレス"><a href="#%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%AC%E3%82%B9">ステートレス</a></h3> <p>状態を管理しないので、入力の内容によってのみ出力が決定される。</p> <h3 id="アドレス可能性"><a href="#%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E5%8F%AF%E8%83%BD%E6%80%A7">アドレス可能性</a></h3> <p>URIで表現される。一目でなんの情報かがわかる。</p> <h3 id="接続性"><a href="#%E6%8E%A5%E7%B6%9A%E6%80%A7">接続性</a></h3> <p>別の情報へのリンクを貼ることができる</p> <h3 id="統一インターフェース"><a href="#%E7%B5%B1%E4%B8%80%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9">統一インターフェース</a></h3> <p>操作は全てがHTTPで動く<br /> 取得「GET」、作成「POST」、更新「PUT」、削除「DELETE」</p> <h3 id="DNA CENTERでの使われ方"><a href="#DNA+CENTER%E3%81%A7%E3%81%AE%E4%BD%BF%E3%82%8F%E3%82%8C%E6%96%B9">DNA CENTERでの使われ方</a></h3> <p>自作プログラムを作って、Cisco DNA centerで使える機能を拡張することができる。</p> skyms tag:crieit.net,2005:PublicArticle/15750 2020-03-07T17:25:02+09:00 2020-03-07T17:25:02+09:00 https://crieit.net/posts/PAAPI-v5-Node-js PAAPI v5に移行してみた: Node.js版 <p><a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>でAmazonのPAAPIを使っているけど、<br /> v4が2020年3月9日に利用できなくなるため、移行してみたときの備忘録。</p> <p><a href="https://crieit.now.sh/upload_images/e5449de49d37c0a93ce3ada90eb537335e635a1adaf4b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e5449de49d37c0a93ce3ada90eb537335e635a1adaf4b.png?mw=700" alt="スクリーンショット 2020-03-07 17.12.50.png" /></a></p> <p>以前は、<a target="_blank" rel="nofollow noopener" href="https://github.com/dmcquay/node-apac">node-apac</a>を使ってたけど、<a target="_blank" rel="nofollow noopener" href="https://github.com/dmcquay/node-apac/issues/97">対応はなさそう</a>。</p> <h2 id="Amazon側の移行手順"><a href="#Amazon%E5%81%B4%E3%81%AE%E7%A7%BB%E8%A1%8C%E6%89%8B%E9%A0%86">Amazon側の移行手順</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://affiliate.amazon.co.jp/help/node/topic/GZH32YX29UH5GACM">公式の移行手順</a>を参考に進める感じ。</p> <h3 id="ステップ1: 新しい認証情報を取得する"><a href="#%E3%82%B9%E3%83%86%E3%83%83%E3%83%971%EF%BC%9A+%E6%96%B0%E3%81%97%E3%81%84%E8%AA%8D%E8%A8%BC%E6%83%85%E5%A0%B1%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B">ステップ1: 新しい認証情報を取得する</a></h3> <p>認証情報の形式が古いと払い出しが必要らしい<br /> いままで使っていたアクセスキーとシークレットキーでOKだったのでスキップ</p> <h3 id="ステップ2: PA-API 5.0を試してみる"><a href="#%E3%82%B9%E3%83%86%E3%83%83%E3%83%972%EF%BC%9A+PA-API+5.0%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">ステップ2: PA-API 5.0を試してみる</a></h3> <p>以前と同様、Scratchpadが用意されている。<br /> アクセスキーがOKだったかも、ここで確認した。<br /> ・<a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/scratchpad/index.html">Product Advertising API 5.0 Scratchpad</a></p> <h3 id="ステップ3: 必要な知識を得る"><a href="#%E3%82%B9%E3%83%86%E3%83%83%E3%83%973%EF%BC%9A+%E5%BF%85%E8%A6%81%E3%81%AA%E7%9F%A5%E8%AD%98%E3%82%92%E5%BE%97%E3%82%8B">ステップ3: 必要な知識を得る</a></h3> <p>公式ドキュメントにも書いてあるとおり、レスポンスがXMLからJSONになったらしい。</p> <p>変更点は、<a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/migration-guide/whats-new-in-paapi5.html">ここ</a>にまとまっている。<br /> 主には、セキュリティ強化、レスポンス速度の改善、新しいAPIの追加など。</p> <p>また、レスポンスに関してv4からv5へのマッピングも用意されてる。<br /> ・<a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/migration-guide/pa-api-40-to-50-mapping.html">PA-API 4.0 to 5.0 Mapping · Product Advertising API 5.0</a></p> <h3 id="ステップ4: PA-API 5.0を導入する"><a href="#%E3%82%B9%E3%83%86%E3%83%83%E3%83%974%EF%BC%9A+PA-API+5.0%E3%82%92%E5%B0%8E%E5%85%A5%E3%81%99%E3%82%8B">ステップ4: PA-API 5.0を導入する</a></h3> <p>従来どおり、Web APIを直接叩けるけど、SDKも提供されている。<br /> 言語は、Java / Node.js / PHP / Pythonの4つ。サンプルもある。<br /> ・<a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/quick-start/using-sdk.html">Using SDK · Product Advertising API 5.0</a></p> <p>ただ、残念なことに、Node.jsのSDKは、zipで公開されている...</p> <h2 id="ソース側の移行手順"><a href="#%E3%82%BD%E3%83%BC%E3%82%B9%E5%81%B4%E3%81%AE%E7%A7%BB%E8%A1%8C%E6%89%8B%E9%A0%86">ソース側の移行手順</a></h2> <h3 id="SDKを配置"><a href="#SDK%E3%82%92%E9%85%8D%E7%BD%AE">SDKを配置</a></h3> <p>zipをダウンロードして展開するとこんな感じになってる。</p> <p><a href="https://crieit.now.sh/upload_images/07628c2b1f8ec3ae587e9d119d743d6a5e635a2951165.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/07628c2b1f8ec3ae587e9d119d743d6a5e635a2951165.png?mw=700" alt="スクリーンショット 2020-03-07 17.11.09.png" /></a></p> <p>src配下がAPIなので、自分のソースに配置。</p> <p><a href="https://crieit.now.sh/upload_images/35f1b70ec8ce6466124c642bb991527e5e635a37ecdf3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/35f1b70ec8ce6466124c642bb991527e5e635a37ecdf3.png?mw=700" alt="スクリーンショット 2020-03-07 6.06.05.png" /></a></p> <p>dependencyがあるので、それもコピペして、<code>npm i</code>する</p> <pre><code class="json">"dependencies": { "superagent": "3.5.2", "crypto-js": "^3.1.9-1" }, </code></pre> <h3 id="APIの呼び出し"><a href="#API%E3%81%AE%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97">APIの呼び出し</a></h3> <p>解答したzipにサンプルがあるので、それを見ながら実装していく。<br /> 使っているのは検索なので、<code>sampleSearchItemsApi.js</code>を参照。</p> <p>以下は、サンプルの抜粋</p> <pre><code class="javascript">// ** API Clientの準備 var ProductAdvertisingAPIv1 = require('./src/index'); var defaultClient = ProductAdvertisingAPIv1.ApiClient.instance; // アクセスキーなどを設定。ホストとかリージョンは、以下を参照 // https://webservices.amazon.com/paapi5/documentation/common-request-parameters.html#host-and-region defaultClient.accessKey = '<YOUR ACCESS KEY>'; defaultClient.secretKey = '<YOUR SECRET KEY>'; defaultClient.host = 'webservices.amazon.co.jp'; defaultClient.region = 'us-west-2'; // ** リクエストの生成 var searchItemsRequest = new ProductAdvertisingAPIv1.SearchItemsRequest(); // アソシエイトタグを設定 searchItemsRequest['PartnerTag'] = '<YOUR PARTNER TAG>'; searchItemsRequest['PartnerType'] = 'Associates'; // 検索リクエストを設定。SearchIndexは以下を参照 // https://webservices.amazon.com/paapi5/documentation/use-cases/organization-of-items-on-amazon/search-index.html searchItemsRequest['Keywords'] = 'Harry Potter'; searchItemsRequest['SearchIndex'] = 'Books'; searchItemsRequest['ItemCount'] = 2; // 取得するレスポンスの指定 // https://webservices.amazon.com/paapi5/documentation/search-items.html#resources-parameter searchItemsRequest['Resources'] = ['Images.Primary.Medium', 'ItemInfo.Title', 'Offers.Listings.Price']; // ** コールバックの設定 var callback = function (error, data, response) { if (error) { // エラーの場合 console.log('Status Code: ' + error['status']); } else { // レスポンスを取得 var searchItemsResponse = ProductAdvertisingAPIv1.SearchItemsResponse.constructFromObject(data); if (searchItemsResponse['SearchResult'] !== undefined) { // 1件目の結果を取得 var item_0 = searchItemsResponse['SearchResult']['Items'][0]; if (item_0 !== undefined && item_0['ASIN'] !== undefined) { console.log('ASIN: ' + item_0['ASIN']); } } // エラーが返ってきた場合 if (searchItemsResponse['Errors'] !== undefined) { var error_0 = searchItemsResponse['Errors'][0]; console.log('Error Code: ' + error_0['Code']); console.log('Error Message: ' + error_0['Message']); } } }; // ** APIの実行 var api = new ProductAdvertisingAPIv1.DefaultApi(); try { api.searchItems(searchItemsRequest, callback); } catch (ex) { console.log('Exception: ' + ex); } </code></pre> <h2 id="対応が必要だった点"><a href="#%E5%AF%BE%E5%BF%9C%E3%81%8C%E5%BF%85%E8%A6%81%E3%81%A0%E3%81%A3%E3%81%9F%E7%82%B9">対応が必要だった点</a></h2> <p>基本的にパラメタがわかったため、一致してるものを探していけばOK。<br /> 変更自体はそこまでだけど、できることが変わっているので注意...</p> <h3 id="リクエスト関連"><a href="#%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E9%96%A2%E9%80%A3">リクエスト関連</a></h3> <ul> <li>MerchantIdがMerchantになっていた。設定値は変わらず</li> <li>SortがSortyByになり、設定値も変更</li> <li>PowerSearchが廃止に...つまり、除外や期間指定ができない</li> </ul> <h3 id="レスポンス関連"><a href="#%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E9%96%A2%E9%80%A3">レスポンス関連</a></h3> <ul> <li>全体的に変更。XMLからJSONになっており、構成も変わっている</li> <li>発売日がUTCになり、時刻まで記載</li> <li>エラーメッセージも全体的に変わっているので対応が必要</li> <li>バリエーションが除外され、GetVariations APIが新設(リクエスト数が増...)</li> <li>ただ、電子書籍の価格が取得できるようになった</li> </ul> <h2 id="よく参照したURL"><a href="#%E3%82%88%E3%81%8F%E5%8F%82%E7%85%A7%E3%81%97%E3%81%9FURL">よく参照したURL</a></h2> <p>とにかく、以下を読みまくった。。</p> <ul> <li>Operations関連: リクエストパラメタとか。指定できるレスポンスもここ <ul> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/search-items.html">SearchItems</a> ... 検索</li> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/get-items.html">GetItems</a> ... ASINから商品情報取得</li> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/get-variations.html">GetVariations</a> ... ASINからバリエーション情報取得</li> </ul></li> <li>Resource関連: レスポンスの内容 <ul> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/item-info.html">ItemInfo</a> ... 商品情報</li> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/images.html">Images</a> ... 画像関連</li> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/offers.html">Offers</a> ... 価格関連</li> </ul></li> <li>共通のリクエストパラメタ関連 <ul> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/locale-reference/japan.html">日本のMarketplaceとかの情報</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/common-request-parameters.html#host-and-region">共通のリクエストパラメタ</a> ... HostやRegionもここ</li> </ul></li> <li>共通のレスポンス関連 <ul> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/troubleshooting/error-messages.html">エラーメッセージ</a></li> </ul></li> <li>マイグレーション関連 <ul> <li><a target="_blank" rel="nofollow noopener" href="https://affiliate.amazon.co.jp/help/node/topic/GZH32YX29UH5GACM">v5.0への移行ガイドの日本語版</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/migration-guide/pa-api-40-to-50-mapping.html">v4.0からv5.0へのマッピング</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://webservices.amazon.com/paapi5/documentation/play-around-using-scratchpad.html">Scratchpadの使い方</a></li> </ul></li> </ul> <p>以上!!</p> <h2 id="こんなのつくってます!!"><a href="#%E3%81%93%E3%82%93%E3%81%AA%E3%81%AE%E3%81%A4%E3%81%8F%E3%81%A3%E3%81%A6%E3%81%BE%E3%81%99%21%21">こんなのつくってます!!</a></h2> <p>積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました!<br /> <a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>は、Nuxt.js+Firebaseで開発してます!</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/></p> <p>もしよかったら、遊んでみてくださいヽ(=´▽`=)ノ</p> <p>要望・感想・アドバイスなどあれば、<br /> 公式アカウント(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/MemoryLoverz">@MemoryLoverz</a>)や開発者(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/kira_puka">@kira_puka</a>)まで♪</p> きらぷか@積読ハウマッチ/SSSAPIなど tag:crieit.net,2005:PublicArticle/15678 2020-01-13T18:52:04+09:00 2020-01-13T18:52:04+09:00 https://crieit.net/posts/what-is-octoparse Octoparseとは?Webデータを自動抽出できるスクレイピングツール <h2 id="Octoparseとは?"><a href="#Octoparse%E3%81%A8%E3%81%AF%EF%BC%9F">Octoparseとは?</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://www.octoparse.jp/">Octoparse</a>は、視覚的に分かりやすくデータを抽出できる<a target="_blank" rel="nofollow noopener" href="https://www.octoparse.jp/blog/the-10-best-web-scraping-tools/">Webスクレイピングツール</a>です。コードを書くことなく、スクレイピングの初心者でも、Octoparseを使ってWebサイトから大量の情報を手軽に抽出できます。</p> <p>WindowsアプリケーションであるOctoparseは、Ajaxを使うWebページを含む静的および動的Webサイトに対応し、フォームを記入したり、テキストボックスに検索語を入力したりするなどで、人間の操作をシミュレートしてWebページとやり取りします。抽出プロジェクトは、自分のマシン(ローカル抽出)またはクラウド(クラウド抽出)で実行できます。CSV、EXCEL、HTML、JSON、データベース(MySQL、SQL Server、Oracle)などさまざまな出力形式があります。</p> <p>Octoparse無料版と有料版は同じ機能を共有しています。無料版だと、一部機能に制限がありますが、ヘビーユーズでもしない限りは、十分すぎるくらいの機能があります。有料版だと、タスクの登録数や自動実行数が多くなり、クラウド上で動作させることもできます。</p> <h3 id="ワークフロー"><a href="#%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC">ワークフロー</a></h3> <p>Octoparseは、視覚的に使いやすい操作ペインを提供します。Octoparseは、Webページを開いたり、アカウントにログインしたり、テキストを入力したり、Web要素をクリックするなど人間のWebブラウジング動作をシミュレートします。内蔵組ブラウザでWebサイトの情報をクリックして、必要な構造化データを取得します。</p> <h3 id="クラウドサービス"><a href="#%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9">クラウドサービス</a></h3> <p>分散コンピューティングに基づいて大規模なWebデータを同時にスクレイピングすることは、Octoparseの最も強力な機能です。クラウド機能を使うと、多数のクラウドサーバーを使って同時に抽出を実行できます。短期間に10,000のWebページをスクレイピングする必要がある場合は、Octoparseクラウドサービスが最適です。クラウド型プラットフォームでは、620倍の高速抽出が可能です。自動取得したデータはクラウドに保存され、どこでもアクセスできます。ハードウェア保守も不要だし、ネットワーク中断に心配する必要もありません。</p> <h3 id="豊富なツール"><a href="#%E8%B1%8A%E5%AF%8C%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB">豊富なツール</a></h3> <p>Octoparseには、ウィザード形式で抽出データを指定する「Wizard mode(ウィザードモード)」と自由に抽出データを指定できる「Advanced mode(アドバンスドモード)」2つのモードがあります。</p> <p>ユーザー体験を向上させるため、Advanced modeでは、豊富なツールセットを提供します。</p> <ul> <li>正規表現式生成ツール</li> <li>Xpath生成ツール</li> <li>実行タイムアウトの設定</li> <li>スクロールダウン</li> <li>ページアンカーフック</li> </ul> <h3 id="API"><a href="#API">API</a></h3> <p>Octoparse APIに接続すると、自分のシステムにデータを自動的に配信でき、自分のアカウントにあるデータにアクセスできます。タスクのルールを設定するだけで、Octoparseクラウドサーバーが残りの作業を行います。データはXMLの形式で配信されます。</p> <h3 id="Webスクレイピングテンプレート"><a href="#Web%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88">Webスクレイピングテンプレート</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://www.octoparse.jp/blog/a-revolutionary-web-scraping-software-to-boost-your-business-easier/">Webスクレイピングテンプレート</a>は非常にシンプルで強力な機能です。テンプレートを使うと、プログラミング知識の少ない/ない人でも簡単にWebスクレイピングを達成できます。具体的には、Octoparseのソフトには数十種類のあらかじめ作成されたテンプレートがあり、パラメータ(ターゲットWebサイトのURL、検索キーワードなど)を入力するだけで、データが抽出されてきます。そのため、スクレイピングタスクやコードを書く必要はありません。例えば、eBayで「イヤフォン」に関する製品情報を収集したい場合は、パラメータに「イヤフォン」と入力してタスクを実行して、数秒でアイテム番号、価格、送料などを含む製品情報を得ることができます。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>Webスクレイピングツールはニュースポータル、人工知能、フォーラム、Eコマースサイト、ソーシャルメディア、不動産、財務報告などさまざまな分野で広く使われています。Octoparseを利用することで、価格比較、研究、事業、営業、マーケティングを効率的に進めることができるようになります。</p> Octoparse Japan tag:crieit.net,2005:PublicArticle/15655 2019-12-29T19:05:24+09:00 2019-12-29T19:05:24+09:00 https://crieit.net/posts/Nuxt-serverMiddleware-API NuxtでserverMiddlewareを使ってAPIをつくってみる <p>Nuxt.js、SSRで実行すると外部サーバなしでAPIを簡単に追加できるらしい。<br /> serverMiddlewareを使ってルートを追加するとAPIが作れたので、その時の備忘録。</p> <h3 id="つかってみる"><a href="#%E3%81%A4%E3%81%8B%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B">つかってみる</a></h3> <h4 id="APIをつくる"><a href="#API%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8B">APIをつくる</a></h4> <pre><code class="typescript">// ~/server/echo.ts import { IncomingMessage, ServerResponse } from "http"; /** * 「?name=AAA」で呼び出すと、AAAを返すechoなAPI */ export default async function(req: IncomingMessage, res: ServerResponse) { try { // req は Node.jsのHTTPリクエストオブジェクト console.log(`req.url=${req.url}`); // URLをパースして、クエリを取得する const url = require("url").parse(req.url, true); const name = url.query.name; res.end(name); } catch (error) { console.error(error); res.end(null); } } </code></pre> <h4 id="設定をする"><a href="#%E8%A8%AD%E5%AE%9A%E3%82%92%E3%81%99%E3%82%8B">設定をする</a></h4> <pre><code class="typescript">// nuxt.config.ts import { Configuration } from "@nuxt/types"; const config: Configuration = { // ...略 serverMiddleware: [ // パスと対応するファイルを設定する { path: "/api/echo", handler: "~/server/echo.ts" }, ], }; export default config; </code></pre> <h4 id="APIを呼びだす"><a href="#API%E3%82%92%E5%91%BC%E3%81%B3%E3%81%A0%E3%81%99">APIを呼びだす</a></h4> <p>APIが作れたので、あとはaxiosなどで呼び出せばOK!</p> <pre><code class="typescript">import axios from "axios"; const res = axios.get(`${process.env.BASE_URL}/api/echo`, { params: { name: "AAA" } }); console.log(res.data); // => AAA </code></pre> <h3 id="つかってみる: express版"><a href="#%E3%81%A4%E3%81%8B%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B%3A+express%E7%89%88">つかってみる: express版</a></h3> <p>Node.jsのHTTPリクエストオブジェクトは扱いが若干めんどくさいので、<br /> Express使って楽したい..</p> <p>serverMiddlewareはExpressを使えるので、<br /> ルーティング含めてExpress側で設定できるので楽(<em>´ω`</em>)</p> <h4 id="APIをつくる"><a href="#API%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8B">APIをつくる</a></h4> <pre><code class="typescript">// ~/server/index.ts import { Request, Response } from "express"; import * as HttpStatus from "http-status-codes"; import bodyParser from "body-parser"; import express from "express"; const app = express(); // setup body-parser app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); // select app.post("/api/select", async (req: Request, res: Response) => { // ... }); // update app.post("/api/update", async (req: Request, res: Response) => { // ... }); // delete app.post("/api/delete", async (req: Request, res: Response) => { // ... }); export default app; </code></pre> <h4 id="設定をする"><a href="#%E8%A8%AD%E5%AE%9A%E3%82%92%E3%81%99%E3%82%8B">設定をする</a></h4> <pre><code class="typescript">// nuxt.config.ts import { Configuration } from "@nuxt/types"; const config: Configuration = { // ...略 serverMiddleware: [ serverMiddleware: ["~/server"], ], }; export default config; </code></pre> <p>これで、<code>~/server/index.ts</code>で設定した<code>/api/select</code>とかがルーティングに追加される。</p> <p>以上!!</p> <h2 id="こんなのつくってます!!"><a href="#%E3%81%93%E3%82%93%E3%81%AA%E3%81%AE%E3%81%A4%E3%81%8F%E3%81%A3%E3%81%A6%E3%81%BE%E3%81%99%21%21">こんなのつくってます!!</a></h2> <p>積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました!<br /> <a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>は、Nuxt.js+Firebaseで開発してます!</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/></p> <p>もしよかったら、遊んでみてくださいヽ(=´▽`=)ノ</p> <p>要望・感想・アドバイスなどあれば、<br /> 公式アカウント(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/MemoryLoverz">@MemoryLoverz</a>)や開発者(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/kira_puka">@kira_puka</a>)まで♪</p> <h1 id="参考にしたサイト"><a href="#%E5%8F%82%E8%80%83%E3%81%AB%E3%81%97%E3%81%9F%E3%82%B5%E3%82%A4%E3%83%88">参考にしたサイト</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://ja.nuxtjs.org/api/configuration-servermiddleware/">API: serverMiddleware プロパティ - NuxtJS</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://mabui.org/nuxtjs-servermiddleware-api/">Nuxt.jsのserverMiddlewareを使って、apiを叩く |</a></li> <li><a target="_blank" rel="nofollow noopener" href="http://jmqys.hatenablog.com/entry/2015/09/02/110816">(Node.js)リクエスト情報を取得するサンプル - フロントサイドエンジニアという選択肢</a></li> </ul> きらぷか@積読ハウマッチ/SSSAPIなど tag:crieit.net,2005:PublicArticle/15275 2019-07-25T03:03:37+09:00 2019-07-25T03:18:33+09:00 https://crieit.net/posts/PHP-API PHPで爆速APIを作るとき工夫したこと <p>「サーモンランAPI」という配信専用のAPIです。<br /> <a target="_blank" rel="nofollow noopener" href="https://splamp.info/salmon/api/">https://splamp.info/salmon/api/</a></p> <p>任天堂ソフト「Splatoon2」のサーモンランの最新情報を取得できます。</p> <h1 id="爆速のために"><a href="#%E7%88%86%E9%80%9F%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AB">爆速のために</a></h1> <p>Apacheサーバー上で、JSONデータを静的ファイルとして配信しています。</p> <p>これまでスプランプ(※うちのサイト)では「<a target="_blank" rel="nofollow noopener" href="https://splamp.info/spstage2/">スプステージ2</a>」という名前でバトルステージの情報を返すAPIを運用してきたのですが、こちらはオプションの充実のために、PHPファイルにアクセスさせる動的な仕組みでした。</p> <p>今回静的ファイルにした理由です。</p> <ol> <li><p>オプションを付けないほうがシンプル<br /> … タイムゾーンなどの混乱の解消のため、時間データはUnixtimeだけにしました。言語も日英同時に配信することにしました。</p></li> <li><p>サーバー負荷が激減する<br /> … 毎回DBにアクセスしたりせずに済むのでレスポンス速度が向上します。</p></li> <li><p>クライアントでキャッシュが有効になる<br /> … ヘッダの<code>Last-Modified</code>や<code>E-tag</code>により、クライアントでキャッシュが有効になります。</p></li> </ol> <h1 id="仕組み"><a href="#%E4%BB%95%E7%B5%84%E3%81%BF">仕組み</a></h1> <p>APIのアクセス先は一見「/salmon/api/now」や「/salmon/api/all」のように見えますが、実は<code>.htaccess</code>で「/salmon/api/」の別の子フォルダにあるJSONファイルにリライトしています。<br /> 例:</p> <pre><code class="apache">RewriteEngine On RewriteRule ^all$ xxx.xxx [L] </code></pre> <p>また、JSONファイルは更新用プログラムによって、定期的に新しいファイルに上書きされます。</p> <p>更新用プログラムはcronで定期的に更新すべきかチェックしていて、更新があるとDBからデータを取得・整形して、出力します。</p> <p>JSONは何となく可読性を高めたくなったので、インデントを付けたり無意味なエスケープを消したりしてみました。</p> <pre><code class="php">$json = json_encode($output, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); </code></pre> <h1 id="ヘッダ問題"><a href="#%E3%83%98%E3%83%83%E3%83%80%E5%95%8F%E9%A1%8C">ヘッダ問題</a></h1> <p>今回一番欠かせなかったのはヘッダの付与でした。</p> <p>毎アクセス動的生成していた頃はPHPの<code>header()</code>なんかを使っていたのですが、今回は静的ファイルですから、Apacheの力を借りる他ありません。</p> <p>Apacheでは、<code>.htaccess</code>を使うと配下のファイルに対して指定したヘッダを付与することができます。</p> <pre><code class="apache">Header set (ヘッダ名) "(値)" </code></pre> <p>今回加えたヘッダは以下の二つです。</p> <pre><code class="apache">Header set Access-Control-Allow-Origin "*" Header set Content-Type "application/json; charset=utf-8" </code></pre> <p><code>Content-Type</code>では、文字化けしたりしないようにUTF-8を明示しています。</p> <p><code>Access-Control-Allow-Origin</code>というのは見たことない人もいるのではないでしょうか。これは、JavaScriptにおいてクロスオリジンでアクセスしてもよいかの指定になります。</p> <p>これをサーバーが明示的に許可しないとjsがアクセスすることはできません。jsでオープンなAPIが使えないなんてもったいない。<code>*</code>を指定することで誰でもアクセスできるようになります。(CORS / Cross-Origin Resource Sharingの許可、と呼ばれたりします。)</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <ul> <li>サーバー上でキャッシュ(静的ファイル)を生成した</li> <li><code>.htaccess</code>でヘッダを指定した</li> <li><code>Access-Control-Allow-Origin</code>の指定でjs勢にも利用してもらえる</li> </ul> <h1 id="感想"><a href="#%E6%84%9F%E6%83%B3">感想</a></h1> <p>JavaScriptからのアクセス許可については、実際にjs勢の方から問い合わせがあって初めて気づきました。意外と見落としている方は多いんじゃないでしょうか。</p> <p>個人的な信条として「サーバーサイドの魔法」というのがあります。サーバーサイドは制約が少なく、予想外のことができるということです。Apacheの設定ファイル<code>.htaccess</code>は特にその幅を広げてくれるので気に入っています。<br /> 他にも色々な機能があるので、調べてみると面白いと思います。<br /> <a target="_blank" rel="nofollow noopener" href="https://murashun.jp/blog/20141229-01.html">.htaccess の書き方 | murashun.jp</a></p> <h1 id="サーモンランAPIの他の記事"><a href="#%E3%82%B5%E3%83%BC%E3%83%A2%E3%83%B3%E3%83%A9%E3%83%B3API%E3%81%AE%E4%BB%96%E3%81%AE%E8%A8%98%E4%BA%8B">サーモンランAPIの他の記事</a></h1> <p>サーモンランAPIについて<br /> <a target="_blank" rel="nofollow noopener" href="https://splamp.info/salmon/api/">https://splamp.info/salmon/api/</a></p> <p>サーモンランAPIサンプル集(連載)<br /> <a href="https://crieit.net/magazines/barley_ural/サーモンランAPIサンプル集">https://crieit.net/magazines/barley_ural/サーモンランAPIサンプル集</a></p> ウラル tag:crieit.net,2005:PublicArticle/15008 2019-05-21T16:05:34+09:00 2019-05-23T12:13:09+09:00 https://crieit.net/posts/Laravel5-8-FormRequest-JSON-API Laravel5.8現在FormRequestのバリデーション結果をJSON APIで返す <p>LaravelはFormRequestという仕組みでバリデーションを分離できる。APIの場合はコードを変えずにバリデーション結果のJSONを取得することができるのでその方法。</p> <p>ちなみにAPIでない通常のWebページの場合は<code>$errors</code>オブジェクトを使ってページ上にバリデーション結果を表示することができる。これのために作ったFormRequestをそのままAPIでも利用することができる。</p> <h2 id="やりかた"><a href="#%E3%82%84%E3%82%8A%E3%81%8B%E3%81%9F">やりかた</a></h2> <p>リクエストする際に<code>Accept: application/json</code>ヘッダーを送るだけ。これでJSONで取得できる。</p> <h2 id="以前のやりかた"><a href="#%E4%BB%A5%E5%89%8D%E3%81%AE%E3%82%84%E3%82%8A%E3%81%8B%E3%81%9F">以前のやりかた</a></h2> <p>ちなみに以前はこんな感じでFormRequestのメソッドをオーバーライドして対応していたっぽい。</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/junsan50/items/ec7f810decd3b82d3d76">【Laravel5】FormRequestのバリデーション結果をJSON APIで返す</a></p> <p>もしかしたらこの時もAcceptヘッダーを送ればできたのかもしれないが。何にしろ、リクエスト側の仕様の問題でAcceptヘッダーを正しく送ることができないのであればこの方法でやるしかなさそう。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14895 2019-03-31T23:50:35+09:00 2019-04-01T09:55:15+09:00 https://crieit.net/posts/React-GraphQL-API ReactでGraphQL APIにアクセスする <p><a href="https://crieit.now.sh/upload_images/0db2bc9716c1a8284f3a9afd4702101b5ca0d1aec3480.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/0db2bc9716c1a8284f3a9afd4702101b5ca0d1aec3480.png?mw=700" alt="image" /></a></p> <h1 id="背景"><a href="#%E8%83%8C%E6%99%AF">背景</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://developers.annict.jp/graphql-api/">AnnictのGraphQL API</a>からデータを取得したい!<br /> 参照:<a href="https://crieit.net/boards/annict-access">アニメ視聴遅れ管理サービスの開発</a></p> <h1 id="reactではどう実装するか"><a href="#react%E3%81%A7%E3%81%AF%E3%81%A9%E3%81%86%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E3%81%8B">reactではどう実装するか</a></h1> <p>Apollo Clientが便利なようです。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/seya/items/e1d8e77352239c4c4897">Apollo Client + React 入門</a></li> </ul> <h2 id="必要なパッケージのインストール"><a href="#%E5%BF%85%E8%A6%81%E3%81%AA%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">必要なパッケージのインストール</a></h2> <pre><code class="cmd">npm install apollo-boost react-apollo graphql-tag graphql --save </code></pre> <h2 id="ApolloClientの作成"><a href="#ApolloClient%E3%81%AE%E4%BD%9C%E6%88%90">ApolloClientの作成</a></h2> <ul> <li>エンドポイントを設定します。</li> <li>アクセストークンをヘッダに設定します。</li> </ul> <pre><code class="javascript">//APIエンドポイント let url = let url = 'https://api.annict.com/graphql' const client = new ApolloClient({ uri: url, request: operation => { operation.setContext({ headers: { authorization: 'Bearer ' + code } }) } }) </code></pre> <h2 id="graphqlを記述する"><a href="#graphql%E3%82%92%E8%A8%98%E8%BF%B0%E3%81%99%E3%82%8B">graphqlを記述する</a></h2> <p>このクエリは、ログインしているユーザ <strong>(viewer)</strong> の<br /> 見た作品 <strong>(state:WATCHED)</strong> を シーズン別降順 <strong>(orderBy: {field: SEASON, direction: DESC)</strong> でフィルタリングして返すという内容です。</p> <pre><code class="javascript">let query = gql`{ viewer { works(state: WATCHED, orderBy: {field: SEASON, direction: DESC}) { nodes { title seasonName seasonYear } } } }` </code></pre> <p>当初はタイトル画像のようなクエリのアプローチをしていたのですが、annictのdiscordコミュニティでannict作者のshimbacoさんに「こう書くといいですよ」と教えていただきました。</p> <h2 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h2> <p>とりあえずコンソールにログを出力するところまで。<br /> これをstoreに入れて表示してreact dndでソートするところまでが目標。</p> <pre><code class="javascript">export const fetchWatchedTitles=(code)=>{ (async()=>{ let url = 'https://api.annict.com/graphql' let query = gql`{ viewer { works(state: WATCHED, orderBy: {field: SEASON, direction: DESC}) { nodes { title seasonName seasonYear } } } }` const client = new ApolloClient({ uri: url, request: operation => { operation.setContext({ headers: { authorization: 'Bearer ' + code } }) } }) let response = await client.query({ query }) if(response !== null){ console.log(response.data.viewer.works.nodes) } })().catch( error=>{ console.log(error); } ) } </code></pre> <h1 id="参考リンク"><a href="#%E5%8F%82%E8%80%83%E3%83%AA%E3%83%B3%E3%82%AF">参考リンク</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/shimbaco/items/e3f2f8650b08e1e060bd">AnnictのGraphQL APIを使ってアニメデータを取得しよう</a></li> </ul> ckoshien tag:crieit.net,2005:PublicArticle/14550 2018-09-23T05:58:30+09:00 2018-10-28T13:07:26+09:00 https://crieit.net/posts/AI-AI-API 今注目のAIアプリを簡単に作れる、「AIメーカー」のAPIを公開しました! <p><a href="https://crieit.now.sh/upload_images/a95d1be30510c7095b20700ada6bad255ba6abc045e37.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a95d1be30510c7095b20700ada6bad255ba6abc045e37.png?mw=700" alt="aimaker_header.png" /></a></p> <hr /> <p>こんにちは、2z(Twitter: <a target="_blank" rel="nofollow noopener" href="https://twitter.com/2zn01">@2zn01</a> )です。</p> <p>先日、今話題のAIをweb上で誰でも気軽に作れる「AIメーカー」を開発しました!</p> <p>■AIメーカー<br /> <a target="_blank" rel="nofollow noopener" href="https://aimaker.io/">https://aimaker.io/</a></p> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">今話題のAIをweb上で誰でも気軽に作れる「AIメーカー」を開発しました!①AIに覚えさせたいタグを入力②タグから自動で画像データを収集③AIがデータから学習の3ステップで誰でも簡単にAIを作れます!動画では手相占いのAIに挑戦!みんなもAIを作って遊んでみてね!<a target="_blank" rel="nofollow noopener" href="https://t.co/66DFU7GRZ2">https://t.co/66DFU7GRZ2</a> <a target="_blank" rel="nofollow noopener" href="https://t.co/ie1LmioyA1">pic.twitter.com/ie1LmioyA1</a></p>— 2z@AIメーカー (@2zn01) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/2zn01/status/1019741210217365504?ref_src=twsrc%5Etfw">2018年7月19日</a></blockquote> <p>そのときにまとめた記事でこんなことを言ってました。</p> <ul> <li>今話題のAIをweb上で誰でも気軽に作れる「AIメーカー」を作ってみた<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/2zn01/items/0d3147c9d9d804ad9880">https://qiita.com/2zn01/items/0d3147c9d9d804ad9880</a></li> </ul> <blockquote> <p>・オープンなAIを目指したい</p> <p>百科事典ならwikipedia、地図ならOpen Street Mapのように、みんなが作ったAIをオープンに公開し、みんなでAIを便利に活用できる、そんな場所があったら面白いし、便利じゃないかと考えました!<br /> ・みんなのAIプラットフォームへ</p> <p>AIをクローズドなものとして囲い込むのではなく、もっとオープンにみんなで共有すればもっと便利さを享受できると考えました。</p> <p>そして、こんなAIが欲しいというのがあったら、みんなで協力してアイディアを出して、みんなで学習データを集め、AIを作ってみるのも良さそうです。</p> <p>学習が完了したAIはみんなで活用します!みんなハッピー!</p> </blockquote> <p>作ったAIをオープンにみんなで共有し、みんなで活用する「みんなのAI」プラットフォームを目指しますと。</p> <h2 id="API公開しました"><a href="#API%E5%85%AC%E9%96%8B%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F">API公開しました</a></h2> <p>ようやくですが、AIを作るだけでなく、AIメーカーで作成したAIをwebサービスやアプリに組み込めるようにAPIを公開しました!</p> <p>AIメーカーのAPIは自分が作ったAIはもちろんですが、他の方が作った公開されているAIもAPIとしてみんなで活用できます。</p> <h2 id="APIの呼び出し方法"><a href="#API%E3%81%AE%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E6%96%B9%E6%B3%95">APIの呼び出し方法</a></h2> <h3 id="HTTPリクエスト"><a href="#HTTP%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88">HTTPリクエスト</a></h3> <p>POST https://aimaker.io/image/classification/api</p> <h3 id="クエリパラメータ"><a href="#%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF">クエリパラメータ</a></h3> <div class="table-responsive"><table> <thead> <tr> <th align="left">パラメータ</th> <th align="left">型</th> <th align="left">説明</th> </tr> </thead> <tbody> <tr> <td align="left">id</td> <td align="left">integer</td> <td align="left">モデルのIDを指定してください。</td> </tr> <tr> <td align="left">apikey</td> <td align="left">string</td> <td align="left">APIキーを指定してください。</td> </tr> <tr> <td align="left">file</td> <td align="left">binary</td> <td align="left">画像ファイルを指定してください (jpg, png, 10MB以内)</td> </tr> </tbody> </table></div> <p>モデルID、APIキーについては、AIメーカーの各モデル画面の「APIを使う!」をご覧ください。<br /> <a target="_blank" rel="nofollow noopener" href="https://aimaker.io/app/image-classification/id/1">https://aimaker.io/app/image-classification/id/1</a></p> <p>各モデルは以下URLのみんなのAIから検索頂けます。<br /> <a target="_blank" rel="nofollow noopener" href="https://aimaker.io/app/search">https://aimaker.io/app/search</a></p> <h3 id="CURLでAPIを実行する場合"><a href="#CURL%E3%81%A7API%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88">CURLでAPIを実行する場合</a></h3> <p><code>curl -X POST -F id=$id -F apikey=$apikey -F "file=@/path/to/image/sample.png" "https://aimaker.io/image/classification/api"</code></p> <h3 id="成功時のレスポンス"><a href="#%E6%88%90%E5%8A%9F%E6%99%82%E3%81%AE%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9">成功時のレスポンス</a></h3> <p><em>JSON形式</em></p> <pre><code class="json-doc"><br />{ "state": 1, "url": "https://aimaker.io/sample.png", "labels": { "0": { "score": 0.997, "label": "ラベル0" }, "1": { "score": 0.003, "label": "ラベル1" } } } </code></pre> <h3 id="失敗時のレスポンス"><a href="#%E5%A4%B1%E6%95%97%E6%99%82%E3%81%AE%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9">失敗時のレスポンス</a></h3> <p><em>JSON形式</em></p> <pre><code class="json-doc"><br />{ "state": 0, "messages": [ "不正なアクセスです。" ] } </code></pre> <h2 id="APIの活用例"><a href="#API%E3%81%AE%E6%B4%BB%E7%94%A8%E4%BE%8B">APIの活用例</a></h2> <p>あくまで一例ですが、以下のような活用が可能かと思います。</p> <ul> <li>webサービスに画像認識を組み込む</li> <li>アプリに画像認識を組み込む</li> <li>LINE BOTなどで画像認識Botを作る</li> </ul> <p>AIメーカーとそのAPIを使うことで、自分で画像認識モデルを作る手間を省いてシステムに組み込めるので、ぜひご活用ください。</p> <h2 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h2> <p>AIメーカーを使って、AIで遊んでみてください!</p> <p>■AIメーカー<br /> <a target="_blank" rel="nofollow noopener" href="https://aimaker.io/">https://aimaker.io/</a></p> <p>みんなのAIは以下のURLから検索頂けます。<br /> <a target="_blank" rel="nofollow noopener" href="https://aimaker.io/app/search">https://aimaker.io/app/search</a></p> <p>「AIメーカー」はまだまだ構想の一部しかできていないので、僕も頑張ってこれからもっと機能を追加していきたいと思っています。<br /> 「みんなのAIプラットフォーム」となれることを目指します!</p> <p>AIメーカーに少しでも興味をもって頂けましたら、ぜひフォローやいいね、リツイートで応援お願いします!</p> <ul> <li>Twitter: <a target="_blank" rel="nofollow noopener" href="https://twitter.com/2zn01">@2zn01</a></li> <li>note: <a target="_blank" rel="nofollow noopener" href="https://note.mu/2zn01">@2zn01</a></li> </ul> <p>AIメーカーでは、以下のようなことができます。</p> <h5 id="・画像認識"><a href="#%E3%83%BB%E7%94%BB%E5%83%8F%E8%AA%8D%E8%AD%98">・画像認識</a></h5> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">今話題のAIをweb上で誰でも気軽に作れる「AIメーカー」を開発しました!①AIに覚えさせたいタグを入力②タグから自動で画像データを収集③AIがデータから学習の3ステップで誰でも簡単にAIを作れます!動画では手相占いのAIに挑戦!みんなもAIを作って遊んでみてね!<a target="_blank" rel="nofollow noopener" href="https://t.co/66DFU7GRZ2">https://t.co/66DFU7GRZ2</a> <a target="_blank" rel="nofollow noopener" href="https://t.co/ie1LmioyA1">pic.twitter.com/ie1LmioyA1</a></p>— 2z@AIメーカー (@2zn01) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/2zn01/status/1019741210217365504?ref_src=twsrc%5Etfw">2018年7月19日</a></blockquote> <h5 id="・文字起こし"><a href="#%E3%83%BB%E6%96%87%E5%AD%97%E8%B5%B7%E3%81%93%E3%81%97">・文字起こし</a></h5> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">みんな~!「AIメーカー」で文字起こし機能をリリースしたよー!以下の方法で簡単に文字起こしを試せるので、ぜひ使ってみて~!!??YouTubeから文字起こし??画像、音声、動画から文字起こし???録音で文字起こしAIをうまく使って少しでも面倒な作業から解放だぁ~!<a target="_blank" rel="nofollow noopener" href="https://t.co/qo13Wo6Yli">https://t.co/qo13Wo6Yli</a> <a target="_blank" rel="nofollow noopener" href="https://t.co/gsRigVROnK">pic.twitter.com/gsRigVROnK</a></p>— 2z@みんなのAI「AIメーカー」開発中 (@2zn01) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/2zn01/status/1030652280914173953?ref_src=twsrc%5Etfw">2018年8月18日</a></blockquote> <h5 id="・月の絵文字でモザイクアート"><a href="#%E3%83%BB%E6%9C%88%E3%81%AE%E7%B5%B5%E6%96%87%E5%AD%97%E3%81%A7%E3%83%A2%E3%82%B6%E3%82%A4%E3%82%AF%E3%82%A2%E3%83%BC%E3%83%88">・月の絵文字でモザイクアート</a></h5> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【お知らせ】月の絵文字でモザイクアートが作れる機能を作りました!画像をアップロードすると、それをもとに月の絵文字を使った絵を描いてくれるので、ぜひ遊んでみてね~!<a target="_blank" rel="nofollow noopener" href="https://t.co/zt3vzPNZS0">https://t.co/zt3vzPNZS0</a><a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/AI%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC?src=hash&ref_src=twsrc%5Etfw">#AIメーカー</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E6%9C%88%E3%81%A7%E7%B5%B5%E3%82%92%E6%8F%8F%E3%81%8F?src=hash&ref_src=twsrc%5Etfw">#月で絵を描く</a> <a target="_blank" rel="nofollow noopener" href="https://t.co/bowo1hlpXV">pic.twitter.com/bowo1hlpXV</a></p>— 2z@AIメーカー開発者 (@2zn01) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/2zn01/status/1040733556463480832?ref_src=twsrc%5Etfw">2018年9月14日</a></blockquote> 2z@AIメーカー tag:crieit.net,2005:PublicArticle/14491 2018-07-28T21:30:43+09:00 2018-10-31T16:26:56+09:00 https://crieit.net/posts/A3RT A3RTとユーザーローカルの文章の自動要約を試してみた <p>先日ユーザーローカルが文章の自動要約ツールを公開しました。また、リクルートテクノロジーズが公開しているAI群であるA3RTにText Summarization APIという文章の自動要約APIがあります。それらを実際に使って文章の要約を試してみました。</p> <p><a target="_blank" rel="nofollow noopener" href="https://text-summary.userlocal.jp/">自動要約 無料ツール by ユーザーローカル</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://a3rt.recruit-tech.co.jp/product/TextSummarizationAPI/">Text Summarization API|PRODUCT|A3RT</a></p> <h2 id="ユーザーローカルの自動要約"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%AE%E8%87%AA%E5%8B%95%E8%A6%81%E7%B4%84">ユーザーローカルの自動要約</a></h2> <p>こちらはAPIではなく、ブラウザ上で使う自動要約ツールとなっています。実際に下記の文章多めの記事で試してみました。コードは削除して試しています。</p> <p><a href="https://crieit.net/posts/bosyu">bosyuの募集一覧を勝手に作ってみた(機械学習解説付き) - Crieit</a></p> <p>結果は下記のようになりました。</p> <h3 id="3行ダイジェスト"><a href="#3%E8%A1%8C%E3%83%80%E3%82%A4%E3%82%B8%E3%82%A7%E3%82%B9%E3%83%88">3行ダイジェスト</a></h3> <pre><code>この機能はそのままクラス分類( Classification )というらしいです。 ひとつのカテゴリにいくつでもキーワードを設定できるようにしました。 分類されないものは全部「その他」カテゴリに入れています。 </code></pre> <h3 id="10行ダイジェスト"><a href="#10%E8%A1%8C%E3%83%80%E3%82%A4%E3%82%B8%E3%82%A7%E3%82%B9%E3%83%88">10行ダイジェスト</a></h3> <pre><code>bo sy u. me の一覧ページを作成してみました。 応募が来るとサービス上で簡単一覧できる便利なサービスです。 (カテゴリの自動分類方法詳細は後述)、環境 機械学習によるカテゴリの自動分類、サービスの肝です。 この機能はそのままクラス分類( Classification )というらしいです。 Watson Natural Language Classifier (自然言語分類) facebookresearch / fastText : Library for fast text representation and classification ひとつのカテゴリにいくつでもキーワードを設定できるようにしました。 非常に的確にカテゴリ分類ができるようになりました。 分類されないものは全部「その他」カテゴリに入れています。 </code></pre> <p>どちらもいまいちではありますが、10行の方は多少それっぽくは見えます。</p> <p>ユーザーローカルの自動要約は3行、5行、10行から選べるため一番それっぽいものを選ぶことができます。また、文章のどのあたりが重要な部分か、というのをマーカーやヒートマップで確認する機能もあるので、参考になります。</p> <p>ただ、重要な部分を使って自動要約を行っているので、人間が作る要約とは違い文章の開始と終了が不自然だったりします。今回の3行の方等もそんな感じですね。</p> <p>また、こちらは結果表示画面に精度向上のためのアンケートがあるので、無料で公開するかわりにみんなで協力してデータを集めて精度を高める実験中、という感じがします。</p> <h2 id="A3RTの自動要約"><a href="#A3RT%E3%81%AE%E8%87%AA%E5%8B%95%E8%A6%81%E7%B4%84">A3RTの自動要約</a></h2> <p>A3RTの方はText Summarization APIといって、プログラムから実行できるようなAPIとなっています。こちらは下記のような制限があります。</p> <blockquote> <p>要約できる1文の最大文字数は200文字、且つ最大文章数は10です。</p> </blockquote> <p>ということで、そのままでは長文には使えないので、記事の本文を上記に合うように区切って、それぞれを自動要約してくっつけることで試してみました。</p> <pre><code>bosyu.meの募集一覧ただ、ただほんとに一覧するだけだとTwitter上で#bosyuというハッシュタグを使って見ればいいだけなので、独自の機能としてカテゴリ分類機能を追加し、カテゴリ毎の募集を見られるようにしてみました。 8ce5b9af-16f5-d75a-536d-b62a6e57971e.pngカテゴリは選択たらすぐに画面が切り替わるのですが、Date Pickerはどうも選択時のcallbackが無いようだったので、仕方なく検索ボタンを押してもらう形にしました。 Google Cloud Natural Language APIGoogle Cloud Natural LanguageとりあえずGoogleなら何かあるだろ、と思って調べたら全くそのままのものがありました。 機能的にはこれで問題なかったのですが、とりあえず最初にGoogleのAPIを知ってしまったので学習が要らないAPIを引き続き探しました。 色々探しましたがGoogleのもののように良い感じに最初からカテゴリ分けされてるっぽいものはなさそうですし、ツイートであれば学習データを集めるのは特に難しいことではないし、学習させるというのも大事なことだと思ったためです。 ツイートなので文章が全体的に短すぎるのか、何時間かしかかけずに集めたデータが少なすぎたのか、おかしなカテゴリに入ってしまうものが多発しました。こういう場合にはわざわざ機械学習を導入せず、シンプルな方法を選択することも必要な場面はあると思います。 </code></pre> <p>変な感じにはなっていますが、これは前述の通り適当な仕様で自動要約しているので、多分その作り方に問題がありそうです。長文の場合はもうちょっと考えて実装しないといけなそうですね。もしくはA3RT自体が対応してくれないと厳しいかもしれません。</p> <p>こちらも要約後の文章数は指定できるので、いくつか出力して一番良いものを選ぶことはできそうです。</p> <p>今回試しに作ったプログラムは下記で操作できるものを公開しています。</p> <p><a target="_blank" rel="nofollow noopener" href="http://alphabrend.sakura.ne.jp/a3rt-text-summarization/">A3RT Text Summarization API Sample</a></p> <p>プログラムはGitHubに公開しています。(最短で動作するように作ったので適当です)</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/dala00/a3rt-text-summarization-sample">dala00/a3rt-text-summarization-sample</a></p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>どちらの自動要約も十分なものか、と言われると微妙ですが、とりあえず大量に要約文を作りたい、という場合には良さそうです。ユーザーローカルは多分そのうち有料でもっと精度の高いAPIが実装されるのではないかと思いますが、A3RTであればなぜかはわかりませんが無料ですので、必要に応じて使っていくことは可能です。</p> <p>今のところどちらも機能的に制約がありますが、機会があればぜひ試してみてください。</p> だら@Crieit開発者