- 投稿日:2022-01-25T18:33:33+09:00
yarnのインストール(Windows)
はじめに 以前、自分が使っている古い方のPCで、Reactを使おうと思ってyarnをインストールしたのですが、パスが通っていないのかコマンドが認識されず、yarnが実行できない。 思い切って新しいPC(Surface Pro8)の方でもう一度インストールしてみようと思って、再度挑戦しました。 ちなみにyarnとは、Facebook社(現メタ社)によって開発された、npmよりも処理が早いJavaScriptのパッケージ管理システムです。よくnpmの上位互換として紹介されているので、流行に乗って使えたほうが良いかなと奮闘中です。ReactもFacebookによる開発ですよね。Facebookはこの辺りの事情に精通しているのでしょうか。 作業環境 PC: SurfacePro8 OS: Windows11 使用ターミナル: コマンドプロンプト その他必要環境: node.js、npm 手順 何はともあれ、まずは公式ドキュメント!ということで、yarnpkg.comのGETTING STARTED → Installationの手順を試してみることに。 最初に、「yarnを使うのは、Corepackを通して扱うのが良い」という趣旨のことが書いてあるので、素直にCorepackを使おうと $corepack enable と実行すると、 そのコマンドは許可されていません、と出ます。node.jsフォルダの中のnpmファイルを見るように指示があるものの、見てもよく分からない...。エラーメッセージを元にあれこれ調べてみたものの、明確な解決策は見つかりませんでした。 「要するに管理者じゃないからダメなんでしょ?ええい、管理者でゴリ押してしまえ」と半ばヤケクソになって「管理者権限 コマンドプロンプト」と検索。どうやらコマンドプロンプトのアプリアイコンを右クリックすれば管理者権限で入れるみたいなので、管理者権限として入った後、再度実行。 ......できました。あまりにもあっけないです。必要なのは、管理者権限で実行してよいのかという不安に打ち勝つ勇気のみですね。 あとは、公式ドキュメントの手順に沿って、npm i -g corepack、 yarn init -2 というコマンドを順に実行するだけです。何やら不穏なエラーメッセージが出ていてこの先が不安ですが、とりあえず良しとしましょう。ん?できてない?一応実行したディレクトリ下に「.yarn」というディレクトリと、package.jsonができているので、できているということにしましょう。またこの辺りで問題が起こったら、記事にするかもしれません。 総論 とりあえず何をするにも、公式ドキュメントのGETTING STARTEDが正義です。このような環境構築系は特に、公式ドキュメントや、エラーメッセージ内ででてきたリンクを参考にするのが一番手っ取り早いと思いました。 参考 公式ドキュメント https://yarnpkg.com/getting-started/install 最後のエラー時に参考として出てきた公式ドキュメントのページ。 https://classic.yarnpkg.com/en/docs/cli/init yarn initで何が行われ、どのようにyarnを初期化しているかについては分かりやすく載っているものの、今回のエラーの原因は突き止められませんでした。 Corepackについて https://nodejs.org/dist/latest/docs/api/corepack.html 管理者権限でコマンドプロンプトに入る方法 https://solutions.vaio.com/2663
- 投稿日:2022-01-25T17:03:45+09:00
Pythonスクレイピング【GCP - cloud functions - サンプルコード付】
はじめに 普段は、firebase cloud functionsで サーバー側の処理を記述しています。 今回も、node環境のサーバーでスクレイピングを行なっていたのですが 処理に時間がかかる・メモリが多く必要になるという理由で スクレイピングに関しては、python3で記述することにしました。 ちなみに、nodeでのスクレイピングは下記のnpmを使用していました。 npm i puppeteer 下記システムは、こちらのサイトでも使用しています。 Pythonの記述・ディレクトリ構造 今回は、GCPのcloud functionsの方に pythonのファイルをデプロイしたので、ディレクトリ構造の説明もしていきたいと思います。 ディレクトリ構造 ディレクトリ構造 pythonFunctions ├ main.py ├ getMetaFromSoup.py ├ requirements.txt ├ .gcloudignore └ README.md main.py[サンプルコード] main.pyは サーバー側で一番はじめに処理が実行されるファイルになります。 関数【getMeta()】では、URLからHTMLファイルを読み込んでいます。 main.py # -*- coding: utf-8 -*- import requests import bs4 from flask import jsonify # import from getMetaFromSoup import getTitle, getDescription, getImage, getDomain def getMeta(request): # クエリ文字列を取得 if request.args and 'url' in request.args: request_name = request.args.get('url') url = request_name # URL html = requests.get(url) soup = bs4.BeautifulSoup(html.content, "html.parser") params = { "title": getTitle(soup), "description": getDescription(soup), "image": getImage(soup), "domain": getDomain(url), } # 必要に応じて変更を行なってください。 headers = { 'Access-Control-Allow-Origin': 'http://yapoyapo.com/' } return (jsonify(params), 200, headers) getMetaFromSoup.py[サンプルコード] 実際にスクレイピングを行なっているファイルになります。 ※入れた方がいいmeta情報があればご共有お願いします! getMetaFromSoup.py from urllib.parse import urlparse # タイトルを取得 def getTitle(soup): title = soup.find('meta', attrs={'property': 'og:title'}) if (str(title) != 'None'): return title.get('content') title = soup.find('title') if (str(title) != 'None'): return title.text title = soup.find('meta', attrs={'name': 'twitter:title'}) if (str(title) != 'None'): return title.get('content') title = soup.find('h1') if (str(title) != 'None'): return title.text return '' # ディスクリプションを取得 def getDescription(soup): description = soup.find('meta', attrs={'property': 'og:description'}) if (str(description) != 'None'): return description.get('content') description = soup.find('description') if (str(description) != 'None'): return description.text description = soup.find('meta', attrs={'name': 'twitter:description'}) if (str(description) != 'None'): return description.get('content') description = soup.find('meta', attrs={'name': 'description'}) if (str(description) != 'None'): return description.get('content') # 画像を取得 def getImage(soup): image = soup.find('meta', attrs={'property': 'og:image'}) if (str(image) != 'None'): return image.get('content') image = soup.find('link', attrs={'rel': 'image_src'}) if (str(image) != 'None'): return image.get('href') image = soup.find('meta', attrs={'name': 'twitter:image'}) if (str(image) != 'None'): return image.get('content') image = soup.find('meta', attrs={'name': 'twitter:image:src'}) if (str(image) != 'None'): return image.get('content') image = soup.find('img') if (str(image) != 'None'): return image.get('href') # ドメインを取得 def getDomain(url): return urlparse(url).netloc requirements.txt[サンプルコード] requirements.txtでは、pipのバージョン管理を行なっています。 ローカルPCのpipのバージョンはpip listで確認できます。 requirements.txt urllib3==1.26.4 beautifulsoup4==4.10.0 requests==2.25.1 .gcloudignore[サンプルコード] .gcloudignoreでは サーバー側に必要のない情報を記載しています。 .gitignoreのような役割を担っています。 .gcloudignore README.md 最後に 重要なファイルは ・main.py ・requirements.txt になります。 また、本記事で紹介した方法で こちらのサイトを運営していますので、ぜひ使ってみてください!
- 投稿日:2022-01-25T16:33:47+09:00
localサーバー(localhost)を立ち上げる
以下のQiita記事の再現をするため、localサーバーを立ち上げようとしたが苦戦したため、手順について記載する。 Node.jsから起動 ローカルサーバーを立ち上げる Node.js上で、serveと叩き緑の文字でServing!と表示されたら成功。 Local: http://localhost:~ をコピーして、エクスプローラーに張り付けて画面が表示(場合によっては白画面)になればOK。 ローカルサーバーを終了する ショートカットキー[ctrl]+[c]で落とす。「INFO: Gracefully shutting down. Please wait...」の表示がされたらOK。接続が切れるまでちょっと時間がかかる。(しばらくコマンドが打てなくなる) サーバーが起動されているのに立ち上がらない場合 起動したいhtmlを開いても、上記画面になってしまいlocalhostが起動しない場合の対応方法。 ディレクションが正しくない Terminalのコマンド画面で、表示させたいディレクション(フォルダ)に設定されていない場合、起動しない。cd フォルダのパスを打って、表示させたいhtmlが置いてあるフォルダになるように設定する。 上記の場合は、「D:\~\~\~\root\docs」フォルダ内のhtmlを起動したいので、cdコマンドで指定している。
- 投稿日:2022-01-25T08:53:10+09:00
Notion API + LINE + AWS Lambda他でメモ内容をLINEにしゃべらせる
野望 相も変わらずNotionをDBに用いたLINE Bot的なものが作りたいです。 前回のあらすじ Notion APIの前にまずはLINE Messaging APIの検証から始めました。 どうやら用意したLINE公式アカウントで受信したテキストをもとに応答をすることができるようになったっぽいです。 https://qiita.com/DJROU/items/900e3c32b87b5d43d8ed 今回やったこと いきなりNotionを繋げて読み込みと書き込みをできるようにするのは荷が重いので、LINE公式アカウントに対してユーザが送ったテキストをNotionで検索した結果を返せるようにしました。 指定したDBのキーに対する値がゲットできるところまでのお試しです。 手順 ①Notionでテーブルの準備 ②Notionでトークンの設定 ②Lambdaのコードを変更する ①Notionでテーブルの準備 まず、Notionのユーザ登録なりなんなりでリストやテーブルを使えるようにしましょう。 無料プランでOKです。 ここではデータの格納先となるテーブルを準備します。 Notionのメニュー > ワークスペースから新規作成して、テーブルを選択します。 自分はこんな感じで作りました。 以降、本記事ではkeyをキー、valueを値とします。 ②Notionでトークンの設定 ここでは、テーブルが置いてあるところ(ワークスペースというらしい)単位で一意のトークンを払い出してみましょう。 Notion > メニュー > 設定 > インテグレーションを開きます。 さらに「独自のインテグレーションを開発する」からインテグレーション自体の設定画面に移ります。 こんなページで設定します。 新しいインテグレーションを作成しましょう。 名前を付けて権限を設定します。私は今後書き込みもしたいので全部盛りにしました。 送信したらトークンができるはずです。 このトークンはあとでLambdaで使用するので控えておきます。 先ほどのテーブルに戻ってこのトークンでのアクセスを許可しましょう。 テーブル編集画面の右上にある「共有」から、先ほど作成したインテグレーションを招待します。 以下のように追加されます。 ③Lambdaのコードを変更する API Referenceからコードをおパクリ申し上げました。 https://developers.notion.com/reference/post-database-query 一部前話と重複する説明は省略します。 前話:https://qiita.com/DJROU/items/900e3c32b87b5d43d8ed routest.js 'use strict'; const line = require('@line/bot-sdk'); const { Client } = require("@notionhq/client"); const notionToken = "Notionで作成したトークン"; const databaseId = '後述するデータベースのID'; const notion = new Client({ auth: notionToken, }); const client = new line.Client({ channelAccessToken: 'LINEのチャンネルアクセストークン' }); exports.handler = (event, context, callback) => { console.log("event.body:", event.body); let requestMessage = JSON.parse(event.body).events[0].message.text; let replyToken =JSON.parse(event.body).events[0].replyToken; (async () => { const responseId = await notion.databases.query({ database_id: databaseId, filter: { or: [ { "property": "key", "text": { "contains": requestMessage } }, ], }, }); let replyText = responseId.results[0].properties.value.rich_text[0].text.content; let message = { type: 'text', text: replyText }; client.replyMessage(replyToken, message).then((data) => { console.log(data); callback(null, "OK"); }).catch((err) => { console.log("だめでし"); callback(err, "NG"); }); })(); }; 1. モジュールとかトークンとか routest.js 'use strict'; const line = require('@line/bot-sdk'); const { Client } = require("@notionhq/client"); const notionToken = "Notionで作成したトークン"; const databaseId = '後述するデータベースのID'; const notion = new Client({ auth: notionToken, }); const client = new line.Client({ channelAccessToken: 'LINEのチャンネルアクセストークン' }); Node.jsで使用するモジュールは「@line/bot-sdk」「@notionhq/client」です。 Lambdaのレイヤーで使えるようにしましょう。 (参考) https://qiita.com/DJROU/items/bcdc2902757e606e9226 databaseIdはNotionで作成したデータベースを指定するIDです。 Notionの画面上から取得しましょう。 テーブル編集画面の右上にある「共有」から、「リンクをコピー」を押します。 ここでコピーされたURLのうち「notion.so/より後・?」より前がデータベースのIDです。 '後述するデータベースのID'のとこに書きましょう。 (例)太字のところ(URLを無効にするために空白を入れています) https:// ww w.notion.so/samplehogehoge12345aaaaa54321?v=samplehugahuga98765bbbbb56789 2. 本体 routest.js exports.handler = (event, context, callback) => { let requestMessage = JSON.parse(event.body).events[0].message.text; let replyToken =JSON.parse(event.body).events[0].replyToken; (async () => { const responseId = await notion.databases.query({ database_id: databaseId, filter: { or: [ { "property": "key", "text": { "contains": requestMessage } }, ], }, }); let replyText = responseId.results[0].properties.value.rich_text[0].text.content; let message = { type: 'text', text: replyText }; client.replyMessage(replyToken, message).then((data) => { console.log(data); callback(null, "OK"); }).catch((err) => { console.log("だめでし"); callback(err, "NG"); }); })(); }; async/awaitの使い方には自信がありません。 notion.databases.queryでNotionのページ(データベース)とキーを検索しています。 「key」という項目が「requestMessage」(LINEで受け取った文字列)を含むときでフィルタしています。orの階層が必要かどうかは未検証です。 routest.js filter: { or: [ { "property": "key", "text": { "contains": requestMessage } }, ], }, notion.databases.queryでリクエストした値はresponseId.results[0].properties.value.rich_text[0].text.contentに入ってきます。奥ぃ。 最後に前回はLINEでオウム返ししていたところをNotionで受け取った値にしてreplyMessageしています。 できあがり keyにない投稿を受け取ったときの処理を書いていないのが課題です。 (画像の「あ」「平井堅」のところ) 次回予告 今のNotionデータベースを使用して、keyとvalueのセットを書き込んでみるらしいです。
- 投稿日:2022-01-25T08:35:42+09:00
VSCode+Textlintで文章校正をする
はじめに Visual Studio Code(VSCode)+textlintで文章校正をするための導入手順です。 環境 Windows11 64bit Visual Studio Code version 1.63 Node.js v16.13.2 npm 8.1.2 textlint v12.1.0 textlintとは 文章を書く時に表記揺れや誤字脱字、読みにくい表現などを校正してくれるツールです。 公式サイト textlint · The pluggable linting tool for text and markdown Qiitaの記事の下書きを、VSCodeを使ってMarkdownで書くことが多いのですが、textlintを使用すれば自動で文章校正ができます。 導入手順 導入手順について説明していきます。 以下の記事も参考にしてみてください。 作者のazuさんによる導入方法についての記事です。 textlintで日本語の文章をチェックする - Web Scratch ドットインストールでも導入方法について動画で紹介されています。 textlint入門 (全11回) - プログラミングならドットインストール Node.jsのインストール textlintを導入するためにはNode.jsが必要となります。 既にインストールされている人は次に進んでください。 Node.js公式サイトからNode.js(推奨版)をダウンロードする ダウンロードしたファイルを実行し、画面の指示に従って進んでいき、Node.jsをインストールする PowerShellを立ち上げて、以下のコマンドを実行し、Node.jsがインストールされたことを確認する node -v Node.jpと一緒にnpm(Node Package Manager)もインストールされているはずなので確認する npm -v textlintのインストール VSCode上でtextlintの環境を作っていきます。 VSCodeを開き、任意のフォルダ、もしくはWorkspeaceを開く 今回は「D:\Workbooks」というフォルダを作成し、VSCodeで開きました。 VSCodeからは必ずフォルダかWorkspeaceを開いてください。ファイルそのものを開いてしまうとtextlintが正しく作業しません。 VSCodeでターミナルを開き、「D:\Workbooks」へ移動する Workspeaceで開いた場合は、「Workbooks.code-workspace」ファイルがあるディレクトリへ移動してください。 ターミナルで以下のコマンドを実行し、プロジェクト管理用ファイルを作成する(「package.json」が作成される) npm init -y textlintをインストールする(「node_modules」と「package-lock.json」が作成される) npm install --save-dev textlint textlintのバージョンを表示し、インストールできたことを確認する ./node_modules/.bin/textlint -v もし以下のようなエラーが出た場合は、実行ポリシーの変更をしてください。 実行ポリシーの変更(現在のプロセスのみ有効) Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process Textlintの校正ルールをインストールする npm install --save-dev textlint-rule-preset-ja-technical-writing npm install --save-dev textlint-rule-preset-jtf-style ルールはいろいろあるのですが、自分はこの2つのルールを使用しています。 textlint-rule-preset-ja-technical-writing 技術文書を書くためのルールのプリセット(「1文の長さは100文字以下とする」や「ら抜き言葉」など) textlint-rule-preset-JTF-style JTF日本語標準スタイルガイド(翻訳用)に準拠しているプリセット ルールを有効にする設定ファイルを作成する(「.textlintrc」が作成される) npx textlint --init .textlintrcの中身は以下のようになっており、これを編集することで適用したいルールを変更できます。 { "filters": {}, "rules": { "preset-ja-technical-writing": true, "preset-jtf-style": true } } 拡張機能「vscode-textlint」のインストール textlintをVSCode上で動かすための拡張機能をインストールします。 拡張機能から「vscode-textlint」を検索する インストールする VSCodeを再起動する もしtextlintがうまく起動しない場合は、以下の設定をする textlintの設定画面を開く textlint: Node Pathに「node_modules」フォルダが存在するフォルダのパスを入力する これで、VSCode上でtextlintを使用して文章が自動校正されるようになりました。 参考にしたサイト textlintで日本語の文章をチェックする - Web Scratch(最終アクセス2022年1月25日) textlint入門 (全11回) - プログラミングならドットインストール(最終アクセス2022年1月25日) textlint と VS Code で始める文章校正 - Qiita(最終アクセス2022年1月25日)