tag:crieit.net,2005:https://crieit.net/tags/%E5%88%9D%E5%BF%83%E8%80%85/feed 「初心者」の記事 - Crieit Crieitでタグ「初心者」に投稿された最近の記事 2021-07-13T02:44:33+09:00 https://crieit.net/tags/%E5%88%9D%E5%BF%83%E8%80%85/feed tag:crieit.net,2005:PublicArticle/17503 2021-07-13T02:44:33+09:00 2021-07-13T02:44:33+09:00 https://crieit.net/posts/8dbd7e242deb435cd79ca8fdedbdfb4e 100万円失いながらハッキングを乗り越え誰でも1分で切り抜きを作れるサービスを公開するまでの失敗と学び <p>先日、<strong>誰でも最短1分でYouTubeの切り抜きを作れる</strong>ウェブサービスを公開しました。</p> <p>私はプログラミングの勉強を始めて1年半の初学者ですが、個人開発でサービスを公開するまでに、数多くの失敗と苦労をしてきました(そして今もしてます笑)。後ほど詳しく書きますが、以下のような経験をしました。</p> <ol> <li>ハッキングを受けデータを盗まれる</li> <li>α版をリリースするも作り直しを決意する</li> <li>巻き返しのため海外フリーランサーを雇うも無駄金となる</li> <li>公開前に本家が同じ機能を発表し諦めかける</li> <li>β版をリリースするも使われない</li> </ol> <p>同じようにプログラミングの勉強をし始めたばかりの方や、個人開発でいつかはサービスを公開したいと考えている方の「転ばぬ先の杖」として、私の経験が役に立てばと思っております。</p> <h1 id="開発したサービス"><a href="#%E9%96%8B%E7%99%BA%E3%81%97%E3%81%9F%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9">開発したサービス</a></h1> <p>YouTubeの公式APIを利用してウェブ上で切り抜きを作成・紹介できるウェブサービス「<strong>YouClip</strong>」を開発しました。</p> <div class="iframe-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/N801yLTnhbo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div> <p>ここから実際に触れます→https://youclip.app</p> <p>私自身が所属するスポーツチームの動画をYouTubeにアップすることが多くあり、試合やプレーの振り返りをするのにあったら便利だなと思ったのが着想のきっかけです。考えてみると、これはスポーツのプレー分析以外にも色々と用途があるのではないかと思い、プログラミングの学習も兼ねて一般向けのサービスとして開発を始めました。</p> <h1 id="今までの失敗と学び"><a href="#%E4%BB%8A%E3%81%BE%E3%81%A7%E3%81%AE%E5%A4%B1%E6%95%97%E3%81%A8%E5%AD%A6%E3%81%B3">今までの失敗と学び</a></h1> <h3 id="1.ハッキングを受けデータを盗まれる"><a href="#%EF%BC%91%EF%BC%8E%E3%83%8F%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0%E3%82%92%E5%8F%97%E3%81%91%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E7%9B%97%E3%81%BE%E3%82%8C%E3%82%8B">1.ハッキングを受けデータを盗まれる</a></h3> <p>開発を始めて間もないある日、いつものように本番サイトを開こうとするとエラーでページが表示されません。おかしいなと思いサーバ上のDBを確認すると、あったはずのテーブルが全て消えており、見慣れない<strong>WARNING</strong>と言う名のテーブルが1つだけありました。そこにはデータが1つだけ入っており、「データを復元して欲しければビットコインを振込め」との脅迫文が書かれていました。<br /> <img width="100%" alt="YouClip demo" title="YouClip demo" src="https://youclip-storage.s3.ap-northeast-1.amazonaws.com/thumbs/warning.png"><br /> (テーブルに入っていた全文)</p> <pre><code>To recover your lost databases and avoid leaking it: visit xxxx and enter your unique token xxxx and pay the required amount of Bitcoin to get it back. Databases that we have: xxxx, xxxx. Your databases are downloaded and backed up on our servers. If we dont receive your payment in the next 9 Days, we will sell your database to the highest bidder or use them otherwise. </code></pre> <blockquote> <p>(日本語訳)<br /> 失ったデータを復元し漏洩したくなければ、xxxxのサイトを訪れ、記載のトークンを入力した上で指定された金額のビットコインを支払え。お前のデータベースはダウンロードし、我々のサーバにバックアップしてある。9日以内に支払いがなければ、誰か高く買ってくれる人に売るか、別の方法で利用するだろう。</p> </blockquote> <p>そこではじめて何者かが<strong>DBをハッキングし、データを人質にビットコインを身代金として要求している</strong>のだと分かりました。幸いまだ開発初期で、ユーザーは身内と知り合い数人しかいなく、個人情報もメールアドレスくらいだったので、彼らにはお詫びをしてデータは諦めることにしました。まさかサーバに上げてすぐにハッキングされるとは思ってもおらず、衝撃でした。</p> <p>原因は、あまり深く考えずサーバにphpMyAdminを入れていたのですが、<strong>アカウント名やパスワードが単純</strong>だったため<strong>ブルートフォースアタック</strong>(総当り攻撃)でハッキングされたのだと思います(アホすぎるorz)。セキュリティに無知だった自分が悪いのですが、これが正式なリリース後だったら・・とゾッとしました。リリースする際には十二分にセキュリティ対策をしようと、苦い教訓となりました。(当然現在はphpMyAdminも入れてません)</p> <h3 id="2.α版をリリースするも作り直しを決意する"><a href="#%EF%BC%92%EF%BC%8E%CE%B1%E7%89%88%E3%82%92%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%99%E3%82%8B%E3%82%82%E4%BD%9C%E3%82%8A%E7%9B%B4%E3%81%97%E3%82%92%E6%B1%BA%E6%84%8F%E3%81%99%E3%82%8B">2.α版をリリースするも作り直しを決意する</a></h3> <p>当初作ろうと思っていた機能とデザインを一通り実装し終えたので、α版として身近な友人や親戚に使ってもらうことにしました。Adobe XDでUI案を作った段階で友人などからフィードバックはもらっていたし、自分でも使いやすく作ったつもりだったので、それほど大きな問題はないだろうと思ってました。しかし、いざ使ってもらうと<strong>肝心の切り抜き機能が使いづらい</strong>と感じる人が多いことが分かりました。そのため、<strong>切り抜き機能のフローやUIを抜本的に見直す</strong>ことを決意し、その影響はサービス全体にも及んで結果として大改修をする羽目になりました。</p> <p>Adobe XDでUI案を作った段階で友人からフィードバックをもらっていたのですが、それでも今回の問題に気付けなかったのは、2つ陥りがちな罠にはまっていたと思います。</p> <ul> <li>画面デザインを見せて意見を聞くだけで、<strong>ユーザーが操作しているところを観察しなかった</strong></li> <li>元からサービスの内容を知っている友人に意見を聞くだけで、<strong>完全に初見の人からフィードバックをもらわなかった</strong></li> </ul> <p>やはり実際に<strong>操作するのを見て初めて気が付く</strong>ことが多くあり、XDの画面デザインを見せるだけでなく、<strong>プロトタイプ機能</strong>を使って模擬的に操作してもらうべきでした。また、サービスの前提知識がある人やITリテラシーが高い人だと、多少分かりにくくても使いこなせてしまいます。実際にこれから使うターゲットユーザーに合わせ、<strong>初見でITリテラシーもそこまで高くない人</strong>からもフィードバックをもらうべきでした</p> <h3 id="3.巻き返しのため海外フリーランサーを雇うも無駄金となる"><a href="#%EF%BC%93%EF%BC%8E%E5%B7%BB%E3%81%8D%E8%BF%94%E3%81%97%E3%81%AE%E3%81%9F%E3%82%81%E6%B5%B7%E5%A4%96%E3%83%95%E3%83%AA%E3%83%BC%E3%83%A9%E3%83%B3%E3%82%B5%E3%83%BC%E3%82%92%E9%9B%87%E3%81%86%E3%82%82%E7%84%A1%E9%A7%84%E9%87%91%E3%81%A8%E3%81%AA%E3%82%8B">3.巻き返しのため海外フリーランサーを雇うも無駄金となる</a></h3> <h4 id="3−1.Crowdworks経由で中国人のエンジニアと働く"><a href="#%EF%BC%93%E2%88%92%EF%BC%91%EF%BC%8ECrowdworks%E7%B5%8C%E7%94%B1%E3%81%A7%E4%B8%AD%E5%9B%BD%E4%BA%BA%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E5%83%8D%E3%81%8F">3−1.Crowdworks経由で中国人のエンジニアと働く</a></h4> <p>大改修により、当初の予定よりだいぶリリース時期が遅れることが見込まれたため、巻き返しに<strong>スポットで外部のエンジニアを雇えないか</strong>考えました。知り合いをはじめ、Twitterや、<a target="_blank" rel="nofollow noopener" href="https://crowdworks.jp/">クラウドワークス</a>、<a target="_blank" rel="nofollow noopener" href="https://www.lancers.jp/">ランサーズ</a>などのクラウドソーシングサイトを利用して、フリーランスエンジニアの方々に連絡してみましたが、いいなと思う人はやはり時給にすると5,000円以上といった感じでした。<strong>自腹を切る上に、どれぐらい開発に時間がかかるかも読み切れない</strong>中で、言い方は悪いですが少しでもコストパフォーマンスの良さそうな人を必死に探しました。</p> <p>そんな中、<a target="_blank" rel="nofollow noopener" href="https://crowdworks.jp/">クラウドワークス</a>に登録していたエンジニアの1人が、技術スタックや経験、公開しているポートフォリオの観点からも良さそうで、かつ時給3,000円程度のオファーだったので、その人にお願いしてみることにしました。やりとりしている段階で気が付きましたが、登録してある情報は日本語でしたが実際には彼は<strong>中国人</strong>で、英語と中国語しか使えないようでした。私自身は留学経験もあり、英語でやりとりするのに抵抗はなかったのでそのまま彼と契約することにしました。</p> <p>彼とは作業時間に応じて支払いをする形(プロジェクト形式)で、途中休暇を挟みながらも足掛け2ヶ月程度リモートで一緒に働いたのですが、<strong>完成前に契約を打ち切りました</strong>。今も使っている有用なライブラリを紹介してくれたり、技術力はある程度期待通りだったのですが、次第に<strong>胡散臭いところや、面倒な交渉が多く発生するようになった</strong>のが原因です。</p> <p>例えば、タスク量はそれほど変わっていないはずなのに、<strong>後半になるにつれ作業時間がなぜか右肩上がり</strong>で増えていました。また、兄弟がコロナにかかって重症で大変なので<strong>ボーナスをくれないか</strong>と交渉されたり、契約の終わりの方には次のクライアントを見つけるのに海外のフリーランスサイトに登録したいが出来ないので、<strong>アカウントを貸してくれないか</strong>とお願いされたりしました。このようなことが積み重なって、次第に信用できなくなっていきました。</p> <h4 id="3−2.海外のクラウドソーシングサイトでインド人・ウクライナ人・スペイン人と働く"><a href="#%EF%BC%93%E2%88%92%EF%BC%92%EF%BC%8E%E6%B5%B7%E5%A4%96%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%82%BD%E3%83%BC%E3%82%B7%E3%83%B3%E3%82%B0%E3%82%B5%E3%82%A4%E3%83%88%E3%81%A7%E3%82%A4%E3%83%B3%E3%83%89%E4%BA%BA%E3%83%BB%E3%82%A6%E3%82%AF%E3%83%A9%E3%82%A4%E3%83%8A%E4%BA%BA%E3%83%BB%E3%82%B9%E3%83%9A%E3%82%A4%E3%83%B3%E4%BA%BA%E3%81%A8%E5%83%8D%E3%81%8F">3−2.海外のクラウドソーシングサイトでインド人・ウクライナ人・スペイン人と働く</a></h4> <p>ただ、<strong>作業自体はある程度スピードアップ</strong>したのは確かだったので、もう少し試してみようと、今度は直接海外のクラウドソーシングサイトを利用してみることにしました。前回の反省を活かして、数時間で出来る小さいタスクに対するコンペ方式で支払いを抑えつつ、何人か試してみていい人がいたら継続しようと考えました。</p> <p>海外のクラウドソーシングサイトで有名な<a target="_blank" rel="nofollow noopener" href="https://www.freelancer.com/">Freelancer.com</a>や<a target="_blank" rel="nofollow noopener" href="https://www.upwork.com/">Upwork</a>を使って、<strong>インド人、ウクライナ人、スペイン人</strong>と働いてみることにしました。確かに金額的には日本よりだいぶ低く抑えられましたが、<strong>お願いした仕様と全く違うもの</strong>を作ってきたり、その多くが自分でやり直さなければいけないことになりました。</p> <p>結局<strong>トータル100万円</strong>近く掛けましたが、果たしてその価値があったかと聞かれると「はい」とは素直に言えない感じになりました。日本のフリーランスの方と働いたことがないため一概には言えないものの、<strong>(中国・インド等の)海外エンジニアだからコスパ的に良いといったことはない</strong>というのが今回の感想です。</p> <h3 id="4.公開前に本家が同じ機能を発表し諦めかける"><a href="#%EF%BC%94%EF%BC%8E%E5%85%AC%E9%96%8B%E5%89%8D%E3%81%AB%E6%9C%AC%E5%AE%B6%E3%81%8C%E5%90%8C%E3%81%98%E6%A9%9F%E8%83%BD%E3%82%92%E7%99%BA%E8%A1%A8%E3%81%97%E8%AB%A6%E3%82%81%E3%81%8B%E3%81%91%E3%82%8B">4.公開前に本家が同じ機能を発表し諦めかける</a></h3> <p>改修も終えそろそろリリースできそうだなと考えていたある日、<strong>YouTube本家</strong>が動画の一部を切り取ってSNSでシェアできる<strong>クリップ</strong>と言う機能を実験的に米国で開始したと言う<a target="_blank" rel="nofollow noopener" href="https://japan.cnet.com/article/35165756/">ニュース</a>が流れてきました。</p> <p>本家が、名前もほぼそのまま、同等の機能を出してくるとは思ってもおらず、リリースしても本家に勝てるはずがないと諦めかけました。しかし少し冷静になって考えてみると、まだ実験的な位置付けで本当に追加されるかもわからないことに加え、そもそも<strong>本家は1つの場面しか切り抜けないが、YouClipは複数の場面を切り抜いて繋げられる</strong>ことなど、機能面でも違いがありました。</p> <p>そこで、この機能面の違いに目を向ければ、特定のユースケースでYouClipにも需要がまだあるのではないかと考え直し、そのユースケースに集中しようと考え直しました。具体的には、複数の場面を切り抜いて繋げる必要があるような、<strong>長時間のライブ配信</strong>がメインの<strong>VTuber動画</strong>や、<strong>ゲーム実況配信</strong>にサービスの主眼を置くことにしました。</p> <h3 id="5.β版をリリースするも使われない"><a href="#%EF%BC%95%EF%BC%8E%CE%B2%E7%89%88%E3%82%92%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%99%E3%82%8B%E3%82%82%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%AA%E3%81%84">5.β版をリリースするも使われない</a></h3> <p>そうやって何とかβ版のリリースに漕ぎ着け、知り合いやTwitter経由でユーザーを集め始めたのですが、一度はサイトに訪問してくれるものの、そのまま何もせずに帰ってしまう人がほとんどでした。Google Analyticsで見てみると、ホーム画面や再生画面の<strong>直帰率が70%近く</strong>あり、全く以て<strong>穴の開いたバケツ</strong>のような状態であることがわかりました。</p> <p>そこからは直接ユーザーに意見を聞いたり、Analyticsで取れる各種KPIや<a target="_blank" rel="nofollow noopener" href="https://clarity.microsoft.com/">Microsoft Clarity(※)</a>の画面レコーディングデータを見つつ、仮説を立てて離脱率が下がるよう改善を繰り返しました。</p> <p>例えば、再生画面の画面レコーディングを見ると、ミュート解除ボタンに気づかず、そのままミュート状態で見続けているユーザーが多くいることに気づきました。ミュート状態だと面白さは半減するため、<strong>ミュート解除ボタンをより目立つ位置と見た目に変える</strong>ことで、再生画面の離脱率を10pt%近く下げることができました。<br /> <img width="90%" alt="ミュート解除の改善" title="ミュート解除の改善" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23090/e846cb3a-c2b6-011e-3540-1b60dd190bd0.png"></p> <p>まだまだ十分とは全く言えない状態ですが、このような小さな改善を繰り返すことで、バケツの穴を少しずつ塞いでいっています。</p> <blockquote> <p>(※)Microsoftの無料ヒートマップツール「Clarity」について<br /> Clarityは、ユーザーの行動を無料で把握できる分析ツールで、匿名化されたユーザーの画面操作記録を見ることが出来ます。</p> </blockquote> <div class="iframe-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/KAibwlJnx9Y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div> <blockquote> <p>詳しくは以下のサイトなどを見てもらうと良いと思いますが、実際にユーザーがどんな風にサービスを使っているのかを知るのにとても役立ちます!<br /> https://sogyotecho.jp/clarity/</p> </blockquote> <h1 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h1> <p>このようにたくさん失敗をし、正直こんなことやって意味あるのか自問自答することもありましたが、長年やってみたいと思っていた個人開発でサービスを作れた事は楽しかったし良い経験となりました。</p> <p>こんなこと出来ないかと空想することから始まり、そこからどうやったら実現出来るか1つずつ考え・調べて・学びながら実装していく作業はとても楽しかったです。そうやって苦労して作ったサービスが誰かに使われているのを見るのはとても嬉しく、新しく投稿があると思わず全部いいねしてしまいます笑</p> <p>また、当然サービスをリリースしても知ってもらわなければ意味がないので、苦手なSNSの運用やマーケティングについても現在進行系で試行錯誤しながら学んでいます。(こちらも現在進行系で失敗?!しているので、いつか振り返りたい)</p> <p>以上が個人開発でサービスを公開するまでの私の失敗と学びです。<br /> 何かしら個人開発をしている人、これからしたい人の参考になれば嬉しいです!</p> Kendai tag:crieit.net,2005:PublicArticle/17090 2021-05-11T23:46:09+09:00 2021-05-11T23:46:09+09:00 https://crieit.net/posts/lambda lambda に感動した <p>Python学習記録2日目<br /> 10年ぐらいVBA一筋の人生を歩んできたので、ささやかなことに一々感動してしまう</p> <h2 id="出来るようになったこと"><a href="#%E5%87%BA%E6%9D%A5%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8">出来るようになったこと</a></h2> <ul> <li>クラス継承とスーパークラスを使った継承<br /> ** VBA ではできないスーパークラスにずっと憧れていた。超便利だった。スーパークラス素敵</li> <li>Dictionary の操作</li> <li>Pandas パッケージをちょろっと</li> <li>map 関数</li> <li>lambda式<br /> ** VBAのFor Each地獄が1行で済んでしまうのに感動して二度とVBAに戻りたくなくなった</li> </ul> Momonga tag:crieit.net,2005:PublicArticle/17085 2021-05-11T09:06:28+09:00 2021-05-11T09:06:28+09:00 https://crieit.net/posts/Python-6099ca840a5d5 Python の学習記録をつけていこうと思う <h2 id="動機"><a href="#%E5%8B%95%E6%A9%9F">動機</a></h2> <p>こういうことも書いていいのだろうか?<br /> 今まで学習記録をブログに書くとかSNSで共有するとかやったことがない<br /> やったことがないことをやってみるのは、微妙にドキドキする<br /> でも悩むのがめんどくさくなったので、学習記録をブログに綴ってみることにする</p> <hr /> <h2 id="できたこと"><a href="#%E3%81%A7%E3%81%8D%E3%81%9F%E3%81%93%E3%81%A8">できたこと</a></h2> <ul> <li>Pythonで MySQL サーバに接続して SELECT する</li> <li>SELECT した行(taple と呼べばよいの?) を行ごとに処理する</li> <li>INSERT する</li> <li>クラスを作る</li> <li>外部クラスとして定義してインポートする</li> <li>インスタンスを生成してディクショナリに入れる</li> </ul> <h2 id="気持ち悪かったこと"><a href="#%E6%B0%97%E6%8C%81%E3%81%A1%E6%82%AA%E3%81%8B%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8">気持ち悪かったこと</a></h2> <p>INSERTしようしたテーブルにはプライマリキーに NotNULL 制約をつけていた。<br /> でもPythonでこのテーブルにINSERT したあとCommit しなかったら、すべてNULL値の行ができてた。<br /> なんでやねん!!!!</p> Momonga tag:crieit.net,2005:PublicArticle/16923 2021-04-21T14:08:10+09:00 2021-04-21T14:52:12+09:00 https://crieit.net/posts/8e0211fd5e77f48de00725f6d1dd4b81 技術ブログの書き方について・・・ <h1 id="よろしくお願いいたします"><a href="#%E3%82%88%E3%82%8D%E3%81%97%E3%81%8F%E3%81%8A%E9%A1%98%E3%81%84%E3%81%84%E3%81%9F%E3%81%97%E3%81%BE%E3%81%99">よろしくお願いいたします</a></h1> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <ul> <li>この記事を書く経緯<br /> 今回、技術ブログ?を書くにあたりそもそも何をすべきなのか理解が及ばなかったため。まとめることとした。</li> <li>何を書くのか<br /> これから書いていくべきものの、スタンスを定める。決意表明みたいなもの。</li> </ul> <h2 id="準備"><a href="#%E6%BA%96%E5%82%99">準備</a></h2> <ul> <li>手順<br /> 1.サイトで調べる<br /> 2.以上!!</li> </ul> <h2 id="説明"><a href="#%E8%AA%AC%E6%98%8E">説明</a></h2> <ul> <li><h4 id="結果の表示"><a href="#%E7%B5%90%E6%9E%9C%E3%81%AE%E8%A1%A8%E7%A4%BA">結果の表示</a></h4> <p>メリット<br /> アウトプットを習慣づけられるとインプットも習慣づけられる<br />    →ネタ不足のため、自分でネタを仕入れるために躍起になる。<br />  <br />  教える側の方が理解度も早い<br />    →教えるためには、自分で理解する必要がある点 <br />     間違っている場合指摘され気づく事ができる点</p> <p>自分の知識の備忘録として<br />    →何がどこにあったか、何を記してあったのかをまとめる場所として最適。</p> <p>デメリット<br /> 文字に起こすのが面倒<br />    →頭の中だけでなく 、書き記すのだから当たり前、メモと変わらない。</p> <p>ネタ探しの時間がかかる<br />    →何か目新しいものを探す旅に出るのが大変</p></li> </ul> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <ul> <li>要点、何が言いたいのか。<br /> 私が調べた感じだと、あくまで自由に並べ立てて良い風に感じたため。<br /> <strong>学んだことを備忘録として残す形に使用していこう</strong>と思う。</li> </ul> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <ul> <li>参考にさせていただいた、リンク等。<br /> きれいに死ぬITエンジニア - エンジニアが技術ブログを書くべき理由 ↓<br /> https://s8a.jp/engineers-should-write-blog</li> </ul> Nakazn tag:crieit.net,2005:PublicArticle/15907 2020-05-22T10:17:55+09:00 2020-05-22T10:17:55+09:00 https://crieit.net/posts/XPath-2-XPath XPath基礎編(2) ー XPathの書き方 <p>前回の記事では、<a href="https://crieit.net/posts/XPath-1-XPath">XPathの基本概念</a>を簡単に紹介しました。今回はXPathによるWebページ(HTML)からデータを指定・取得する方法、つまりXPathの書き方を紹介します。</p> <h1 id="1.タグ(要素)で指定する"><a href="#1.%E3%82%BF%E3%82%B0%EF%BC%88%E8%A6%81%E7%B4%A0%EF%BC%89%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">1.タグ(要素)で指定する</a></h1> <p>下記のHTMLサンプルで、文章が のように、といった記号で囲まれているのが分かります。このようなといった記号を、タグと言います。</p> <pre><code><タグ名>ここにコンテンツが入ります... </タグ名> </code></pre> <p>最初のタグを「開始タグ」、終わりのタグを「終了タグ」といいます。そしてこの開始タグから終了タグまでの全体を、要素と呼びます。</p> <p>下記のHTMLの中で赤色で表示された部分はタグです。(Firefoxで青色、Chromeでは紫色で表示されます。)<br /> <a href="https://crieit.now.sh/upload_images/ac2152aaa3a20ce773412b967f786c335ec5f9c9b9231.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ac2152aaa3a20ce773412b967f786c335ec5f9c9b9231.png?mw=700" alt="image" /></a></p> <p>下記はHTMLでよく見かけるタグのまとめです。詳しくのは<a target="_blank" rel="nofollow noopener" href="https://www.tagindex.com/html5/elements/">この記事</a>を合わせてご覧ください!<br /> <a href="https://crieit.now.sh/upload_images/3b23cd0e54eb80bd11f5914238779f8b5ec5fa2b21fb0.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3b23cd0e54eb80bd11f5914238779f8b5ec5fa2b21fb0.png?mw=700" alt="image" /></a></p> <p><strong>XPathの最も一般的な書き方は、スラッシュ “/” で区切りながらタグを記述します。</strong></p> <p>例えば、このHTMLから『Harry Potter』を取得したい場合は、ツリー構造の上から順に『htmlタグ→bodyタグ→h1タグ』と指定できます。次のように書きます。</p> <pre><code>/html/body/h1 </code></pre> <p>また、『//』を用いて、途中までのパスを省略することができます。</p> <pre><code>//h1 </code></pre> <p><a href="https://crieit.now.sh/upload_images/73909d4648ca098024e571d5d2c90ada5ec5fa7109dbf.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/73909d4648ca098024e571d5d2c90ada5ec5fa7109dbf.png?mw=700" alt="image" /></a></p> <p>タグを複数に合致する場合に、N番目のタグを指定することができます。この例では、『7,631円』を取得する場合、「div」の行から2行目の「span」であるため、次のように書きます。</p> <pre><code>//div/span[2] </code></pre> <p>抽象化にすると、タグ(要素)で書くXPath構文はこうなります。</p> <pre><code>//タグ名 //タグ名/タグ名 </code></pre> <h1 id="2.属性で指定する"><a href="#2.%E5%B1%9E%E6%80%A7%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">2.属性で指定する</a></h1> <p>属性とはタグの中に記載されていて、タグの情報を細かく表すものです。タグに属性をつけることで、要素の効果を指定したり、具体的な指示を付け加えることが出来ます。属性は通常、「id="booksTitle"」のように表示されます。なお、属性は複数指定する事も可能です。</p> <pre><code><タグ名 属性名="属性値"> </code></pre> <p>最も一般的な属性には、href、title、style、src、id、classなどがあります。詳しくはこの記事を合わせてご覧ください!</p> <p><strong>XPathでは属性を『@』の関数で表します。</strong></p> <p>例えば、『Harry Potter』を取得したい場合、XPathは次のように書きます。</p> <pre><code>//h1[@id="booksTitle"] </code></pre> <p><a href="https://crieit.now.sh/upload_images/74f53e19cdd3d7db9d3aaa665416865e5ec5fa9fbdc81.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/74f53e19cdd3d7db9d3aaa665416865e5ec5fa9fbdc81.png?mw=700" alt="image" /></a></p> <p>抽象化にすると、属性で書くXPath構文はこうなります。</p> <pre><code>//タグ名[@属性名="属性値"] </code></pre> <p>もし同じ属性を持つすべての要素を取得する場合、次のように書きます。</p> <pre><code>//*[@属性名="属性値"] </code></pre> <h1 id="3.テキストで指定する"><a href="#3.%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">3.テキストで指定する</a></h1> <p>下記のようにタグで囲まれているのはテキストです。</p> <pre><code><タグ名>ここにテキストが入ります... </タグ名> </code></pre> <p>Webページからデータを取得するのは、通常ページ内のコンテンツまたはテキストを取得することです。ですから、取得したいテキストを直接指定することができます。</p> <p><strong>XPathではテキストを『text()』の関数で表します。</strong></p> <p>例えば、『Harry Potter』を取得したい場合、テキストで指定すると、次のように書きます。</p> <pre><code>//h1[text()="Harry Potter"] </code></pre> <p><a href="https://crieit.now.sh/upload_images/606ad984d03cb33dbcf324b48fe3ef3a5ec5fae570088.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/606ad984d03cb33dbcf324b48fe3ef3a5ec5fae570088.png?mw=700" alt="image" /></a></p> <p>抽象化にすると、属性で書くXPath構文はこうなります。</p> <pre><code>//タグ名[text()="取得するテキスト"] </code></pre> <p>もし同じテキストを持つすべての要素を取得する場合、次のように書きます。</p> <pre><code>//*[text()="取得するテキスト"] </code></pre> <h1 id="4.タグ関係で指定する"><a href="#4.%E3%82%BF%E3%82%B0%E9%96%A2%E4%BF%82%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">4.タグ関係で指定する</a></h1> <p>HTMLのツリー構造において、すべての要素が親子/兄弟関係を持っています。</p> <p>1つまたは複数の要素を含む要素は親要素と呼ばれ、含まれる要素は子要素です。子要素は1つのみの親があり、親の開始タグと終了タグの間にあります。同じ親を持つ要素は兄弟要素と呼ばれます。</p> <p>具体的な例も見てみましょう。</p> <p>以下のサンプルは、[body]要素を基点に、[body]要素は[h1]要素と[div]要素の親で、[h1]要素と[div]要素は、[body]要素の子です。親子/兄弟関係にある要素を取得し、それぞれにスタイルを変更する例です。</p> <p>[h1]要素と[div]要素は、同じ親[body]要素を持つため、兄弟要素です。</p> <p>また、[div]要素は2つの[span]要素の親ですから、2つの[span]要素は[body]要素の子孫要素です。</p> <p><a href="https://crieit.now.sh/upload_images/ac2152aaa3a20ce773412b967f786c335ec5fb00d4eb2.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ac2152aaa3a20ce773412b967f786c335ec5fb00d4eb2.png?mw=700" alt="image" /></a></p> <p>カレント要素を基点として、親子、もしくは兄弟関係にある要素を取得することができます。例えば、『7,631円』を取得したい場合、タグの関係で指定すると、下記のように書くことができます。</p> <ul> <li><strong>[div]要素の子要素とする場合</strong></li> </ul> <pre><code>//div/span[2] </code></pre> <ul> <li><strong>[body]要素の子孫要素とする場合</strong></li> </ul> <pre><code>//body//span[2] </code></pre> <ul> <li><strong>[span class="author notFaded"]要素の兄弟要素とする場合</strong></li> </ul> <pre><code>//span[@class="author notFaded"]/following-sibling::span[1] </code></pre> <ul> <li><strong>[span class="tax_postage"]要素の兄弟要素とする場合</strong></li> </ul> <pre><code>//span[@class="tax_postage"]/preceding-sibling::span[1] </code></pre> <p>兄弟関係のあるタグを指定するには『following-sibling::』と『preceding-sibling::』という2つの関数をよく使います。</p> <p><strong>『following-sibling::』は、指定された要素より後の兄弟要素を指定する<br /> 『preceding-sibling::』は、指定された要素より前の兄弟要素を指定する</strong></p> <p>『following-sibling::』は、テーブル要素を指定する時に大活躍します。例えば、下記のHTMLサンプルがあります。<br /> <a href="https://crieit.now.sh/upload_images/47e4d5aa57d6e1622c851c7ab7d081235ec5fb78228ea.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/47e4d5aa57d6e1622c851c7ab7d081235ec5fb78228ea.png?mw=700" alt="image" /></a></p> <p>このHTMLはページに変更すると、以下のようなテーブルの形になります。<br /> <a href="https://crieit.now.sh/upload_images/d31f11d0dc981223209a01066480dfcd5ec5fb8c89537.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d31f11d0dc981223209a01066480dfcd5ec5fb8c89537.png?mw=700" alt="image" /></a></p> <p>この例では、店名の『12345』取得します。ただし、[td]要素が複数あり、<strong>//td[1]</strong> で対応できなくなります。また、もし複数のページから、同じ構造のテーブルを一括取得する場合、固定的な値「店名」を基点として、『following-sibling::』を使うほうが薦めです。次のように書きます。</p> <pre><code>//th[text()="店名"]/following-sibling::td[1] </code></pre> <p><a href="https://crieit.now.sh/upload_images/bf91fbab825806d55d50077a1188024a5ec5fb9c4b147.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bf91fbab825806d55d50077a1188024a5ec5fb9c4b147.png?mw=700" alt="image" /></a></p> <p>抽象化にすると、タグ関係で書くXPath構文はこうなります。<br /> <a href="https://crieit.now.sh/upload_images/79fa6ebb0e474fa3720643700236f4145ec5fbb4e1ce5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/79fa6ebb0e474fa3720643700236f4145ec5fbb4e1ce5.png?mw=700" alt="image" /></a><br /> もし上記の構文で複数に合致する場合に、<strong>[N]</strong> を付けてN番目のタグを指定することができます。</p> <p>いかがでしょうか?以上は最も使われるXPath書き方です。さっそくお試してみてください。次回はXPathによく使われる関数を紹介します。お楽しみに!</p> <p>元記事:<a target="_blank" rel="nofollow noopener" href="https://helpcenter.octoparse.jp/hc/ja/articles/360013122059">https://helpcenter.octoparse.jp/hc/ja/articles/360013122059</a></p> Octoparse Japan tag:crieit.net,2005:PublicArticle/15905 2020-05-21T12:08:13+09:00 2020-05-21T12:08:13+09:00 https://crieit.net/posts/XPath-1-XPath XPath基礎編(1)ー XPathの基本概念 <p>Webサイト上からデータを自動的に取得するには2つの方法があります。1つはPythonなどのプログラミング言語でWebクローラーを作る、もう1つは<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/top-30-free-web-scraping-software/">Webスクレイピングツール</a>でデータを取得するのです。しかし、どれにしても、XPathは重要な役割を果たしています。XPathの書き方が分かれば、データをより正しくて効率的に取得できます。</p> <p>それでXPathのシリーズではXPathの基本概念からXPathの書き方、応用まで詳しく紹介したいと思います。</p> <p>この記事では、XPathの基本概念を簡単に紹介します。</p> <h1 id="1. XPathとは?"><a href="#1.+XPath%E3%81%A8%E3%81%AF%EF%BC%9F">1. XPathとは?</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://www.octoparse.jp/blog/essential-for-web-scraping-xpath-introduction/">XPath</a> (XML Path Language)とは、ツリー構造となっているXML/HTMLドキュメントからの要素や属性値などを指定するための簡潔な構文(言語)です。<br /> Webページは通常HTMLで記述されるから、XPathはWebページの情報を取得する時によく利用します。ブラウザ(Chrome、Firefoxなど)でWebページのHTMLを表示するする場合、F12キーを押すことで、対応するHTMLドキュメントに簡単にアクセスできます。<br /> <a href="https://crieit.now.sh/upload_images/9df9699255a9f1dfaaa6c977dbd9c7f85ec5ef58a99b5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9df9699255a9f1dfaaa6c977dbd9c7f85ec5ef58a99b5.png?mw=700" alt="image" /></a></p> <h1 id="2. XPathの仕組み"><a href="#2.+XPath%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF">2. XPathの仕組み</a></h1> <p>XPathは具体的にはどのように動作するのかを見てみましょう。下記の画像はHTMLドキュメントの一部です。<br /> <a href="https://crieit.now.sh/upload_images/adab33ab3d7b51a493bb3cfb063f098b5ec5efa851b61.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/adab33ab3d7b51a493bb3cfb063f098b5ec5efa851b61.png?mw=700" alt="image" /></a></p> <p>HTMLは、ツリー構造のように、異なるレベルのがあります。この例では、レベル1は<strong>bookstore</strong>で、レベル2は<br /> <strong>book</strong>です。<strong>Title、author、year、price</strong>はすべてレベル3です。</p> <p>山括弧(など)を含むテキストはタグと呼ばれます。HTMLの要素は通常、開始タグと終了タグで構成され、その間にコンテンツが挿入されます。以下の形になります。</p> <pre><code><○○>(開始タグ)ここにコンテンツが入ります... </○○>(終了タグ) </code></pre> <p>XPathはスラッシュ “/” で区切りながら階層を記述し、基準となるノードから別のノードを指定できます。URLと似ています。この例では、要素「author」を検索する場合、XPathは次のようになります。</p> <pre><code>/bookstore/book/author </code></pre> <p>それがどのように機能するかをよりよく理解するには、コンピューター上の特定のファイルを見つける方法を参照してください。<br /> <a href="https://crieit.now.sh/upload_images/0620d07afe9f4535ee22c558c2a575fb5ec5ef88cc427.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/0620d07afe9f4535ee22c558c2a575fb5ec5ef88cc427.png?mw=700" alt="image" /></a></p> <p>「author」という名前のファイルを見つけるには、正しいファイルパスは <strong>\ bookstore \ book \ author</strong>です。</p> <p>コンピューター上のすべてのファイルには独自のパスがあるように、Webページ上の要素もパスがあります。そのパスはXPathで記述されています。</p> <p>ルート要素(ドキュメントの一番上の要素)から始まり、中にあるすべての要素を経由して目標要素に至るXPathは、絶対XPathと呼ばれます。</p> <pre><code>例: /html/body/div/div/div/div/div/div/div/div/div/span/span/span… </code></pre> <p>絶対XPathは長くて混乱する可能性があるため、絶対XPathを単純化するために、「//」を使用して途中までのパスを省略することができます(短いXPathとも呼ばれる)。</p> <p>たとえば、</p> <pre><code>絶対XPath:  /bookstore/book/author 短いXPath:  //author </code></pre> <h1 id="3. XPathを表示・書くには"><a href="#3.+XPath%E3%82%92%E8%A1%A8%E7%A4%BA%E3%83%BB%E6%9B%B8%E3%81%8F%E3%81%AB%E3%81%AF">3. XPathを表示・書くには</a></h1> <h2 id="【Google Chromeの場合】"><a href="#%E3%80%90Google+Chrome%E3%81%AE%E5%A0%B4%E5%90%88%E3%80%91">【Google Chromeの場合】</a></h2> <p>Chromeでこのページを表示し、右クリックメニューの[検証]から開発者ツールを表示します。Elementタブのhtmlで、要素を右クリックします。メニューの[Copy] → [Copy XPath ] でその要素を取得するためのXPathがクリップボードにコピーされます。<br /> <a href="https://crieit.now.sh/upload_images/7abc7bfcf22757417e5d1de2508ecd645ec5efc5ddd9d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7abc7bfcf22757417e5d1de2508ecd645ec5efc5ddd9d.png?mw=700" alt="image" /></a></p> <p>表示されているElementタブのhtmlから “Ctrl + F” で検索欄を表示します。XPathを入力すると、得られる要素が選択されるはずです。<br /> <a href="https://crieit.now.sh/upload_images/26083b025f9b75340b4e0133bc0d3c885ec5efd93cb43.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/26083b025f9b75340b4e0133bc0d3c885ec5efd93cb43.png?mw=700" alt="image" /></a></p> <p>また、「XPath Helper」という拡張機能を追加することもできます。XPathを入力すると、一致する結果が表示されます。(<a target="_blank" rel="nofollow noopener" href="https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?hl=zh-CN">XPath Helperをインストールする</a>)<br /> <a href="https://crieit.now.sh/upload_images/2a1ec783d7eb286b630a0cec3a3a6a0f5ec5efeb6a203.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/2a1ec783d7eb286b630a0cec3a3a6a0f5ec5efeb6a203.png?mw=700" alt="image" /></a></p> <p>​</p> <h2 id="【Firefoxの場合】 "><a href="#%E3%80%90Firefox%E3%81%AE%E5%A0%B4%E5%90%88%E3%80%91%E3%80%80">【Firefoxの場合】 </a></h2> <p>Firefoxの旧バージョンに搭載されている拡張機能「Firebug」が利用できます。(<a target="_blank" rel="nofollow noopener" href="https://helpcenter.octoparse.jp/hc/ja/articles/360015765193-Firebug-FireXPath%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95">Firebug&FireXPath拡張機能をインストールする方法</a>)</p> <p>FirefoxでWebページを開く➡Firebugボタンをクリック➡ページ内の要素をクリック➡その要素のXPathが表示されます。<br /> <a href="https://crieit.now.sh/upload_images/f00ff934aa298fe710ed30ead91c5db95ec5f00a607c0.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f00ff934aa298fe710ed30ead91c5db95ec5f00a607c0.png?mw=700" alt="image" /></a></p> <p>以上はXPathの基本概念でした。次回はXPathの書き方を紹介しますので、お楽しみにしてください!</p> <p>元記事:<a target="_blank" rel="nofollow noopener" href="https://helpcenter.octoparse.jp/hc/ja/articles/360015765513">https://helpcenter.octoparse.jp/hc/ja/articles/360015765513</a></p> Octoparse Japan tag:crieit.net,2005:PublicArticle/15621 2019-12-18T23:02:34+09:00 2019-12-18T23:02:34+09:00 https://crieit.net/posts/Rails6-Ruby Rails6 ビューファイルにRubyのコード書く時の<% %>と<%= %>の違い <h1 id="&lt;% %&gt;と&lt;%= %&gt;の違い"><a href="#%26lt%3B%25+%25%26gt%3B%E3%81%A8%26lt%3B%25%3D+%25%26gt%3B%E3%81%AE%E9%81%95%E3%81%84"><% %>と<%= %>の違い</a></h1> <ul> <li>: この中に書いたコードは表示されない。変数定義やif文などの記載に使う。</li> <li>: この中に書いたコードは表示される。ビューファイル上に変数の値を表示したい時などに使用する</li> </ul> miriwo: 19年7月7日からQiita毎日投稿中! tag:crieit.net,2005:PublicArticle/15305 2019-08-07T08:16:34+09:00 2019-08-07T08:16:34+09:00 https://crieit.net/posts/cb6050dd0fc495cbd9e3aec214eed697 アウトプット始めました <p><strong>はじめに</strong></p> <hr /> <p>情報系を学んでいる大学3年生です。<br /> 文章を書くことに慣れておらず、言い回しが変であったり、意味がわからないという部分が多々あると思いますが、ご了承ください。</p> <p><strong>きっかけ</strong></p> <hr /> <p>なぜ、大学3年生のこの時期にアウトプットをし始めようかと思ったかというと、、、</p> <p>単に暇そうだったからです笑笑</p> <p>3年前期のテストが終わり夏休みと入りましたが、私は9月にインターシップに3週間ほど行かせてもらうのですが、その勉強をするという名目でバイトに入らないという決断をしました。</p> <p>バイトに入らないと1日がとても長いです笑笑</p> <p>勉強ばかりでは、飽きてしまうこともあるかなと思い、暇つぶしと勉強したことの復習の一石二鳥ということで、アウトプットしてみようと考えました。</p> <p><strong>これから</strong></p> <hr /> <p>私はとても飽きっぽくて、3日坊主のことなんてザラにあります。</p> <p><del>買ったばっかりのゲーム、ギター、スケボー、日記、スケジュール帳、、、</del></p> <p>最初は頑張ろうと思うんですけどね笑笑</p> <p>しかし、今回は周りの意識の高まりから負けてはいられないと思うので、毎日やったことを書いていけたらいいなと思います。いや、書いていきます!</p> <p>質問や変なところがあったら、どんどん指摘していただきたいです。</p> <p>以上!<br /> 今後に期待していただきたいです</p> yusuke yamashita