ミライハック https://www.geek.sc アウフヘーベン Mon, 21 Aug 2023 10:36:14 +0000 ja hourly 1 https://www.geek.sc/wp-content/uploads/2017/06/nekotodon.com-9d80b0e49b404db3.png ミライハック https://www.geek.sc 32 32 99425232 「項目をゴミ箱へ移動する際にエラーが発生しました。」エラーの解決策 https://www.geek.sc/archives/3389 <![CDATA[齊藤貴義]]> Sun, 12 Dec 2021 10:47:19 +0000 <![CDATA[インターネット]]> https://www.geek.sc/?p=3389 <![CDATA[

WordPressで記事を削除しようとするとエラーになる WordPressで下書きの記事を削除しようとすると「項目をゴミ箱へ移動する際にエラーが発生しました。」というエラーになる場合があります。 複数選択してゴミ箱に移 ... ]]>
<![CDATA[

WordPressで記事を削除しようとするとエラーになる

WordPressで下書きの記事を削除しようとすると「項目をゴミ箱へ移動する際にエラーが発生しました。」というエラーになる場合があります。

複数選択してゴミ箱に移そうとしても同じエラーになります。

解決策

解決策としては記事にタイトルを付けて保存します。タイトルは何でもかまいません。

これでゴミ箱に削除できるようになります。

]]>
3389
「wp_enqueue_script() が誤って呼び出されました」エラーの対処法 https://www.geek.sc/archives/3372 <![CDATA[齊藤貴義]]> Fri, 10 Dec 2021 07:51:55 +0000 <![CDATA[インターネット]]> <![CDATA[システム開発]]> https://www.geek.sc/?p=3372 <![CDATA[

WordPressアップグレードでウィジェットが崩れるエラー発生 WordPressのアップグレードでウィジェットのページが崩れて正常に表示されなくなりました。WordPressのデバッグを有効にすると以下のメッセージが ... ]]>
<![CDATA[

WordPressアップグレードでウィジェットが崩れるエラー発生

WordPressのアップグレードでウィジェットのページが崩れて正常に表示されなくなりました。WordPressのデバッグを有効にすると以下のメッセージが表示されました。

wp_enqueue_script() が誤って呼び出されました。”wp-editor” script should not be enqueued together with the new widgets editor (wp-edit-widgets or wp-customize-widgets).

このエラーの場合、テーマのfunctions.phpに以下のコードを追加すると解消します。

function phi_theme_support() {
    remove_theme_support( 'widgets-block-editor' );
}
add_action( 'after_setup_theme', 'phi_theme_support' );
]]>
3372
FujiSSL GOでSSL証明書を自動更新する https://www.geek.sc/archives/3293 <![CDATA[齊藤貴義]]> Sun, 31 Jan 2021 13:47:39 +0000 <![CDATA[システム開発]]> https://www.geek.sc/?p=3293 <![CDATA[

FujiSSL GOとは FujiSSL GOは、FujiSSLが提供する証明書の自動更新システムです。Let’s Encryptのような形でCUIで証明書を自動更新できます。従来のような秘密鍵やCSRファイルの生成、証 ... ]]>
<![CDATA[

FujiSSL GOとは

FujiSSL GOは、FujiSSLが提供する証明書の自動更新システムです。Let’s Encryptのような形でCUIで証明書を自動更新できます。従来のような秘密鍵やCSRファイルの生成、証明書の申請などの手続きが必要なく、簡単に証明書を発行・更新できます。今回はそのFujiSSL GOを使った証明書の作成手順をご紹介します。

SSLサーバ証明書自動更新システムFujiSSL GO

FujiSSL GOアカウントの作成

FujiSSL GOを使用するにはアカウントが必要です。FujiSSL GOマネジメントコンソールにアクセスします。

アカウントがない場合は、アカウントを作成します。

アカウント作成後に確認メールが送信されますのでクリックします。

以下の画面が表示されればアカウントの作成は完了です。

FujiSSL GOの証明書の購入

FujiSSL GOのアカウントを作成したら、次に証明書を購入します。FujiSSL GOマネジメントコンソールにログインします。

左のサイドメニューから「証明書」をクリックします。

右上の「証明書の購入」をクリックして証明書の購入画面へ進みます。購入したい証明書の数を選択して、「上記の内容で証明書の購入を確定」をクリックします。

デポジットが不足している場合は、左のサイドメニューから「お支払い」をクリックして、クレジット決済または銀行振込でデポジットをチャージします。

証明書を購入後、証明書の契約コードと注文コードをメモします。

FujiSSL GOクライアントのインストール

サーバーにFujiSSL GOクライアントをインストールします。今回は/etc/fujisslにインストールしましたが、インストール場所は任意の場所でかまいません。

$ wget https://console.fujissl.jp/files/fujissl-go-0.0.2.zip
$ unzip fujissl-go-0.0.2.zip
$ mv fujissl-go-0.0.2 fujissl
$ sudo mv fujissl /etc/fujissl
$ cd /etc/fujissl
$ sudo php ./bin/fujissl-go create geek(任意のconfファイル名)

ここまで実行できた段階で、/etc/fujissl/conf/geek(任意の名前).confというファイルが生成されます。

ファイル生成時に、PHPのタイムゾーンが設定されていないと以下のワーニングが出る場合があります。

PHP Warning:  date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /etc/fujissl/lib/Log.php on line 1

ワーニングを無視して作業することもできますが、このエラーは/etc/php.iniに以下の記述を記載することで解消します。

date.timezone = Asia/Tokyo

FujiSSL GOのconfファイルの編集

作ほど生成されたconfのファイルを編集します。

config:
  appid: *********(先ほどメモした契約コード)
  ordid: *********(先ほどメモした注文コード)
  fqdn: www.geek.sc(ドメイン名)
  document_root: /var/www/html(ドキュメントルート)
  backup_dir: /etc/fujissl/backup(バックアップディレクトリ)
  private_key: /etc/fujissl/private.key(作成する秘密鍵のフルパス)
  certificate: /etc/fujissl/certificate.crt(作成する証明書のフルパス)
  ca_bundle: /etc/fujissl/bundle.crt(作成する中間調名書のフルパス)

FujiSSL GOによる証明書の登録

confファイルを設定できたら、以下のコマンドで証明書の登録を行います。

$ sudo php ./bin/fujissl-go regist -c www.geek.sc -f geek.conf

以下のメッセージが出れば登録は完了です。

Create /var/www/html/.well-known/pki-validation/fileauth.txt file.
Create /etc/fujissl/backup/www.geek.sc/private.key file.
The certificate registed was successful.
Register the following command in cron:
/usr/bin/php /etc/fujissl/bin/fujissl-go autorenew -c www.geek.sc -f geek.conf

しかし、この段階ではまだ登録完了後の審査中で、証明書ファイルは作成されていません。証明書ファイルが作成されるまで何度か以下のコマンドを実行する必要があります。証明書の更新の時にも使用しますので、1日1回くらいの頻度でCRONに登録しておくと良いでしょう。

/usr/bin/php /etc/fujissl/bin/fujissl-go autorenew -c www.geek.sc -f geek.conf

数時間後には、confで指定したパスに証明書ファイルおよび中間証明書ファイルが作成されました。

]]>
3293
リングフィットアドベンチャー・ダウンロード版の使い方 https://www.geek.sc/archives/3088 <![CDATA[齊藤貴義]]> Mon, 13 Jul 2020 09:32:14 +0000 <![CDATA[ゲーム]]> https://www.geek.sc/?p=3088 <![CDATA[

