{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/blog/20211107/",
    "result": {"data":{"site":{"siteMetadata":{"title":"Juicy Blog 🍋"}},"markdownRemark":{"id":"92953565-2afe-51fe-8ebd-954c300e6c81","excerpt":"いつ頃購入したかは定かではないのですが、Raspberry Pi(以下raspi)の初代と3Bを所持していました。\nこれとは別に自宅サーバを何台か動かしているのですが、突発的にraspiを動かしたくなりました。\nraspi 3B…","html":"<p>いつ頃購入したかは定かではないのですが、Raspberry Pi(以下raspi)の初代と3Bを所持していました。\nこれとは別に自宅サーバを何台か動かしているのですが、突発的にraspiを動かしたくなりました。\nraspi 3Bはまだしもさすがに初代をこのご時世に使うのは非常に厳しいものがあります。</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ ssh pi-1 lscpu\nArchitecture:        armv6l\nByte Order:          Little Endian\nCPU(s):              1\nOn-line CPU(s) list: 0\nThread(s) per core:  1\nCore(s) per socket:  1\nSocket(s):           1\nVendor ID:           ARM\nModel:               7\nModel name:          ARM1176\nStepping:            r0p7\nCPU max MHz:         700.0000\nCPU min MHz:         700.0000\nBogoMIPS:            697.95\nFlags:               half thumb fastmult vfp edsp java tls</code></pre></div>\n<p>完全にシングルスレッドでCPUの周波数も700MHzしかありません。\nそれでもこのブレッドボードが販売されたときはブラウザが動かせるのがウリでした。\n初代のraspiをどう使おうか考えた結果、センサの類はいずれ試すとしてとりあえずスクレイピングでもしておこうかと思いました。</p>\n<p>最初はAxiosとJSDOMの組み合わせを考えていたのですが、スクレイピングをしようと思ったサイトはJavaScriptがないと動かない様子。\nというわけでPuppeteerとRaspbianをインストールしたときに使えるChromiumブラウザを使うことにしました。\n幸いAnsibleとかはすぐ使えちゃうようなので、以下のタスクでサクッと必要なパッケージをインストールしてみます。(このタスク自体はサクッと書けたのですが、インストールが完了するまではしばし辛抱が必要です)</p>\n<div class=\"gatsby-highlight\" data-language=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token punctuation\">---</span>\n<span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Install packages\n  <span class=\"token key atrule\">apt</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"{{ item }}\"</span>\n    <span class=\"token key atrule\">state</span><span class=\"token punctuation\">:</span> present\n  <span class=\"token key atrule\">with_items</span><span class=\"token punctuation\">:</span>\n    <span class=\"token punctuation\">-</span> git\n    <span class=\"token punctuation\">-</span> nodejs\n    <span class=\"token punctuation\">-</span> npm\n    <span class=\"token punctuation\">-</span> node<span class=\"token punctuation\">-</span>sqlite3\n    <span class=\"token punctuation\">-</span> chromium<span class=\"token punctuation\">-</span>browser\n    <span class=\"token punctuation\">-</span> fonts<span class=\"token punctuation\">-</span>ipafont<span class=\"token punctuation\">-</span>mincho\n    <span class=\"token punctuation\">-</span> fonts<span class=\"token punctuation\">-</span>ipafont<span class=\"token punctuation\">-</span>gothic</code></pre></div>\n<p>ここでのポイントはまずnvmなどのようなバージョン管理ツールを使うのは現実的ではありません。\n少なくとも私の場合は一度のビルドに時間がかかりすぎるうえビルド中にクラッシュしてしまいデバッグしようという気持ちにもなりませんでした。</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ ssh pi-1 node -v\nv10.24.0\n$ ssh pi-1 npm -v\n5.8.0</code></pre></div>\n<p>Raspbianが提供しているNode.jsは2021年11月の時点で<code class=\"language-text\">10.24.0</code>なのでBabelを使わなくてもよいし、Promiseも使えるし、Puppeteerのインストールも弾かれるわけでもなく、そんなに古いわけでもありません。\nただし、npmのほうは少々厳しいですね。\nインストールができればよいくらいのスタンスでそれ以外は期待しないほうがよいと思います。\nnode-sqlite3も後ほど使う予定なのですが、とりあえずこれを入れておけば<code class=\"language-text\">node install</code>したときにビルドに失敗したりSQLが実行できないということはなくなるはず。\nChromiumをインストールするだけだと、日本語が表示できないのでIPAのフォントをインストールしておくとよいです。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> puppeteer <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"puppeteer\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> option <span class=\"token operator\">=</span> process<span class=\"token punctuation\">.</span>env<span class=\"token punctuation\">.</span><span class=\"token constant\">NODE_ENV</span> <span class=\"token operator\">===</span> <span class=\"token string\">\"production\"</span>\n  <span class=\"token operator\">?</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">product</span><span class=\"token operator\">:</span> <span class=\"token string\">\"chrome\"</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">executablePath</span><span class=\"token operator\">:</span> <span class=\"token string\">\"/usr/bin/chromium-browser\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> browser <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> puppeteer<span class=\"token punctuation\">.</span><span class=\"token function\">launch</span><span class=\"token punctuation\">(</span>option<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> page <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">newPage</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\npage<span class=\"token punctuation\">.</span><span class=\"token function\">setDefaultNavigationTimeout</span><span class=\"token punctuation\">(</span><span class=\"token number\">300000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\npage<span class=\"token punctuation\">.</span><span class=\"token function\">setDefaultTimeout</span><span class=\"token punctuation\">(</span><span class=\"token number\">300000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>つづいてPuppeteerの書き方について。\nシステムにインストールされているChromiumブラウザを使いたいので<code class=\"language-text\">puppeteer-core</code>を選ぼうと思ったんですが、開発環境ではChromiumをいちいちインストールするのも面倒なので<code class=\"language-text\">puppeteer</code>を指定しています。\n<code class=\"language-text\">npm install</code>するとき環境変数で<code class=\"language-text\">PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1</code>を指定しないと時間を無駄にするので気をつけましょう。\nそして<code class=\"language-text\">NODE_ENV</code>でターゲットのraspiの環境で<code class=\"language-text\">executablePath</code>を指定してあげるようにします。\n<code class=\"language-text\">setDefaultNavigationTimeout</code>と<code class=\"language-text\">setDefaultTimeout</code>にデフォルトの30秒だと<strong>短すぎるので</strong>タイムアウトを300秒に指定します。\nこれは単純にCPUがボトルネックになっているため、昨今のようなJavaScriptを多用しているようなサイトだとまず間違いなく処理しきれないためです。</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/091af234f4bcac765125fad570d404bf/374ac/forecastCity-20211107_0541.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 27.848101265822784%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABO0lEQVQY002QSY7bMBBFdf875CBZ9C7IPp2OoyC2bLdbA0VSHEQN1sAXiL1JFT4K9euhFj/7cy5oru8sw8hRO7BFiEfHT43zwv2j4ny+cL3e2PeY2O0/lhiTn8VfXzE/XnjL/1IUZ5byDoPB2wXjE0p0gv3bF04/X8nznKK4cCsuUN1gsLiD7dNPMl38xjcP6rZDaYsTgtFapHQoM6FNIC5PytfvnE45UpkkIRRBKkJn6LqAUAO+n8iKhyDMMS19eGL7iVZ7PiqBNp77e8W6w0MYpPYYG9CmR3ceZQNlrWiVoapbWtmRKdnSNDXWGpyzeOdQUqK1Ytu2lNW6rlijEaKhFSLdDv6YVVUmb56nxGZKO2qheZQCqRzWj4RxSRrGhXHasH6iOSLpPGXV0giN1I4+zInrh+cnP638A8SEx02fXzBiAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"天気の画像\"\n        title=\"天気の画像\"\n        src=\"/static/091af234f4bcac765125fad570d404bf/f058b/forecastCity-20211107_0541.png\"\n        srcset=\"/static/091af234f4bcac765125fad570d404bf/c26ae/forecastCity-20211107_0541.png 158w,\n/static/091af234f4bcac765125fad570d404bf/6bdcf/forecastCity-20211107_0541.png 315w,\n/static/091af234f4bcac765125fad570d404bf/f058b/forecastCity-20211107_0541.png 630w,\n/static/091af234f4bcac765125fad570d404bf/374ac/forecastCity-20211107_0541.png 634w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>これがRaspberry Piで上記のコードを用いてスクレイピングした画像の一部です。\n普段そこまで天気を気にすることはないのですが、雨が降りそうなときは予めアラート飛ばすくらいはできそうです。</p>\n<p>raspi 3bは何に使うかというと、こちらはリソースに余裕があるため<a href=\"https://github.com/pi-hole/pi-hole\">Pi-hole</a>をインストールして運用することにしました。</p>\n<p>これは何か簡単に説明すると、raspiで<strong>好ましくないサイトやドメインをブロックする</strong>ことができます。\n最も身近な例で言えばGoogle Analyticsのデータ収集を防ぎたいと思うと、本来であればPCごとにあるhostsファイルを編集します。\n最近では<a href=\"https://github.com/StevenBlack/hosts\">hosts</a>というようなプロジェクトもあるのですが、例えばiOSやAndroidでは編集できませんし、PCをクリーンインストールするたびにこのセットアップをするのも面倒です。\nPi-holeがインストールされているraspiをネームサーバーに指定すれば問題が解決するというわけ。</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">curl -sSL https://install.pi-hole.net | bash</code></pre></div>\n<p>インストールしたばかりの状態であれば特に問題なくpi-holeのインストールスクリプトで多少時間はかかるものの問題なくインストールできました。\nデフォルトでさきほど紹介したhostsが指定されているようなのでこれでも充分といえば充分です。\n追加で<a href=\"https://firebog.net/\">https://firebog.net/</a>と<a href=\"https://dbl.oisd.nl\">https://dbl.oisd.nl</a>をブロックリストに追加しておきました。</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">curl https://analytics.google.com/\ncurl: (7) Failed to connect to analytics.google.com port 443: Connection refused</code></pre></div>\n<p>あとは<code class=\"language-text\">curl</code>なりブラウザなりでGoogle Analyticsに<strong>アクセスできない</strong>ことがわかればセットアップは成功です。\nもともと初代raspiもdnsmasqなんかを使って簡易的なDNSサーバとして使っていたことを思い出しましたが、Pi-holeにも同様の機能はありそうなのでモバイルの開発もはかどりそうです。\nraspi 3bはポート80をpi-holeに渡してしまいましたが、リソース的に余裕があればSambaなどもセットアップしたいと思ってます。</p>\n<p>結局フィジカルコンピューティングをしたくて購入したはずが、Linuxしかやることがなくて使いみちを失ってしまいがちなraspiたちでしたが、センサの類を使わなくてもまだまだ工夫のしがいはありそうです。</p>","frontmatter":{"title":"Long Live Pi","date":"November 07, 2021","description":"眠っていたRaspberry Piを再利用する方法について"}},"previous":{"fields":{"slug":"/blog/20211017/"},"frontmatter":{"title":"Expo AVで動画を再生する"}},"next":{"fields":{"slug":"/blog/20211127/"},"frontmatter":{"title":"ActiveStorageでRSpecのtips"}}},"pageContext":{"id":"92953565-2afe-51fe-8ebd-954c300e6c81","previousPostId":"0a716a63-9ffe-5aae-ba1e-b041729e27b4","nextPostId":"471e9f76-b44c-560c-98c1-afc798c0094e"}},
    "staticQueryHashes": ["2785349746","2841359383"]}