【医師ポイ活】毎日の医師ポイ活を半自動化するPythonプログラム(Mac版)

この記事は約12分で読めます。

医師のプラットフォーム(PF)サイトは、m3をはじめとして、メドピア、ケアネット、日経メディカルなどがある。ここでは、毎日の医師PFのポイ活を半自動化するプログラムを記載。

ちなみに、私のPCがMacなのでMac版のみの記事(windows版はニーズがあれば記載するかも)。

完全自動化ではなく、特定の時間になったら、ポイ活につながるPFのwebサイトを開くという半自動化で、その後のクリック操作は個人で手動で行う必要あり(全自動は出来なくはなさそうだが、そこまでコード書くのは面倒になったのと、やりすぎると。。。(略

pythonコードを作成

ファイル名は今回は、open_websites.pyとした。

webbrowserモジュールを使用してURLを開くだけの、非常にシンプルなコード。

urlsに配列で記載している医師プラットフォームのURLは、ご自身の都合に合わせて加筆修正してください。今後、各社のサイトのURL自体も変わる可能性が大いにあります。

Python
import webbrowser

def open_websites(urls):
    for idx, url in enumerate(urls):
        if idx == 0:
            # 最初のURLは現在のタブで開く
            webbrowser.open(url)
        else:
            # 2番目以降のURLは新しいタブで開く
            webbrowser.open_new_tab(url)

# 開きたいURLを記載
urls = [
    "https://medical.nikkeibp.co.jp/",
    "https://www.carenet.com/",
    "https://medpeer.jp/missions?from=top_banner",
    "https://mrkun.m3.com/mrq/everydaybonus/0000772134/41867/campaignList/viewDetail.htm?mkep=campaignList&pageContext=gp-41867&displaysite=campaignList&mke=1",
    "https://dailymission.m3.com/mission/?mkep=campaignList&pageContext=gp-62498&displaysite=campaignList&mke=1",
    "https://www.m3.com/?from=todoIcon"
]

open_websites(urls)

一旦この時点で正常動作するか、ターミナルでpython3 open_websites.py を実行して動作確認する。

python2系で日本語文字を使っている場合は、文字コード指定必要

こちらは余談だが、先ほどのコード実行を python open_websites.py とすると、下記のようなエラーが出る。

Zsh
 ~/dev/automate   main ?  python open_websites.py                 2998  10:51:04
  File "open_websites.py", line 11
SyntaxError: Non-ASCII character '\xe6' in file open_websites.py on line 11, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

私の場合は、pythonコマンドの場合はMacのデフォルトのpython2系を使い、python3コマンドの場合にはpython3系を使うようにしている。

python open_websites.pyとするとpython2系で実行することになり、その場合は、日本語のコメント部分(先ほどのスクリプトだと、# 最初のURLは現在のタブで開く など)の読み込みでエラーが生じてしまう。

これは、python2系はデフォルトでASCII文字のみをサポートしているため、非ASCII文字(日本語など)を含むPythonファイルを実行するには、ファイルのエンコーディングを明示的に指定する必要があるため。

というわけで、もし、日本語のコメントがある状態で、python open_websites.py を実行したい場合には、下記のように「# -*- coding: utf-8 -*-」という、このコードは、非ASCII文字を含むutf-8コードで記載していますよと明示する必要がある。

Zsh
# -*- coding: utf-8 -*-
import webbrowser

def open_websites(urls):
    for idx, url in enumerate(urls):
        if idx == 0:
            # 最初のURLは現在のタブで開く
            webbrowser.open(url)
        else:
            # 2番目以降のURLは新しいタブで開く
            webbrowser.open_new_tab(url)

# 開きたいURLを記載

ちなみに、もちろん、コード内に日本語がなければこの問題は解消されるので、

そもそもコメント部分を削除してコードのみにする、コメントを英語にするなどでも良い。

また、Python 3では、デフォルトでUTF-8エンコーディングが使用されるため、通常はファイルの先頭にエンコーディングを指定する必要はない。Python 3では、ASCII以外の文字を含むソースコードをそのまま記述することができるし、むしろわざわざ「# -*- coding: utf-8 -*-」と記載するのは非推奨となった。

Macがスリープ状態でもコードを実行できるようにする

launchdエージェントを使う

ただし、先ほどのスクリプトを記載しただけだと、毎回ターミナルでpython open_websites.py とコードを実行しないといけない。

プログラムを実行するタイミングが指定されていないのと、外出していたり席を離れたりしていてPCがスリープ状態の時には、スクリプトが実行されずにwebサイトが開かない。

なので、macがスリープ状態でも指定時刻でコードを実行できるように、launchdエージェントを使う。

launchdエージェントとは、macOSで使用されるシステムレベルのデーモン/エージェント管理フレームワーク。特定の条件(時間、イベントなど)でスクリプトやアプリケーションを自動的に実行するために使用される。

launchdを使用するには、特定のタスクの設定を含む.plist(プロパティリスト)ファイルを作成し、それをシステムの適切なディレクトリに配置する必要がある。

というわけで、まずは.plistファイルを作成。

.plistファイルを作成して配置

先ほど作成した、open_websites.pyスクリプトを実行するための.plistファイル(XML形式)を作成する。

ファイル名をopen_websites.plistと、実行するpythonファイル名と同じにした。

こちらは同じに揃えないといけないという制約はない。実際のコードは.plist内に記載されている実行ファイルへの絶対パスの方で記載するため。ただ、分かりやすいように同じ名前にした。

launchd.plistのマニュアルページは下記サイトの関連項目の最後に記載されている。

Macの「ターミナル」でのlaunchdを使ったスクリプトの管理
Macの「ターミナル」で、launchdを使用してシェルスクリプトをデーモンとして実行します。
XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>com.user.open_websites</string>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/local/bin/python3</string>
      <string>/Users/ky/dev/automate/open_websites.py</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
      <key>Hour</key>
      <integer>17</integer>
      <key>Minute</key>
      <integer>30</integer>
    </dict>
</dict>
</plist>
  • Label: タスクの一意な識別子。
  • ProgramArguments: 実行するコマンド、ここではPythonのパスとスクリプトの絶対パス。pythonの絶対パスは、ターミナルで which pythonと入力してパスを出力してコピペする。デフォルトはpython2系は/usr/bin/python。python3系は/usr/local/bin/python3。
  • スクリプト(open_websites.py)の絶対パスは、該当スクリプトがあるフォルダのディレクトリでpwd(print working directoryの略で現在のディレクトリを表示)する。
  • StartICalendarInterval: タスクを実行する時間。今回は17:30に実行したいので、hourとminuteを設定。ここを変更することで、目的の時刻にスクリプトを起動することができる。

作成した.plistファイルを~/Library/LaunchAgents(ユーザー特有のタスク)に配置する。

タスクを有効化して確認

ターミナルで launchctlコマンドを使用して.plistファイルをロードし、タスクを有効化する。

Zsh
launchctl load ~/Library/LaunchAgents/open_websites.plist

タスクを有効化しても、特にターミナルでメッセージが表示されるわけではないのと、有効になったとしてもスクリプト実行を指定した時刻までは、特に何も起きない。

なので、launchctl listコマンドでタスクが正しくロードされているか確認する。

launchtl listコマンドだけを実行すると、実行中のファイルが多数表示されて見つけるのが大変なので、grepコマンド(global regular expression print(ファイル全体から/正規表現に一致する行を/表示する。の略)を利用してopen_webという名前のエージェントを絞り込み表示する。

Zsh
launchctl list | grep open_web

今回、敢えて、2つの.plistファイルを作成して出力してみた。

出力されている2つの.plistのうち、片方はステータス「1」になっていて、もう片方は「0」になっている。0が正しく動作していることを表し、1がジョブを実行しようとしたがエラーになっていることを表す。

もし、pythonスクリプトをターミナルで直接実行していてエラーが出ないにも関わらず、launchtl list コマンドでエラーになる場合には、.plistのファイルの書き方に間違いがあることになる。

例えば、xml形式で記載していない、スクリプトへの絶対パスが正しくない、pythonへのパスが正しくないなど。

Load failed: 5: Input/output errorの場合

permissionなど、いくつか原因が考えられるが、unloadしてから再度loadすると、私の場合は毎回直る。

完成!

これらの手順により、指定された時間に自動的にopen_websites.pyスクリプトが実行される。

実際に実行されると、次のようになる。

一気にブラウザURLが開くのは、見ていて気持ちいい。

複数のURLを定期時刻に自動的に開いてくれるだけの単純なプログラムだが、医師ポイ活以外でも、朝のチェックするニュースURLとか、株価チェックとか他にも汎用的に使えるので、興味ある方はぜひ。

P.S. プチ拡張したversionを下記に記載。

WEB講演会の直前になったら自動的にURLを開いてくれるChrome拡張機能

あと、今回のコードとは別だが、WEB講演会の直前になったら自動的にURLを開いてくれるChrome拡張機能「crx-gcal-url-opener」はこちら。

crx-gcal-url-opener
Chrome extension that automatically opens Google Calendar meet links and event URLs

Googleカレンダーのイベント開始1分前にカレンダーに設定されたGoogle MeetまたはZoomのURLを自動で新しいタブとして開いてくれる。仕事に集中しすぎてミーティングに参加し忘れる、遅れてしまうなどのトラブルを防いでくれるので、web講演会に限らず、オンラインmtg全般でとても便利。

web講演会の予約ページを開くと、下記のように「カレンダーに登録する」ボタンがほとんどの医師PFサイトにあると思うので、googleカレンダーのボタンを押してgoogleカレンダーに追加しておくだけで良い。そうすると、web講演会開始の1分前に自動でURLを開いてくれるので、見逃しのリスクが減る。

コメント

タイトルとURLをコピーしました