リングフィットアドベンチャー・ダウンロード版の購入方法 リングコンという専用コントローラを使って気軽にフィットネスやダイエットができるNintendo Switchのリングフィットアドベンチャーは、現在も品薄状態が続いて ... ]]>
<![CDATA[

リングフィットアドベンチャー・ダウンロード版の購入方法

リングコンという専用コントローラを使って気軽にフィットネスやダイエットができるNintendo Switchのリングフィットアドベンチャーは、現在も品薄状態が続いていて、Amazonや楽天では高額で転売もされています。

何とか転売屋を使わずに定価で買いたい人は、任天堂のMy Nintendo Storeや家電量販店の抽選を利用すると良いでしょう。私もMy Nintendo Storeでダウンロード版(DL版)を購入しました。ダウンロード版もパッケージ版と同じくリングコンなどの付属品は全て同梱されています。唯一の違いはソフトが付属しないことだけです。ソフトウェアはMy Nintendo Storeからダウンロードする形になります。追加料金は発生しません。

パッケージ版 ダウンロード版
リングコン ⭕ ⭕
レフトバンド ⭕ ⭕
パッケージソフト ⭕ ❌

本記事では、My Nintendo Storeでリングフィットアドベンチャーのダウンロード版を購入した場合のスイッチへの導入方法を解説していきます。

運良くMy Nintendo StoreでリングフィットアドベンチャーのDL版の在庫があったら、カートへ追加をクリックします。

「注文を確定する」で注文完了です。支払い方法としてクレジットカード、PayPal、My Nintendo Switchのニンテンドーeショップの残高などを使用することができます。

注文後は、ダウンロード版の発送まで待ちます。パッケージ版と同様にリングコンが任天堂から宅急便で発送されます。

リングフィットアドベンチャー・ダウンロード版が到着したら

リングフィットアドベンチャー・ダウンロード版が到着したら早速開封してみましょう。

箱はパッケージ版とダウンロード版は全く同一です。

「筋肉は一生の相棒」

ダウンロード版では同梱されているのはリングコンとレッグバンドのみです。Switchにソフトウェアをダウンロードしましょう。

Switchへのリングフィットアドベンチャーのダウンロード方法

リングフィットアドベンチャーは、Nintendo eショップには登録されておらず、検索しても出ててきません。My Nintendo Storeの注文履歴またはメールからアクティベートする必要があります。以下は注文履歴からアクティベーションする方法です。

「リングフィットアドベンチャー」の注文履歴の中ほどに、「引き換え番号」と「今すぐ引き換える」リンクがあります。

「今すぐ引き換える」をクリックします。

確認画面が表示されますので、「引き換える」をクリックします。

引き換えが完了しました。手持ちのスイッチに自動的にリングフィットアドベンチャーのインストールが開始します。なお、この「今すぐ引き換える」は何度も押すことができますので、いったんリングフィットアドベンチャーのソフトをアンインストールしても、ここから再び再インストールできます。

ソフトウェア一覧にリングフィットアドベンチャーが追加されました。

筋肉は裏切らない。さあリングコンにコントローラーを装着して筋トレを開始しましょう。

私もリングフィットアドベンチャーをやり始めて少し痩せました。運動強度は調整できるので自分に合った無理の無い運動がオススメです。あと運動後にプロテインを摂ると良いでしょう。

]]>
3088
ModuleNotFoundError: No module named *エラーへの対応 https://www.geek.sc/archives/3075 <![CDATA[齊藤貴義]]> Thu, 11 Jun 2020 17:19:10 +0000 <![CDATA[システム開発]]> https://www.geek.sc/?p=3075 <![CDATA[

pip3でインストールしたライブラリでModuleNotFoundError: No module namedエラーが出る pip3コマンドでreppyというrobots.txtのパーサライブラリをインストールしていたの ... ]]>
<![CDATA[

pip3でインストールしたライブラリでModuleNotFoundError: No module namedエラーが出る

pip3コマンドでreppyというrobots.txtのパーサライブラリをインストールしていたのですが、Jupyter Notebookからは正常に実行できるのですが、ファイルに書いてPython3コマンドで実行しようとするとModuleNotFoundErrorが出力されました。

ModuleNotFoundError: No module named 'reppy'

Pip3とPython3で参照しているパスが違う

原因としてはPip3とPython3で参照しているパスが違ったようです。以下のコマンドでライブラリをインストールしたところ、Python3コマンドで正常に実行できるようになりました。

python3 -m pip install reppy

ちなみにPython実行時にどのパスを参照しているかを調べるには、以下のコードで調査できます。

import sys
print(sys.prefix)
print(sys.path)
]]>
3075
SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version *への対応 https://www.geek.sc/archives/3060 <![CDATA[齊藤貴義]]> Tue, 09 Jun 2020 14:09:47 +0000 <![CDATA[システム開発]]> https://www.geek.sc/?p=3060 <![CDATA[

SeleniumのChromeDriverでエラー PythonでSeleniumのWebDriverを扱っているとよくこのエラーが出ますよね。 SessionNotCreatedException: Message: ... ]]>
<![CDATA[

SeleniumのChromeDriverでエラー

PythonでSeleniumのWebDriverを扱っているとよくこのエラーが出ますよね。

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81

インストールされているChromeとChrome WebDriverのバージョンが違うとこのエラーが出ます。そのたびにChrome WebDriverのページから対応するChrome WebDriverをインストールしてパスを通して…とやると面倒ですよね。

webdriver_managerライブラリ

そんな時にPythonのwebdriver_managerライブラリを使うと少し便利です。まず最初にpip3コマンドでwebdriver_managerをインストールします。

pip3 install webdriver-manager

このwebdriver_managerを使うと、最初に対応ドライバがない場合は自動的にインストールするようにコードを書くことができます。

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())

ドライバのインストールが始まります。

[WDM] - Cache is valid for [09/06/2020]
[WDM] - Looking for [chromedriver 83.0.4103.39 mac64] driver in cache 
[WDM] - Trying to download new driver from http://chromedriver.storage.googleapis.com/83.0.4103.39/chromedriver_mac64.zip
 
[WDM] - Unpack archive /Users/faust/.wdm/drivers/chromedriver/83.0.4103.39/mac64/chromedriver.zip

インストールしたドライバーをそのままSeleniumで使用することができます。

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get("https://www.google.com")

これでWebスクレイピングが少し快適になりました。

]]>
3060
macOSでPNGファイルをJPEGファイルに一括変換する https://www.geek.sc/archives/3046 <![CDATA[齊藤貴義]]> Tue, 02 Jun 2020 07:06:54 +0000 <![CDATA[システム開発]]> https://www.geek.sc/?p=3046 <![CDATA[

大量のPNGファイルをJPEGに変換したい JPEGしか対応していないプロジェクトに対応するため、Macで大量のPNGファイルをJPEGに変換する必要が出てきました。ネットで検索するとフォルダアクションで自動的に変換する ... ]]>
<![CDATA[

大量のPNGファイルをJPEGに変換したい

JPEGしか対応していないプロジェクトに対応するため、Macで大量のPNGファイルをJPEGに変換する必要が出てきました。ネットで検索するとフォルダアクションで自動的に変換する記事が多数出てくるのですが、フォルダアクションで変換するとExif情報に問題があるようでRe:VIEWでrake pdf時に以下のエラーが出力されました(Re:VIEW Starterだとextractbbコマンドを呼び出さないためエラーは出ません)。

extractbb:warning: JPEG: Inconsistent resolution may have specified in Exif and JFIF: 144x144 - 72x72
extractbb:warning: JPEG: Inconsistent resolution may have specified in Exif and JFIF: 144x144 - 72x72
extractbb:warning: JPEG: Inconsistent resolution may have specified in Exif and JFIF: 144x144 - 72x72
extractbb:warning: JPEG: Inconsistent resolution may have specified in Exif and JFIF: 144x144 - 72x72
extractbb:warning: JPEG: Inconsistent resolution may have specified in Exif and JFIF: 144x144 - 72x72
extractbb:warning: JPEG: Inconsistent resolution may have specified in Exif and JFIF: 144x144 - 72x72

mogrifyコマンドで変換する

ImageMagickのmogrifyコマンドでPNGからJPEGへ一括変換できるとTwitterで教えてもらいました。

まずImageMagickをインストールします。

$ brew install imagemagick

PNG画像があるディレクトリに移動して、mogrifyコマンドで一括変換を行います(元のPNGファイルも残されます)。

$ mogrify -format jpeg *.png

これでJPEGファイルへ一括変換されました。ffmpegを導入している場合は下記のコマンドでも同様のことができます。

for i in *.png; do ffmpeg -i $i ${i%.png}.jpeg;done

憶えておくと便利ですね。

]]>
3046
Spotted dirty metadata bufferエラーの対応方法 https://www.geek.sc/archives/3028 <![CDATA[齊藤貴義]]> Sat, 23 May 2020 08:00:56 +0000 <![CDATA[LInux]]> https://www.geek.sc/?p=3028 <![CDATA[

fsckが実施できない ディスク障害が起き、ディスク交換を行ってスナップショットから復元しても、ファイルシステムの論理的整合性が保たれない状態が続きました。対応として起動時にfsckを実行しようと下記のコマンドでファイル ... ]]>
<![CDATA[

fsckが実施できない

ディスク障害が起き、ディスク交換を行ってスナップショットから復元しても、ファイルシステムの論理的整合性が保たれない状態が続きました。対応として起動時にfsckを実行しようと下記のコマンドでファイルを準備しました。

$ touch /forcefsck

Liuuxではルートパーティションに/forcefsckというファイルが存在すると、起動時に自動的にfsckを実行します。しかし、起動中にSpotted dirty metadata bufferというエラーが出てfsckが実行されませんでした。

kernel: EXT4-fs (xvda): mounted filesystem with ordered data mode. Opts: (null)
kernel: EXT4-fs error (device xvda): ext4_mb_generate_buddy:757: group 1650, block bitmap and bg descriptor inconsi
stent: 9657 vs 9506 free clusters
kernel: JBD2: Spotted dirty metadata buffer (dev = xvda, blocknr = 0). There's a risk of filesystem corruption in c
ase of system crash.

Rescue modeで起動してfsckを実行

自動的なfsckが実行できなかったため、サーバー起動時のブートローダー選択でレスキューモードを選択して起動させました。起動したところで以下のコマンドを実行して手動でfsckを実施しました。

# fsck -t ext4 /dev/xvda

これでディスクの論理的整合性が保たれて起動できるようになりました。

]]>
3028
Yumでsqlite3.DatabaseError: database disk image is malformedエラーが出る場合の解決法 https://www.geek.sc/archives/3015 <![CDATA[齊藤貴義]]> Fri, 22 May 2020 11:49:33 +0000 <![CDATA[LInux]]> https://www.geek.sc/?p=3015 <![CDATA[

Yumでsqlite3.DatabaseError: database disk image is malformedエラー 障害があったCentOSサーバーでsudo yum upgradeを実行しようとしたのですが、 ... ]]>
<![CDATA[

Yumでsqlite3.DatabaseError: database disk image is malformedエラー

障害があったCentOSサーバーでsudo yum upgradeを実行しようとしたのですが、以下のようにPythonのエラーと共に”sqlite3.DatabaseError: database disk image is malformed”というSQLiteのDBエラーが出て中断してしまうことがありました。

$ sudo yum upgrade
…
Traceback (most recent call last):
  File "/usr/bin/yum", line 29, in 
    yummain.user_main(sys.argv[1:], exit_code=True)
  File "/usr/share/yum-cli/yummain.py", line 375, in user_main
    errcode = main(args)
  File "/usr/share/yum-cli/yummain.py", line 281, in main
    return_code = base.doTransaction()
  File "/usr/share/yum-cli/cli.py", line 817, in doTransaction
    resultobject = self.runTransaction(cb=cb)
  File "/usr/lib/python2.7/site-packages/yum/__init__.py", line 1944, in runTransaction
    self.verifyTransaction(resultobject, vTcb)
  File "/usr/lib/python2.7/site-packages/yum/__init__.py", line 2076, in verifyTransaction
    self.history.sync_alldb(po)
  File "/usr/lib/python2.7/site-packages/yum/history.py", line 1358, in sync_alldb
    if not self._wipe_anydb(ipkg, "rpm"):
  File "/usr/lib/python2.7/site-packages/yum/history.py", line 1352, in _wipe_anydb
    executeSQL(cur, sql, (pid,))
  File "/usr/lib/python2.7/site-packages/yum/sqlutils.py", line 168, in executeSQLQmark
    return cursor.execute(query, params)
sqlite3.DatabaseError: database disk image is malformed

sudo yum clean allを実行してリポジトリ情報をクリアしても失敗します。最終的には下記のコマンドでエラーなくアップグレードできました。

$ sudo yum clean dbcache

yum clean dbcacheは、Yumのメタデータに高速アクセスするためのsqliteファイルを削除するコマンドです。yum clean allは/var/cache/yum/のエントリを削除するコマンドのため、yum clean allだけでは削除できないDBキャッシュが存在するようです。yum clean dbcacheでそれを削除できました。Yumのキャッシュ削除には以下のコマンドがあるため状況に応じて試してみるのが良いでしょう。

sudo yum clean all          # /var/cache/yumディレクトリ内のエントリを全て削除
sudo yum clean metadata     # XMLメタデータを削除
sudo yum clean dbcache      # SQLiteのDBキャッシュファイルを削除
sudo yum makecache              # キャッシュを再作成
]]>
3015
Squidでプロキシサーバーを構築 https://www.geek.sc/archives/3002 <![CDATA[齊藤貴義]]> Mon, 11 May 2020 08:27:41 +0000 <![CDATA[システム開発]]> https://www.geek.sc/?p=3002 <![CDATA[

Squidでプロキシサーバーの構築 Squidを使ったプロキシサーバーの構築について解説します。Squidはオープンソースのプロキシサーバーのミドルウェアです。今回はCentOS7 / AmazonLinux2を例に解説 ... ]]>
<![CDATA[

Squidでプロキシサーバーの構築

Squidを使ったプロキシサーバーの構築について解説します。Squidはオープンソースのプロキシサーバーのミドルウェアです。今回はCentOS7 / AmazonLinux2を例に解説していきます。まず最初にSquidをインストールします。

$ sudo yum install squid

次に/etc/squid/squid.confを編集します。まずファイル中ほどにある「http_access deny all」をコメントアウトします。次いでファイルの最後に以下を追記します。

# 自分のグローバルIPアドレスだけを接続許可
acl allowadress src [クライアントのIPアドレス]/255.255.255.255
http_access allow allowadress
http_access deny all
# プロキシサーバーの情報の秘匿
forwarded_for off
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
request_header_access Cache-Control deny all
# ポート番号(デフォルトは3128番ですが攻撃対象になるため変更した方が良いです)
http_port 53891
# キャッシュを残さないように設定
no_cache deny all

Squidデーモンを起動させます。

$ sudo systemctl start squid

クライアント側からの確認

クライアントからcurlコマンドで、Webのコンテンツが取得できるかやグローバルIPアドレスが書き換わっているかを確認します。

$ curl --proxy http://[プロキシサーバーのIPアドレス]:53891 http://httpbin.org/ip

プロキシサーバーのIPアドレスが表示されれば成功です。「curl: (7) Failed to connect to ... port 5389: Connection refused」などのエラーメッセージが表示される場合はネットワークやファイアウォールの設定に問題がある可能性があります。

]]>
3002
ハローワークから求人情報をスクレイピングする https://www.geek.sc/archives/2975 <![CDATA[齊藤貴義]]> Sun, 03 May 2020 19:39:02 +0000 <![CDATA[システム開発]]> https://www.geek.sc/?p=2975 <![CDATA[

Python + Selenium + Beautiful Soupでハロワをスクレイピング Python3でSelenium(ChromeDriver)とBeautiful Soupを使って、ハローワークの求人情報を取 ... ]]>
<![CDATA[

Python + Selenium + Beautiful Soupでハロワをスクレイピング

Python3でSelenium(ChromeDriver)とBeautiful Soupを使って、ハローワークの求人情報を取得する方法についてです。今回は東京都千代田区の求人情報を取得しようと思います。

ハローワーク

実装方法

まず最初にライブラリを読み込みます。

from selenium import webdriver
from selenium.webdriver.support.ui import Select
import time
from bs4 import BeautifulSoup

Chrome Driverを起動し、ハローワークのトップページにアクセスさせます。

url = "https://www.hellowork.mhlw.go.jp/"

driver = webdriver.Chrome()
driver.get(url)
time.sleep(1)

求人情報検索ボタンをクリックさせます。

driver.find_element_by_class_name("retrieval_icn").click()
time.sleep(1)

就業場所のセレクトボックスから東京都を選択させます。

element = driver.find_element_by_id("ID_tDFK1CmbBox")
Select(element).select_by_value("13")
time.sleep(1)

市区町村の選択ボタンをクリックします。

driver.find_element_by_id("ID_Btn").click()
time.sleep(1)

モーダルが起動したところで千代田区を選択させて決定ボタンをクリックさせます。

element = driver.find_element_by_id("ID_rank1CodeMulti")
Select(element).select_by_value("13101")
time.sleep(1)

driver.find_element_by_id("ID_ok").click()
time.sleep(1)

モーダルが閉じたところで検索ボタンをクリックさせます。

driver.find_element_by_id("ID_searchBtn").click()
time.sleep(1)

検索画面のHTMLをBeautiful Soupで解析します。

soup = BeautifulSoup(driver.page_source, "html.parser")

求人情報はkyujinというクラス名がついたテーブルで区切られているため、テーブルの情報を取得します。

jobs = soup.find_all("table", attrs={"class": "kyujin"})

今回は取得したテーブル情報からタイトルと待遇を抽出します。

message = ""
for i, job in enumerate(jobs):
    job_name = str(job.find("td", attrs={"class": "m13"}).text.strip())
    salary_tags = job.find_all("tr",attrs={"class": "border_new"})[5].select(".disp_inline_block")
    for t, salary_tag  in enumerate(salary_tags):
        job_salary = salary_tag.text
    message = message + "■{0} ( {1} ) \n".format(job_name, job_salary)

最後にこの結果を出力してブラウザを閉じます。

print(message)
driver.close()

一連の実装まとめ

一連の実装をまとめると以下の通りとなります。

from selenium import webdriver
from selenium.webdriver.support.ui import Select
import time
from bs4 import BeautifulSoup

url = "https://www.hellowork.mhlw.go.jp/"

driver = webdriver.Chrome()
driver.get(url)
time.sleep(1)

driver.find_element_by_class_name("retrieval_icn").click()
time.sleep(1)

element = driver.find_element_by_id("ID_tDFK1CmbBox")
Select(element).select_by_value("13")
time.sleep(1)

driver.find_element_by_id("ID_Btn").click()
time.sleep(1)

element = driver.find_element_by_id("ID_rank1CodeMulti")
Select(element).select_by_value("13101")
time.sleep(1)

driver.find_element_by_id("ID_ok").click()
time.sleep(1)

driver.find_element_by_id("ID_searchBtn").click()
time.sleep(1)

soup = BeautifulSoup(driver.page_source, "html.parser")
jobs = soup.find_all("table", attrs={"class": "kyujin"})[1::]

message = ""
for i, job in enumerate(jobs):
    job_name = str(job.find("td", attrs={"class": "m13"}).text.strip())
    salary_tags = job.find_all("tr",attrs={"class": "border_new"})[5].select(".disp_inline_block")
    for t, salary_tag  in enumerate(salary_tags):
        job_salary = salary_tag.text
    message = message + "■{0} ( {1} ) \n".format(job_name, job_salary)

print(message)
driver.close()

実行結果は以下の通りとなります。ハローワークの求人結果が取得できました。

]]>
2975
GCPのNatural Language APIで感情分析を行う https://www.geek.sc/archives/2691 <![CDATA[齊藤貴義]]> Fri, 24 Jan 2020 03:45:32 +0000 <![CDATA[システム開発]]> https://www.geek.sc/?p=2691 <![CDATA[

GCPのNatural Language APIで感情分析 GCP(Google Cloud Platform)では、Natural Language(自然言語解析)に関するAPIを提供しています。このAPIを活用するこ ... ]]>
<![CDATA[

GCPのNatural Language APIで感情分析

GCP(Google Cloud Platform)では、Natural Language(自然言語解析)に関するAPIを提供しています。このAPIを活用することでテキストの感情分析を行うこともできます。例えばそのテキストがポジティブな話題であるのがネガティブな話題であるのかなどが推定できます。この記事では、GCPのNatural Language APIを使った感情分析の基本について解説していきます。

GCPでプロジェクトを作成する

GCP(Google Cloud Platform)で感情分析を行う方法を解説していきます。まずGCPでプロジェクトを作成します。

今回はPythonで感情分析を実装していきます。続いてGoogle Cloud AIと機械学習プロダクトのクイックスタートを開きます。

「始める前に」の「プロジェクトの設定」ボタンをクリックします。

ポップアップが開いたら先ほど作成したプロジェクトを選択して「NEXT」を選びます。

秘密鍵のJSONファイルがダウンロードできるようになります。ダウンロードボタンを押して秘密鍵をローカルに保存します。

続いて.bashrcまたは.zshrcに、ダウンロードしたJSONのパスをGOOGLE_APPLICATION_CREDENTIALSという環境変数としてセットします。

export GOOGLE_APPLICATION_CREDENTIALS="/ダウンロードしたJSONのパス/*********.json"

pipまたはpip3コマンドを使ってGCPのクラウドストレージ関連ライブラリをインストールします。

$ pip3 install --upgrade google-cloud-storage

これでGoogle Cloud Platformの感情分析が使えるようになりました。さっそく感情分析してみましょう。ここでは「メロスは激怒した」というテキストの感情分析を行います。

# Imports the Google Cloud client library
from google.cloud import language
from google.cloud.language import enums
from google.cloud.language import types

# Instantiates a client
client = language.LanguageServiceClient()

# The text to analyze
text = u"メロスは激怒した。"
document = types.Document(
    content=text,
    type=enums.Document.Type.PLAIN_TEXT)

# Detects the sentiment of the text
sentiment = client.analyze_sentiment(document=document).document_sentiment

print('Text: {}'.format(text))
print('Sentiment: {}, {}'.format(sentiment.score, sentiment.magnitude))

このコードを実行した結果は以下の通りとなりました。

Text: メロスは激怒した。
Sentiment: -0.30000001192092896, 0.30000001192092896

出力されたSentimentの2種類の値は、それぞれscore(+1.0〜-1.0の間の値を取る。+1.0近いほどポジティブな感情で、-1.0に近いほどネガティブな感情)とmagnitude(テキストの感情の強度を示す)です。

ドキュメントの感情分析の score は、ドキュメントの全体的な感情を示します。ドキュメントの感情分析の magnitude は、そのドキュメントに感情的な内容がどのくらい含まれているかを示します。この値は、ドキュメントの長さに比例する傾向があります。
…score の値がニュートラル(ほぼ 0.0)なドキュメントは、感情的でない場合もあれば、ポジティブとネガティブの両方の値が高いために互いに相殺されている混合的なドキュメントである場合もあります。通常は、magnitude の値を使用してこの曖昧さを取り除くことができます。本当にニュートラルなドキュメントは magnitude の値が低くなりますが、混合的なドキュメントは高くなります。

今回の出力結果はscoreが-0.3になっておりmagnitudeは0.3です。ネガティブな文章であると判定できています。

複数行にわたる感情分析を行いたいときは以下のように記述すると良いでしょう。

# -*- coding: utf-8 -*-
# Imports the Google Cloud client library
from google.cloud import language
from google.cloud.language import enums
from google.cloud.language import types

# Instantiates a client
client = language.LanguageServiceClient()

# The text to analyze
 text = u"""
聞いて、メロスは激怒した。
「あきれた王だ。生かしておけぬ。」"""
document = types.Document(
    content=text,
    type=enums.Document.Type.PLAIN_TEXT)

# Detects the sentiment of the text
sentiment = client.analyze_sentiment(document=document).document_sentiment

print('Text: {}'.format(text))
print('Sentiment: {}, {}'.format(sentiment.score, sentiment.magnitude))

出力結果は以下のようになります。

Text:
聞いて、メロスは激怒した。
「あきれた王だ。生かしておけぬ。」

Sentiment: -0.20000000298023224, 2.0

GCPのストレージから感情分析を行う

GCPのストレージにアップロードしたファイルからテキストを抽出して感情分析を行うこともできます。バケットを作成してテキストファイルをアップロードしてみましょう。

「GCP」→「Storage」→「ブラウザ」と開き、バケット作成画面を開きます。

バケットに名前をつけ、リージョンを選択します。今回はテストですので単一リージョンで良いでしょう。

続いてバケットにファイルをアップロードします。今回は青空文庫からダウンロードした太宰治『人間失格』のテキストファイルをningen_shikkaku.txtとしてアップロードしました。

続いて以下のコードを記述して実行します。

from google.cloud import language
from google.cloud.language import enums
from google.cloud.language import types

gcs_uri = 'gs://バケット名/アップロードしたファイル名.txt'

client = language.LanguageServiceClient()

# Instantiates a plain text document.
document = types.Document(
    gcs_content_uri=gcs_uri,
    type=enums.Document.Type.PLAIN_TEXT)

# Detects sentiment in the document. You can also analyze HTML with:
#   document.type == enums.Document.Type.HTML
sentiment = client.analyze_sentiment(document).document_sentiment

print('Score: {}'.format(sentiment.score))
print('Magnitude: {}'.format(sentiment.magnitude))

30分ほどテキストの感情分析が行われた後、以下の結果が出力されました。

Score: 0.0
Magnitude: 84.9000015258789

Scoreはプラスマイナス0。長い文章から感情のスコアを読み取ると中立的になるのかもしれません。ただMagnitudeは84で『人間失格』がかなり感情の起伏が激しい文章であると読み取っています。

トラブルシューティング1

google.api_core.exceptions.Unauthenticated: 401 Permission to access the GCS address is denied.

このようなエラーが出る場合は、バケットの閲覧権限が付与されていません。以下のコマンドでアクティベートしましょう。

$ gcloud auth activate-service-account --key-file=最初にダウンロードしたプロジェクトの秘密鍵JSONファイルのパス

正常に実行されると以下のような出力が返ってきます。

Activated service account credentials for: [starting-account-***********@プロジェクトID.iam.gserviceaccount.com]

このアカウントIDをGCPのStoregeで閲覧権限のあるユーザーとして追加すれば正常に実行できるようになります。

トラブルシューティング2

Cannot move files across regions. Please use a regional bucket in the same location and with same storage class as AutoML. Required Location: us-central1, required location type: Region, required storage class: Standard.

上記のようなエラーが出力された場合は、バケットのリージョンとAutoMLのリージョンが合っていない可能性が高いです。バケットのリージョンを確認しましょう。

]]>
2691
AWSでEC2インスタンスを構築した時の初期ユーザー https://www.geek.sc/archives/2610 <![CDATA[齊藤貴義]]> Mon, 02 Sep 2019 16:48:39 +0000 <![CDATA[LInux]]> <![CDATA[インフラ]]> https://www.geek.sc/?p=2610 <![CDATA[

ディストリビューション別AWS初期ユーザー AWSでLinuxのEC2インスタンスを構築した時の初期ユーザーについてまとめました。以下のユーザーでSSHログインできsudoを実行することができます。 ディストリ 初期ユー ... ]]>
<![CDATA[

ディストリビューション別AWS初期ユーザー

AWSでLinuxのEC2インスタンスを構築した時の初期ユーザーについてまとめました。以下のユーザーでSSHログインできsudoを実行することができます。

ディストリ 初期ユーザー
AmazonLinux ec2-user
Centos centos
RHEL ec2-user
Fedora Core fedora
Ubuntu ubuntu
Debian admin
openSUSE ec2-user
Arch Linux root

実際にEC2を構築した場合はAMIの種類によって上記の表と異なる場合があります。

]]>
2610
MacでDNSキャッシュをクリアする方法 https://www.geek.sc/archives/2593 <![CDATA[齊藤貴義]]> Fri, 16 Aug 2019 14:26:59 +0000 <![CDATA[システム開発]]> https://www.geek.sc/?p=2593 <![CDATA[

MacのDNSキャッシュをクリアしたい Macで特定ドメインに対してなぜかdigやnslookupコマンドで引けるIPアドレスとPINGで引けるIPアドレスが違っていたので、DNSリゾルバキャッシュを削除したいと思いまし ... ]]>
<![CDATA[

MacのDNSキャッシュをクリアしたい

Macで特定ドメインに対してなぜかdigやnslookupコマンドで引けるIPアドレスとPINGで引けるIPアドレスが違っていたので、DNSリゾルバキャッシュを削除したいと思いました。

MacでDNSリゾルバキャッシュはコンソールを開いて以下のコマンドで削除することができます。

$ sudo killall -HUP mDNSResponder

原因は /etc/hosts に特定ドメインとIPアドレスを記述していたためでした…。

WindowsでのDNSキャッシュクリア

WindowsでDNSレゾルバキャッシュクリアをしたい場合は、PowerShellまたはコマンドプロンプトで以下のコマンドで削除できます。

$ ipconfig /flushdns
]]>
2593
Unable to revert mtime: /Library/Fontsエラーについて https://www.geek.sc/archives/2536 <![CDATA[齊藤貴義]]> Sat, 13 Jul 2019 16:02:24 +0000 <![CDATA[インターネット]]> <![CDATA[システム開発]]> https://www.geek.sc/?p=2536 <![CDATA[

Pythonのスクレイピング処理でエラー PythonでSeleniumパッケージを使った処理を実行しようとしたのですが、以下のエラーになりました。 Unable to revert mtime: /Library/Fo ... ]]>
<![CDATA[

Pythonのスクレイピング処理でエラー

PythonでSeleniumパッケージを使った処理を実行しようとしたのですが、以下のエラーになりました。

Unable to revert mtime: /Library/Fonts

NotADirectoryError: [Errno 20] Not a directory: 'chromedriver'

原因はChromeDriver

原因としてはChromeDriverがインストールされていなかったようです。

公式だとこちらからダウンロードできますが、私のMacの場合うまく動きませんでした。

brewコマンドで追加したところ正常に動作しました。

$ brew install caskroom/cask/brew-cask
$ brew cask install chromedriver

これでエラーも出なくなりました。

]]>
2536
Peer’s Certificate issuer is not recognized.エラー https://www.geek.sc/archives/2528 <![CDATA[齊藤貴義]]> Fri, 12 Jul 2019 17:51:41 +0000 <![CDATA[インターネット]]> <![CDATA[システム開発]]> https://www.geek.sc/?p=2528 <![CDATA[

HTTPSを設定したサイトでPeer’s Certificate issuer is not recognized.エラーになる HTTPSを設定したサイトでFirefoxで開くと以下のエラーになっていました。 Peer ... ]]>
<![CDATA[

HTTPSを設定したサイトでPeer’s Certificate issuer is not recognized.エラーになる

HTTPSを設定したサイトでFirefoxで開くと以下のエラーになっていました。

Peer’s Certificate issuer is not recognized.

HTTP Strict Transport Security: false
HTTP 公開鍵ピンニング: false

SEC_ERROR_UNKNOWN_ISSUER

原因としては中間証明書の設定不備。中間証明書の項目がコメントアウトされていました。

# SSLCertificateChainFile /etc/httpd/chain.crt

コメント解除でエラーも解消しました。

SSLCertificateChainFile /etc/httpd/chain.crt
]]>
2528
伊達慶邦を将軍にすると記した奥州改元大政元年資料 https://www.geek.sc/archives/2506 <![CDATA[齊藤貴義]]> Thu, 11 Jul 2019 22:40:10 +0000 <![CDATA[歴史]]> https://www.geek.sc/?p=2506 <![CDATA[

奥羽越列藩同盟の政権構想 戊辰戦争の時、奥羽越列藩同盟では新政府軍に対抗して輪王寺宮(北白川宮能久親王)を新しい天皇として擁立しようとする動きがありました。いわば南北朝構想です。 奥羽越列藩同盟に迎えられた輪王寺宮は18 ... ]]>
<![CDATA[

奥羽越列藩同盟の政権構想

戊辰戦争の時、奥羽越列藩同盟では新政府軍に対抗して輪王寺宮(北白川宮能久親王)を新しい天皇として擁立しようとする動きがありました。いわば南北朝構想です。

奥羽越列藩同盟に迎えられた輪王寺宮は1868年(慶応3年)6月15日に東武皇帝として即位し、元号を大政に改元したとする説があります。

その事を裏付ける史料が徳川宗家に伝わる『徳川宗家文書補遺』(徳川記念財団所蔵)に収められています。この史料では輪王寺宮を中心に九条や沢などの東北鎮撫軍の公卿、征夷大将軍として伊達慶邦、総副軍総裁に松平容保が名を連ねているいわば東北版朝廷の閣僚名簿となっています。仙台市博物館の戊辰戦争150年の特別展でこの史料を見る機会がありました。特別展は撮影禁止でしたが、この史料自体は仙台市博物館のパンフレットでも紹介されています。

以下、その奥州改元大政元年資料の書き起こしです。

奥州改元大政元年資料

奥州改元
大政元年六月十五日
御即位
上野宮御事
東武皇帝

御諱
御后

一条前開白御女
仙台慶邦養女

執柄職
九条開白太政大臣
醍醐左大臣
澤大納言

月卿
龍亭大納言
正中野右少将
龍開院少納言

雲閣
野木位宰相
越小路左少将
澤侍從
田村新中将

北面
安達左近将監
山原左京亮一
保科左馬長
室賀上給榷佐
出川佐渡守
山崎大膳正
大久保主膳頭
神保左兵衛尉

藏人頭

舍人
室田椎少将
品川大夫

兼国務方

権征夷大将軍
仙台新三位藤原慶邦

総副軍総裁
会津中将源容保

陸奥国探題兼守衛
南部盛岡少将

出羽国探題兼守衛
佐竹秋田侍従

奥羽夷蝦相海兼守衛
津軽弘前少将

軍師
大久保筑後守
長尾主膳正
部西土佐守
伊倉備中守
八戶藏人佐
以上

越後口 米沢少将
奸賊防禦 桑名少将
松前伊豆守
本多宮内少将
先鋒軍師 高橋外記
本多正之助
白川口 二本松侍從

好賊
棚意四品
水野真三郎

防禦 松平大学頭
先陣 伊達将監 里見但馬
遊軍並兼御守衛賊
庄内少将

右誤字落字難斗本ノ事

即位や改元を巡ってどこまで実際に話が進んでいたのかは懐疑的な議論もあり冷静な検証が必要ですが、当時はこのような文書が盛んにつくられ奥羽越列藩同盟で使われていたと思われます。

]]>
2506
Google Mapsのローカルガイドアカウントが停止された場合の対処法 https://www.geek.sc/archives/2486 <![CDATA[齊藤貴義]]> Tue, 09 Jul 2019 14:57:35 +0000 <![CDATA[インターネット]]> https://www.geek.sc/?p=2486 <![CDATA[

Google Mapsのローカルガイドアカウントが停止された Google Mapsで色々な飲食店のクチコミを投稿してローカルガイドに就任していたのですが(レベル7)、ある日、何かのレビューがいけなかったのかローカルガイ ... ]]>
<![CDATA[

Google Mapsのローカルガイドアカウントが停止された

Google Mapsで色々な飲食店のクチコミを投稿してローカルガイドに就任していたのですが(レベル7)、ある日、何かのレビューがいけなかったのかローカルガイドアカウントを停止されてしまいました。

実はそれでかなり困っていたのですが、Googleのローカルガイドのヘルプでローカルガイドアカウントが停止(suspend)した場合という記事を見掛けました。

それによるとTwitterまたはfacebookでGoogleローカルガイドの公式アカウントへメンションを送ると、Googleにアカウントの調査を依頼できると書いてありました。

■ SNSを通じてローカルガイドチームに連絡する方法を確認する
・上記を確認して問題が無いということであれば、twitterやfacebookを通じてローカルガイドチームへと連絡する方法を確認したあとで、ローカルガイドチームへ調査を依頼することができます(英語)

 連絡先を得る手段として、現在は、twitterやfacebook のみです。

  twitter : https://twitter.com/localguides
  facebook : https://www.facebook.com/GoogleLocalGuides/

■ twitterで、ローカルガイドチームへの連絡方法を確認をする場合
 localguideのアカウントは、DMを受け取らないため、「メンション」にする必要があります。
 なお @localguides をフォローする必要はありません。

 [フォローアップ] ローカルガイドのアカウントが削除されたユーザからもtwitterでのDM送信について
 https://www.localguidesconnect.com/cmxpv89733/board/message?board.id=Japanese&message.id=5759#M5759

— 要約 —
twitterのダイレクトメッセージはお互いにフォローし合っていないと送ることができません。
ですので、「メンション」してローカルガイド・チームにお知らせください。

ツイートする時に@localguides とユーザーを指定します。これを「メンション」といい、指定されたユーザーに通知が届きます。

日本語でご連絡いただいても大丈夫ですが、英語の場合のメッセージ例を記載いたします。
Profile URLは 「GoogleMap の Profile URLを取得するには?」を確認して取得してください。

 日本語:
 ローカルガイドのアカウントが停止されています。助けてもらえますか?
 GoogleマッププロフィールURL:https://www.google.com/maps/contrib/************************/

 英語:
 My Local Guides account has been suspended. Can you please help?
 GoogleMap Profile URL: https://www.google.com/maps/contrib/************************/

TwitterでGoogleローカルガイド公式アカウントにメンションを送ってみた。

そんな方法が通用するのかと半信半疑だったのですが、とりあえずTwitterで公式アカウントへメンションを送ってみました。メッセージはテンプレ通り、”My Local Guides account has been suspended. Can you please help?”にしました。そうしたら3日後に公式カウントからリプライがありました。

Hi there! Thanks for the provided information. Our team will look into your account and reach out via email within three weeks.

アカウントを3週間以内に調査して調査結果をメールするとのこと。やったー!

Googleから停止解除してもらった

そして待つこと3週間。ほぼ3週間目に差し掛かったところでGoogleからメールが届きました。

Important information about your Google Local Guides account

Hello,

Google Maps team is constantly checking the quality of the Maps, and your account was temporarily suspended. Your account is unsuspended now, so please follow these instructions to reactivate your account:

1) Visit https://maps.google.com/localguides/home
2) Sign up for the program

Once you’ve signed up for Local Guides
3) Visit https://www.localguidesconnect.com/
4) Click on the grey icon in the top right corner to log-in with your email address.

Please note that It may take 2-3 days for your contribution to be restored.
Apologies for the inconvenience! Please let us know if you have any issues or questions.

Best regards,
The Local Guides Team

We encourage you to visit our Connect forum, where you can chat with other Local Guides around the world, ask questions, share your experiences, and more.

ローカルガイドアカウントが停止されていたけど解除したので、再度ローカルガイドにサインアップしてほしいとのこと。そしてローカルガイドプログラムに申し込んだら無事にアカウントが復活しました。

同じくスパムではないのにローカルガイドアカウントを停止されている方は、Twitterまたはfacebookで公式アカウントにコンタクトを取ってみると良いかと思います。

]]>
2486
お名前.comのレンタルサーバーでxterm-256color: Unknown terminal typeエラー https://www.geek.sc/archives/2408 <![CDATA[齊藤貴義]]> Sun, 30 Jun 2019 12:30:59 +0000 <![CDATA[LInux]]> <![CDATA[システム開発]]> https://www.geek.sc/?p=2408 <![CDATA[

お名前.com の共用サーバーでviコマンドが使えない お名前.comの共有サーバーSDにてFTPではできない作業をするためSSHでログインする機会があったのですが、viコマンドでファイルを開こうとするとエラーが出ました ... ]]>
<![CDATA[

お名前.com の共用サーバーでviコマンドが使えない

お名前.comの共有サーバーSDにてFTPではできない作業をするためSSHでログインする機会があったのですが、viコマンドでファイルを開こうとするとエラーが出ました。

$ vi hogehoge.txt
xterm-256color: Unknown terminal type
I don't know what kind of terminal you are on - all I have is 'xterm-256color'.
[Using open mode]

ターミナルタイプが認識できない。ということでターミナルタイプをセットしました。

$ export TERM=xterm

.bashrcや.bash_profileのようなものが無い(そもそもホームディレクトリにファイルを作成できない)ので永続化は無理っぽいです。諦めるしかありません。それかviではなくvimコマンドを打つようにするか。

お名前.comの共有サーバーのOSはSolaris10

蛇足ですが、お名前.comでuname -aを打ってみたら、

uname -a
SunOS ssh 5.10 Generic_Virtual i86pc i386 i86pc

と返ってきました。SunOS ssh 5.10はSolaris10(x86版)です。お名前ドットコムでSolarisが生き続けていたとはちょっと意外でした。

]]>
2408